diff --git a/.eslintrc.js b/.eslintrc.js index ddffea9..4693849 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,5 +21,6 @@ module.exports = { "@typescript-eslint/consistent-type-imports": "warn", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-restricted-imports": ["error", "discord-api-types"], + "no-unused-vars": "off", }, }; diff --git a/.gitignore b/.gitignore index f96e548..468b707 100644 --- a/.gitignore +++ b/.gitignore @@ -105,4 +105,7 @@ dist config.hjson -logs/ \ No newline at end of file +logs/ + +# WebStorm +.idea/ \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4526c77..07ef67a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,7 +6,7 @@ "tsconfig": "tsconfig.json", "problemMatcher": ["$tsc"], "group": "build", - "label": "tsc: build - tsconfig.json", + "label": "tsc: build - tsconfig.json" } ] diff --git a/HowToUse.yml b/HowToUse.yml index 6eb9a78..310e6ca 100644 --- a/HowToUse.yml +++ b/HowToUse.yml @@ -12,6 +12,7 @@ Starting the bot: Run These commands: Might only need to run these once Before Starting the bot - "yarn prisma:generate" // You'll need to Do this After you edit the schema.prisma File - "yarn prisma:push" // You'll use this to make the Database you defined Before startup +(don't forget to create a .env file, defining DATABASE_URL=) Then, - To start the bot go to the dist directory and start "index.js" with pm2 diff --git a/README.md b/README.md index 74e1f6f..cbfb69e 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,111 @@ -[![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/drunkbartender) -[![Discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.com/invite/pY6hNVs) -[![Github](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/shadow6060/DBRewrite) -[![Typescript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/) -[![Website](https://img.shields.io/badge/-Website-blueviolet?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGF2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0NDg4LCAyMDIwLzA3LzEwLTIyOjA2OjUzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjIuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTEyLTI1VDEyOjU1OjE1WiIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTItMjVUMTM6MDE6NDJaIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIyLTEyLTI1VDEzOjAxOjQyWiIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Yjc2ODI5ZTQtY2RhMC0zZjQxLThlNWItMzNkY2Q5Nzc3NmJiIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTU4Nzc3ODAtZTE5ZS1kZDRiLWIwYjItY2VkN2UyYjVlN2NiIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6N2FhMjBmYmItNzEwNy05NTQ4LTgxZmUtODFjZTMxZGY2M2M5Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3YWEyMGZiYi03MTA3LTk1NDgtODFmZS04MWNlMzFkZjYzYzkiIHN0RXZ0OndoZW49IjIwMjItMTItMjVUMTI6NTU6MTVaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjIuMCAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNvbnZlcnRlZCIgc3RFdnQ6cGFyYW1ldGVycz0iZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6Yjc2ODI5ZTQtY2RhMC0zZjQxLThlNWItMzNkY2Q5Nzc3NmJiIiBzdEV2dDp3aGVuPSIyMDIyLTEyLTI1VDEzOjAxOjQyWiIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pnios6IAAAJaSURBVCiRndLLS5RRHIfx7++cd5x3HGfSGUZR8zqFlWZONyy7aEHRIozAIiJaGeiiIDAoENqE4C4QKkgoyS4QKegiWmWIl02hpQaZMU5iMZrXmffMO+85p//BZ//ZPaS1xlYy+gbev7ZFShLnNoHWRkaHx3qfPe/P8rnFiZOn6hsbL7YKkXIYY8SYTk18nR6dGP/0wvBHRy5nMAmPocDNTOTn27ecqkB318ep5vq9c+HSxHSTcNLI8rrA3S6U7/NdT05tRmj2boYW5KTGZtVcIIjM/UUoycr1oOGBOBwp08UPW9xvF5a41f7E6Skv5NtuN+JS3EKChXc4WLTUQss7XGjuxdmMEBaDxQKFQUQMH1R2hYMUTyW+RO32pLQ6XQXWmj/PMo20zcDcTJWF5HpdISwuKKFtDoM5blIA1gmlpTz70X16U2SqYGg75bx6jGF286XqiC9rd10pzDtnGBOCEZEC4xoiwYE0wFJkVISNhkAuq4bDULmb3Gzou773dEi2xFYQ7/oshTY0wDWkQ+BcAT6F6JJaq71mHz/XJmtnfshfp4/hkDF4A0fTxOOWS9cMR7HT61MhmMDqphZFYQCrBHtDqivnDefIHpJcpiVIwwhlsw9pglYuUGsFeZnJEJvXzkxMjh+MYBf8DNWVyCnIZ/3BXJZpBrhvZd6BIYi8iaSG6SesWkz9/I2Nth7Z+S+BSW6wmuW/JFNCwfQ4eRubLsRhWB3doo+aDqBDatLEoW3JnNkl9W1mXg+aHljlBVRVXYKryXXA7SOtGcOfFR0bn5QDtNVX2ZYUgP/eWQ654oa7+gAAAABJRU5ErkJggg==)](https://drunk-bartender.org) -

- -

- -

Drunk Bartender

-
-

❓ What is Drunk Bartender

-
-Drunk bartender is a bot that was created in August 2019, - -We are a part of an independent group of developers who have been working on this for the longest time with the same original team as in the beginning We have some commands and recently moved over to Slash Commands to follow Discord Requirements to continue operating and work with most other bots that follow it, and we are currently working on moving into Discord.js v14 - -We can also be reached at anytime and we have always worked hard on providing premium support to anyone who reaches out to us as that is the most important to us as your time is valuable, so we do our best to make your experience the best, so you can have more enjoyment with your time with us that is what keeps us going with this project and will always work our hardest to bring you the best new features we can and bring more fun commands - -And we are always open to hearing suggestions from the community about new features and love to hear your feedback on things we are glad that you have decided to spend some time with us as that is really important to us and if you want you also get to know us as most of our dms are open and are always ready to answer any questions -
-

ℹ Commands

- -| Commands | Usage | Permissions | -|:------------------------------|:----------------------------------------:|-------------:| -| /balance | Gets a user's balance. | Global 🌐 | -| /work | Work to get money. | Global 🌐 | -| /crime | Commit a crime for money. | Global 🌐 | -| /daily | Gets money daily. | Global 🌐 | -| /order | Orders a drink. | Global 🌐 | -| /tip | Tip's a bartender. | Global 🌐 | -| /status | Gets the status of an order. | Global 🌐 | -| /cancel | Cancel's an order. | Global 🌐 | -| /feedback | Sends a feedback. | Global 🌐 | -| /doggo | Cute images of dogs. | Global 🌐 | -| /goose | Cool images of goose. | Global 🌐 | -| /meow | Wow images of cats. | Global 🌐 | -| /memes | Get some very funny memes. | Global 🌐 | -| /pat | Pat someone. | Global 🌐 | -| /tickle | Tickle your friends. | Global 🌐 | -| /hug | Give someone a big old hug. | Global 🌐 | -| /slap | Slap a very naughty person. | Global 🌐 | -| /status | Get a status of your order. | Global 🌐 | -| /blacklist | Blacklist's a user. | Admin 🛠 | -| /unblacklist | Unblacklist's a user. | Admin 🛠 | -| /list | List's all available orders. | Staff 🛠 | -| /claim | Claim's a user's order. | Staff 🛠 | -| /unclaim | Unclaim's a user's order. | Staff 🛠 | -| /fetch | Fetches the status of an order. | Staff 🛠 | -| /duty | Gives the on-duty role. | Staff 🛠 | -| /deliverymessage set | Sets a delivery message. | Staff 🛠 | -| /deliverymessage fetch | Gets your delivery message. | Staff 🛠 | -| /deliverymessage placeholders | Gets your delivery message placeholders. | Staff 🛠 | -| /brew | Brew's an order. | Staff 🛠 | -| /delete | Delete's a order. | Staff 🛠 | - -
-

🔗 Links

- -- [GitHub](https://github.com/shadow6060/DBRewrite) -
- -- [Website](https://drunk-bartender.org) -
- -- [Patreon](https://www.patreon.com/drunkbartender) -
- -- [Discord](https://discord.gg/pY6hNVs) -
- -- [Appeals](https://www.drunk-bartender.org/Appeals) -
+[![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/drunkbartender) +[![Discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.com/invite/pY6hNVs) +[![Github](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/shadow6060/DBRewrite) +[![Typescript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/) +[![Website](https://img.shields.io/badge/-Website-blueviolet?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGF2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0NDg4LCAyMDIwLzA3LzEwLTIyOjA2OjUzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjIuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTEyLTI1VDEyOjU1OjE1WiIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTItMjVUMTM6MDE6NDJaIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIyLTEyLTI1VDEzOjAxOjQyWiIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Yjc2ODI5ZTQtY2RhMC0zZjQxLThlNWItMzNkY2Q5Nzc3NmJiIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTU4Nzc3ODAtZTE5ZS1kZDRiLWIwYjItY2VkN2UyYjVlN2NiIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6N2FhMjBmYmItNzEwNy05NTQ4LTgxZmUtODFjZTMxZGY2M2M5Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3YWEyMGZiYi03MTA3LTk1NDgtODFmZS04MWNlMzFkZjYzYzkiIHN0RXZ0OndoZW49IjIwMjItMTItMjVUMTI6NTU6MTVaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjIuMCAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNvbnZlcnRlZCIgc3RFdnQ6cGFyYW1ldGVycz0iZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6Yjc2ODI5ZTQtY2RhMC0zZjQxLThlNWItMzNkY2Q5Nzc3NmJiIiBzdEV2dDp3aGVuPSIyMDIyLTEyLTI1VDEzOjAxOjQyWiIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pnios6IAAAJaSURBVCiRndLLS5RRHIfx7++cd5x3HGfSGUZR8zqFlWZONyy7aEHRIozAIiJaGeiiIDAoENqE4C4QKkgoyS4QKegiWmWIl02hpQaZMU5iMZrXmffMO+85p//BZ//ZPaS1xlYy+gbev7ZFShLnNoHWRkaHx3qfPe/P8rnFiZOn6hsbL7YKkXIYY8SYTk18nR6dGP/0wvBHRy5nMAmPocDNTOTn27ecqkB318ep5vq9c+HSxHSTcNLI8rrA3S6U7/NdT05tRmj2boYW5KTGZtVcIIjM/UUoycr1oOGBOBwp08UPW9xvF5a41f7E6Skv5NtuN+JS3EKChXc4WLTUQss7XGjuxdmMEBaDxQKFQUQMH1R2hYMUTyW+RO32pLQ6XQXWmj/PMo20zcDcTJWF5HpdISwuKKFtDoM5blIA1gmlpTz70X16U2SqYGg75bx6jGF286XqiC9rd10pzDtnGBOCEZEC4xoiwYE0wFJkVISNhkAuq4bDULmb3Gzou773dEi2xFYQ7/oshTY0wDWkQ+BcAT6F6JJaq71mHz/XJmtnfshfp4/hkDF4A0fTxOOWS9cMR7HT61MhmMDqphZFYQCrBHtDqivnDefIHpJcpiVIwwhlsw9pglYuUGsFeZnJEJvXzkxMjh+MYBf8DNWVyCnIZ/3BXJZpBrhvZd6BIYi8iaSG6SesWkz9/I2Nth7Z+S+BSW6wmuW/JFNCwfQ4eRubLsRhWB3doo+aDqBDatLEoW3JnNkl9W1mXg+aHljlBVRVXYKryXXA7SOtGcOfFR0bn5QDtNVX2ZYUgP/eWQ654oa7+gAAAABJRU5ErkJggg==)](https://drunk-bartender.org) + +

+ +

+ +

Drunk Bartender

+
+

❓ What is Drunk Bartender

+
+Drunk bartender is a bot that was created in August 2019, +Drunk bartender is a bot that was created in August 2019, + +We are a part of an independent group of developers who have been working on this for the longest time with the same original team as in the beginning We have some commands and recently moved over to Slash Commands to follow Discord Requirements to continue operating and work with most other bots that follow it, and we are currently working on moving into Discord.js v14 + +We can also be reached at anytime and we have always worked hard on providing premium support to anyone who reaches out to us as that is the most important to us as your time is valuable, so we do our best to make your experience the best, so you can have more enjoyment with your time with us that is what keeps us going with this project and will always work our hardest to bring you the best new features we can and bring more fun commands +We can also be reached at anytime and we have always worked hard on providing premium support to anyone who reaches out to us as that is the most important to us as your time is valuable, so we do our best to make your experience the best, so you can have more enjoyment with your time with us that is what keeps us going with this project and will always work our hardest to bring you the best new features we can and bring more fun commands + +And we are always open to hearing suggestions from the community about new features and love to hear your feedback on things we are glad that you have decided to spend some time with us as that is really important to us and if you want you also get to know us as most of our dms are open and are always ready to answer any questions +
+ +

ℹ Commands

+ +| Commands | Usage | Permissions | +| :---------------------------- | :--------------------------------------: | ----------: | +| /balance | Gets a user's balance. | Global 🌐 | +| /work | Work to get money. | Global 🌐 | +| /crime | Commit a crime for money. | Global 🌐 | +| /daily | Gets money daily. | Global 🌐 | +| /order | Orders a drink. | Global 🌐 | +| /tip | Tip's a bartender. | Global 🌐 | +| /status | Gets the status of an order. | Global 🌐 | +| /cancel | Cancel's an order. | Global 🌐 | +| /feedback | Sends a feedback. | Global 🌐 | +| /doggo | Cute images of dogs. | Global 🌐 | +| /goose | Cool images of goose. | Global 🌐 | +| /meow | Wow images of cats. | Global 🌐 | +| /memes | Get some very funny memes. | Global 🌐 | +| /pat | Pat someone. | Global 🌐 | +| /tickle | Tickle your friends. | Global 🌐 | +| /hug | Give someone a big old hug. | Global 🌐 | +| /slap | Slap a very naughty person. | Global 🌐 | +| /status | Get a status of your order. | Global 🌐 | +| /blacklist | Blacklist's a user. | Admin 🛠 | +| /unblacklist | Unblacklist's a user. | Admin 🛠 | +| /list | List's all available orders. | Staff 🛠 | +| /claim | Claim's a user's order. | Staff 🛠 | +| /unclaim | Unclaim's a user's order. | Staff 🛠 | +| /fetch | Fetches the status of an order. | Staff 🛠 | +| /duty | Gives the on-duty role. | Staff 🛠 | +| /deliverymessage set | Sets a delivery message. | Staff 🛠 | +| /deliverymessage fetch | Gets your delivery message. | Staff 🛠 | +| /deliverymessage placeholders | Gets your delivery message placeholders. | Staff 🛠 | +| /brew | Brew's an order. | Staff 🛠 | +| /delete | Delete's a order. | Staff 🛠 | + +
+| Commands | Usage | Permissions | +|:------------------------------|:----------------------------------------:|-------------:| +| /balance | Gets a user's balance. | Global 🌐 | +| /work | Work to get money. | Global 🌐 | +| /crime | Commit a crime for money. | Global 🌐 | +| /daily | Gets money daily. | Global 🌐 | +| /order | Orders a drink. | Global 🌐 | +| /tip | Tip's a bartender. | Global 🌐 | +| /status | Gets the status of an order. | Global 🌐 | +| /cancel | Cancel's an order. | Global 🌐 | +| /feedback | Sends a feedback. | Global 🌐 | +| /doggo | Cute images of dogs. | Global 🌐 | +| /goose | Cool images of goose. | Global 🌐 | +| /meow | Wow images of cats. | Global 🌐 | +| /memes | Get some very funny memes. | Global 🌐 | +| /pat | Pat someone. | Global 🌐 | +| /tickle | Tickle your friends. | Global 🌐 | +| /hug | Give someone a big old hug. | Global 🌐 | +| /slap | Slap a very naughty person. | Global 🌐 | +| /status | Get a status of your order. | Global 🌐 | +| /blacklist | Blacklist's a user. | Admin 🛠 | +| /unblacklist | Unblacklist's a user. | Admin 🛠 | +| /list | List's all available orders. | Staff 🛠 | +| /claim | Claim's a user's order. | Staff 🛠 | +| /unclaim | Unclaim's a user's order. | Staff 🛠 | +| /fetch | Fetches the status of an order. | Staff 🛠 | +| /duty | Gives the on-duty role. | Staff 🛠 | +| /deliverymessage set | Sets a delivery message. | Staff 🛠 | +| /deliverymessage fetch | Gets your delivery message. | Staff 🛠 | +| /deliverymessage placeholders | Gets your delivery message placeholders. | Staff 🛠 | +| /brew | Brew's an order. | Staff 🛠 | +| /delete | Delete's a order. | Staff 🛠 | + +
+

🔗 Links

+ +- [GitHub](https://github.com/shadow6060/DBRewrite) +
+ +- [Website](https://drunk-bartender.org) +
+ +- [Patreon](https://www.patreon.com/drunkbartender) +
+ +- [Discord](https://discord.gg/pY6hNVs) +
+ +- [Appeals](https://www.drunk-bartender.org/Appeals) +
diff --git a/config/config.hjson.example b/config/config.hjson.example index a99bb6a..318b1ee 100644 --- a/config/config.hjson.example +++ b/config/config.hjson.example @@ -1,7 +1,7 @@ { token: "" mainServer: "snowflake" - + dashboardUrl: "https://your-dashboard-url.com", databaseUrl: postgresql://user:password@localhost:/mydb?schema=public developers: [] emojis: { diff --git a/package.json b/package.json index a389a70..6fb1c64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dbrewrite", - "version": "1.3.4", + "version": "1.3.5", "description": "", "main": "index.js", "scripts": { @@ -30,11 +30,12 @@ "discord-api-types": "^0.37.35", "eslint": "^8.12.0", "eslint-plugin-regexp": "^1.6.0", + "prettier": "^3.2.5", "prisma": "latest", "ts-node": "^10.9.1", "ts-toolbelt": "^9.6.0", "tsconfig-paths": "^4.1.2", - "typescript": "^4.9.5" + "typescript": "^5.4.5" }, "dependencies": { "@discordjs/builders": "^1.5.0-dev.1677499471-ffdb197.0", @@ -42,9 +43,13 @@ "@paralleldrive/cuid2": "^2.2.1", "@prisma/client": "latest", "@sapphire/shapeshift": "^3.8.1", + "@types/express": "^4.17.21", "cross-env": "^7.0.3", "discord.js": "^14.14.1", + "express": "^4.19.2", "fast-glob": "^3.2.11", + "fastify": "^4.26.2", + "fastify-socket.io": "^5.0.0", "got": "^11.8.3", "hjson": "^3.2.2", "nekos.life": "^3.0.0", @@ -52,6 +57,7 @@ "picocolors": "^1.0.0", "pino": "^7.9.2", "pretty-ms": "^7.0.1", + "socket.io": "^4.7.5", "source-map-support": "^0.5.21", "typescript-memoize": "^1.1.0", "uuid": "^9.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 833ed26..fe333bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,85 +1,154 @@ -lockfileVersion: 5.3 - -specifiers: - '@discordjs/builders': ^0.12.0 - '@discordjs/rest': ^0.3.0 - '@prisma/client': ^3.13.0 - '@types/node': ^17.0.23 - '@typescript-eslint/eslint-plugin': ^5.16.0 - '@typescript-eslint/parser': ^5.16.0 - cross-env: ^7.0.3 - discord-api-types: ^0.30.0 - discord.js: ^13.6.0 - eslint: ^8.12.0 - eslint-plugin-regexp: ^1.6.0 - fast-glob: ^3.2.11 - hjson: ^3.2.2 - picocolors: ^1.0.0 - pino: ^7.9.2 - pretty-ms: ^7.0.1 - prisma: ^3.13.0 - source-map-support: ^0.5.21 - ts-toolbelt: ^9.6.0 - typescript: ^4.7.0-beta - typescript-memoize: ^1.1.0 - zod: ^3.14.3 +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false dependencies: - '@discordjs/builders': 0.12.0 - '@discordjs/rest': 0.3.0 - '@prisma/client': 3.13.0_prisma@3.13.0 - cross-env: 7.0.3 - discord-api-types: 0.30.0 - discord.js: 13.6.0 - fast-glob: 3.2.11 - hjson: 3.2.2 - picocolors: 1.0.0 - pino: 7.9.2 - pretty-ms: 7.0.1 - source-map-support: 0.5.21 - typescript-memoize: 1.1.0 - zod: 3.14.3 + '@discordjs/builders': + specifier: ^1.5.0-dev.1677499471-ffdb197.0 + version: 1.7.0 + '@discordjs/rest': + specifier: ^0.3.0 + version: 0.3.0 + '@paralleldrive/cuid2': + specifier: ^2.2.1 + version: 2.2.2 + '@prisma/client': + specifier: ^5.11.0 + version: 5.11.0(prisma@5.11.0) + '@sapphire/shapeshift': + specifier: ^3.8.1 + version: 3.9.6 + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + discord.js: + specifier: ^14.14.1 + version: 14.14.1 + fast-glob: + specifier: ^3.2.11 + version: 3.2.11 + got: + specifier: ^11.8.3 + version: 11.8.6 + hjson: + specifier: ^3.2.2 + version: 3.2.2 + nekos.life: + specifier: ^3.0.0 + version: 3.0.0 + nodemon: + specifier: ^2.0.20 + version: 2.0.22 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + pino: + specifier: ^7.9.2 + version: 7.9.2 + pretty-ms: + specifier: ^7.0.1 + version: 7.0.1 + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + typescript-memoize: + specifier: ^1.1.0 + version: 1.1.0 + uuid: + specifier: ^9.0.0 + version: 9.0.1 + yarn: + specifier: ^1.22.18 + version: 1.22.22 + zod: + specifier: ^3.14.3 + version: 3.14.3 devDependencies: - '@types/node': 17.0.23 - '@typescript-eslint/eslint-plugin': 5.16.0_5ae56ee64658da37428c53e9c0c05c28 - '@typescript-eslint/parser': 5.16.0_20848afcae97cb82b3144239e86ffbc6 - eslint: 8.12.0 - eslint-plugin-regexp: 1.6.0_eslint@8.12.0 - prisma: 3.13.0 - ts-toolbelt: 9.6.0 - typescript: 4.7.0-beta + '@types/node': + specifier: ^17.0.42 + version: 17.0.45 + '@types/uuid': + specifier: ^9.0.1 + version: 9.0.8 + '@typescript-eslint/eslint-plugin': + specifier: ^5.16.0 + version: 5.16.0(@typescript-eslint/parser@5.16.0)(eslint@8.12.0)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^5.16.0 + version: 5.16.0(eslint@8.12.0)(typescript@4.9.5) + discord-api-types: + specifier: ^0.37.35 + version: 0.37.77 + eslint: + specifier: ^8.12.0 + version: 8.12.0 + eslint-plugin-regexp: + specifier: ^1.6.0 + version: 1.6.0(eslint@8.12.0) + prisma: + specifier: ^5.6.0 + version: 5.11.0 + ts-node: + specifier: ^10.9.1 + version: 10.9.2(@types/node@17.0.45)(typescript@4.9.5) + ts-toolbelt: + specifier: ^9.6.0 + version: 9.6.0 + tsconfig-paths: + specifier: ^4.1.2 + version: 4.2.0 + typescript: + specifier: ^4.9.5 + version: 4.9.5 packages: - /@discordjs/builders/0.11.0: - resolution: {integrity: sha512-ZTB8yJdJKrKlq44dpWkNUrAtEJEq0gqpb7ASdv4vmq6/mZal5kOv312hQ56I/vxwMre+VIkoHquNUAfnTbiYtg==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} dependencies: - '@sindresorhus/is': 4.6.0 - discord-api-types: 0.26.1 - ts-mixer: 6.0.1 - tslib: 2.3.1 - zod: 3.14.3 - dev: false + '@jridgewell/trace-mapping': 0.3.9 + dev: true - /@discordjs/builders/0.12.0: - resolution: {integrity: sha512-Vx2MjUZd6QVo1uS2uWt708Fd6cHWGFblAvbpL5EBO+kLl0BADmPwwvts+YJ/VfSywed6Vsk6K2cEooR/Ytjhjw==} - engines: {node: '>=16.9.0'} + /@discordjs/builders@1.7.0: + resolution: {integrity: sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==} + engines: {node: '>=16.11.0'} dependencies: - '@sindresorhus/is': 4.6.0 - discord-api-types: 0.26.1 - ts-mixer: 6.0.1 - tslib: 2.3.1 - zod: 3.14.3 + '@discordjs/formatters': 0.3.3 + '@discordjs/util': 1.0.2 + '@sapphire/shapeshift': 3.9.6 + discord-api-types: 0.37.61 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.6.2 dev: false - /@discordjs/collection/0.4.0: + /@discordjs/collection@0.4.0: resolution: {integrity: sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} dev: false - /@discordjs/rest/0.3.0: + /@discordjs/collection@1.5.3: + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + dev: false + + /@discordjs/collection@2.0.0: + resolution: {integrity: sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==} + engines: {node: '>=18'} + dev: false + + /@discordjs/formatters@0.3.3: + resolution: {integrity: sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==} + engines: {node: '>=16.11.0'} + dependencies: + discord-api-types: 0.37.61 + dev: false + + /@discordjs/rest@0.3.0: resolution: {integrity: sha512-F9aeP3odlAlllM1ciBZLdd+adiAyBj4VaZBejj4UMj4afE2wfCkNTGvYYiRxrXUE9fN7e/BuDP2ePl0tVA2m7Q==} engines: {node: '>=16.9.0'} dependencies: @@ -94,7 +163,45 @@ packages: - encoding dev: false - /@eslint/eslintrc/1.2.1: + /@discordjs/rest@2.2.0: + resolution: {integrity: sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==} + engines: {node: '>=16.11.0'} + dependencies: + '@discordjs/collection': 2.0.0 + '@discordjs/util': 1.0.2 + '@sapphire/async-queue': 1.5.2 + '@sapphire/snowflake': 3.5.1 + '@vladfrangu/async_event_emitter': 2.2.4 + discord-api-types: 0.37.61 + magic-bytes.js: 1.10.0 + tslib: 2.6.2 + undici: 5.27.2 + dev: false + + /@discordjs/util@1.0.2: + resolution: {integrity: sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==} + engines: {node: '>=16.11.0'} + dev: false + + /@discordjs/ws@1.0.2: + resolution: {integrity: sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==} + engines: {node: '>=16.11.0'} + dependencies: + '@discordjs/collection': 2.0.0 + '@discordjs/rest': 2.2.0 + '@discordjs/util': 1.0.2 + '@sapphire/async-queue': 1.5.2 + '@types/ws': 8.5.9 + '@vladfrangu/async_event_emitter': 2.2.4 + discord-api-types: 0.37.61 + tslib: 2.6.2 + ws: 8.14.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@eslint/eslintrc@1.2.1: resolution: {integrity: sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -111,7 +218,12 @@ packages: - supports-color dev: true - /@humanwhocodes/config-array/0.9.5: + /@fastify/busboy@2.1.1: + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + dev: false + + /@humanwhocodes/config-array@0.9.5: resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==} engines: {node: '>=10.10.0'} dependencies: @@ -122,31 +234,58 @@ packages: - supports-color dev: true - /@humanwhocodes/object-schema/1.2.1: + /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@nodelib/fs.scandir/2.1.5: + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@noble/hashes@1.4.0: + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + dev: false + + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - /@nodelib/fs.stat/2.0.5: + /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - /@nodelib/fs.walk/1.2.8: + /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - /@prisma/client/3.13.0_prisma@3.13.0: - resolution: {integrity: sha512-lnEA2tTyVbO5mS1ehmHJQKBDiKB8shaR6s3azwj3Azfi5XHIfnqmkolLCvUeFYnkDCNVzGXJpUgKwQt/UOOYVQ==} - engines: {node: '>=12.6'} + /@paralleldrive/cuid2@2.2.2: + resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} + dependencies: + '@noble/hashes': 1.4.0 + dev: false + + /@prisma/client@5.11.0(prisma@5.11.0): + resolution: {integrity: sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw==} + engines: {node: '>=16.13'} requiresBuild: true peerDependencies: prisma: '*' @@ -154,55 +293,135 @@ packages: prisma: optional: true dependencies: - '@prisma/engines-version': 3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b - prisma: 3.13.0 + prisma: 5.11.0 dev: false - /@prisma/engines-version/3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b: - resolution: {integrity: sha512-TGp9rvgJIKo8NgvAHSwOosbut9mTA7VC6/rpQI9gh+ySSRjdQFhbGyNUiOcQrlI9Ob2DWeO7y4HEnhdKxYiECg==} - dev: false + /@prisma/debug@5.11.0: + resolution: {integrity: sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A==} + + /@prisma/engines-version@5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102: + resolution: {integrity: sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA==} - /@prisma/engines/3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b: - resolution: {integrity: sha512-Ip9CcCeUocH61eXu4BUGpvl5KleQyhcUVLpWCv+0ZmDv44bFaDpREqjGHHdRupvPN/ugB6gTlD9b9ewdj02yVA==} + /@prisma/engines@5.11.0: + resolution: {integrity: sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw==} requiresBuild: true - dev: true + dependencies: + '@prisma/debug': 5.11.0 + '@prisma/engines-version': 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102 + '@prisma/fetch-engine': 5.11.0 + '@prisma/get-platform': 5.11.0 - /@sapphire/async-queue/1.3.0: + /@prisma/fetch-engine@5.11.0: + resolution: {integrity: sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w==} + dependencies: + '@prisma/debug': 5.11.0 + '@prisma/engines-version': 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102 + '@prisma/get-platform': 5.11.0 + + /@prisma/get-platform@5.11.0: + resolution: {integrity: sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw==} + dependencies: + '@prisma/debug': 5.11.0 + + /@sapphire/async-queue@1.3.0: resolution: {integrity: sha512-z+CDw5X4UgIEpZL8KM+ThVx1i8V60HBg0l/oFewTNbQQeRDJHdVxHyJykv+SF1H+Rc8EkMS81VTWo95jVYgO/g==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} dev: false - /@sapphire/snowflake/3.2.0: + /@sapphire/async-queue@1.5.2: + resolution: {integrity: sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dev: false + + /@sapphire/shapeshift@3.9.6: + resolution: {integrity: sha512-4+Na/fxu2SEepZRb9z0dbsVh59QtwPuBg/UVaDib3av7ZY14b14+z09z6QVn0P6Dv6eOU2NDTsjIi0mbtgP56g==} + engines: {node: '>=v18'} + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.17.21 + dev: false + + /@sapphire/snowflake@3.2.0: resolution: {integrity: sha512-tfHzY+6/5bbHdB+uNqsEQ5rhjaZAoFUrqP/l1S5jwxMdKeSCIiGkJjcE99/WGGdzyWGjTNgNVX/dt4Me/FdMlg==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} dev: false - /@sindresorhus/is/4.6.0: + /@sapphire/snowflake@3.5.1: + resolution: {integrity: sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dev: false + + /@sindresorhus/is@4.6.0: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} dev: false - /@types/json-schema/7.0.11: + /@szmarczak/http-timer@4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: false + + /@tsconfig/node10@1.0.11: + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/cacheable-request@6.0.3: + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 17.0.45 + '@types/responselike': 1.0.3 + dev: false + + /@types/http-cache-semantics@4.0.4: + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + dev: false + + /@types/json-schema@7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true - /@types/node-fetch/2.6.1: - resolution: {integrity: sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==} + /@types/keyv@3.1.4: + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + dependencies: + '@types/node': 17.0.45 + dev: false + + /@types/node@17.0.45: + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + /@types/responselike@1.0.3: + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 17.0.23 - form-data: 3.0.1 + '@types/node': 17.0.45 dev: false - /@types/node/17.0.23: - resolution: {integrity: sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==} + /@types/uuid@9.0.8: + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + dev: true - /@types/ws/8.5.3: - resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + /@types/ws@8.5.9: + resolution: {integrity: sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==} dependencies: - '@types/node': 17.0.23 + '@types/node': 17.0.45 dev: false - /@typescript-eslint/eslint-plugin/5.16.0_5ae56ee64658da37428c53e9c0c05c28: + /@typescript-eslint/eslint-plugin@5.16.0(@typescript-eslint/parser@5.16.0)(eslint@8.12.0)(typescript@4.9.5): resolution: {integrity: sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -213,23 +432,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.16.0_20848afcae97cb82b3144239e86ffbc6 + '@typescript-eslint/parser': 5.16.0(eslint@8.12.0)(typescript@4.9.5) '@typescript-eslint/scope-manager': 5.16.0 - '@typescript-eslint/type-utils': 5.16.0_20848afcae97cb82b3144239e86ffbc6 - '@typescript-eslint/utils': 5.16.0_20848afcae97cb82b3144239e86ffbc6 + '@typescript-eslint/type-utils': 5.16.0(eslint@8.12.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.16.0(eslint@8.12.0)(typescript@4.9.5) debug: 4.3.4 eslint: 8.12.0 functional-red-black-tree: 1.0.1 ignore: 5.2.0 regexpp: 3.2.0 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.7.0-beta - typescript: 4.7.0-beta + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/5.16.0_20848afcae97cb82b3144239e86ffbc6: + /@typescript-eslint/parser@5.16.0(eslint@8.12.0)(typescript@4.9.5): resolution: {integrity: sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -241,15 +460,15 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.16.0 '@typescript-eslint/types': 5.16.0 - '@typescript-eslint/typescript-estree': 5.16.0_typescript@4.7.0-beta + '@typescript-eslint/typescript-estree': 5.16.0(typescript@4.9.5) debug: 4.3.4 eslint: 8.12.0 - typescript: 4.7.0-beta + typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.16.0: + /@typescript-eslint/scope-manager@5.16.0: resolution: {integrity: sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -257,7 +476,7 @@ packages: '@typescript-eslint/visitor-keys': 5.16.0 dev: true - /@typescript-eslint/type-utils/5.16.0_20848afcae97cb82b3144239e86ffbc6: + /@typescript-eslint/type-utils@5.16.0(eslint@8.12.0)(typescript@4.9.5): resolution: {integrity: sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -267,21 +486,21 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.16.0_20848afcae97cb82b3144239e86ffbc6 + '@typescript-eslint/utils': 5.16.0(eslint@8.12.0)(typescript@4.9.5) debug: 4.3.4 eslint: 8.12.0 - tsutils: 3.21.0_typescript@4.7.0-beta - typescript: 4.7.0-beta + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.16.0: + /@typescript-eslint/types@5.16.0: resolution: {integrity: sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.16.0_typescript@4.7.0-beta: + /@typescript-eslint/typescript-estree@5.16.0(typescript@4.9.5): resolution: {integrity: sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -296,13 +515,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.7.0-beta - typescript: 4.7.0-beta + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.16.0_20848afcae97cb82b3144239e86ffbc6: + /@typescript-eslint/utils@5.16.0(eslint@8.12.0)(typescript@4.9.5): resolution: {integrity: sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -311,16 +530,16 @@ packages: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 5.16.0 '@typescript-eslint/types': 5.16.0 - '@typescript-eslint/typescript-estree': 5.16.0_typescript@4.7.0-beta + '@typescript-eslint/typescript-estree': 5.16.0(typescript@4.9.5) eslint: 8.12.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.12.0 + eslint-utils: 3.0.0(eslint@8.12.0) transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.16.0: + /@typescript-eslint/visitor-keys@5.16.0: resolution: {integrity: sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -328,7 +547,16 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /acorn-jsx/5.3.2_acorn@8.7.0: + /@vladfrangu/async_event_emitter@2.2.4: + resolution: {integrity: sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: false + + /acorn-jsx@5.3.2(acorn@8.7.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -336,13 +564,18 @@ packages: acorn: 8.7.0 dev: true - /acorn/8.7.0: + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.7.0: resolution: {integrity: sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==} engines: {node: '>=0.4.0'} hasBin: true dev: true - /ajv/6.12.6: + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: fast-deep-equal: 3.1.3 @@ -351,63 +584,96 @@ packages: uri-js: 4.4.1 dev: true - /ansi-regex/5.0.1: + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true - /ansi-styles/4.3.0: + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 dev: true - /argparse/2.0.1: + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: false + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /array-union/2.1.0: + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /asynckit/0.4.0: + /asynckit@0.4.0: resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} dev: false - /atomic-sleep/1.0.0: + /atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} dev: false - /balanced-match/1.0.2: + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - /brace-expansion/1.1.11: + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + dev: false + + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true - /braces/3.0.2: + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - /buffer-from/1.1.2: + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: false - /callsites/3.1.0: + /cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: false + + /cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + dev: false + + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: true - /chalk/4.1.2: + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} dependencies: @@ -415,34 +681,58 @@ packages: supports-color: 7.2.0 dev: true - /color-convert/2.0.1: + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + 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 + dev: false + + /clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + dependencies: + mimic-response: 1.0.1 + dev: false + + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 dev: true - /color-name/1.1.4: + /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true - /combined-stream/1.0.8: + /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 dev: false - /comment-parser/1.3.1: + /comment-parser@1.3.1: resolution: {integrity: sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==} engines: {node: '>= 12.0.0'} dev: true - /concat-map/0.0.1: + /concat-map@0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true - /cross-env/7.0.3: + /cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} hasBin: true @@ -450,7 +740,7 @@ packages: cross-spawn: 7.0.3 dev: false - /cross-spawn/7.0.3: + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} dependencies: @@ -458,7 +748,19 @@ packages: shebang-command: 2.0.0 which: 2.0.2 - /debug/4.3.4: + /debug@3.2.7(supports-color@5.5.0): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 5.5.0 + dev: false + + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -470,58 +772,83 @@ packages: ms: 2.1.2 dev: true - /deep-is/0.1.4: + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true - /delayed-stream/1.0.0: + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} engines: {node: '>=0.4.0'} dev: false - /dir-glob/3.0.1: + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} dependencies: path-type: 4.0.0 dev: true - /discord-api-types/0.26.1: + /discord-api-types@0.26.1: resolution: {integrity: sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==} engines: {node: '>=12'} dev: false - /discord-api-types/0.30.0: - resolution: {integrity: sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw==} + /discord-api-types@0.37.61: + resolution: {integrity: sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==} dev: false - /discord.js/13.6.0: - resolution: {integrity: sha512-tXNR8zgsEPxPBvGk3AQjJ9ljIIC6/LOPjzKwpwz8Y1Q2X66Vi3ZqFgRHYwnHKC0jC0F+l4LzxlhmOJsBZDNg9g==} - engines: {node: '>=16.6.0', npm: '>=7.0.0'} + /discord-api-types@0.37.77: + resolution: {integrity: sha512-AkEn9nZA5w/XJ8wzKzlpx3X+MToQCowKahftF1+KYnMWnuglCrVRojy1XlIWX8Frgp1v8INceGKpvDkbvMLJ4g==} + dev: true + + /discord.js@14.14.1: + resolution: {integrity: sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==} + engines: {node: '>=16.11.0'} dependencies: - '@discordjs/builders': 0.11.0 - '@discordjs/collection': 0.4.0 - '@sapphire/async-queue': 1.3.0 - '@types/node-fetch': 2.6.1 - '@types/ws': 8.5.3 - discord-api-types: 0.26.1 - form-data: 4.0.0 - node-fetch: 2.6.7 - ws: 8.5.0 + '@discordjs/builders': 1.7.0 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.3.3 + '@discordjs/rest': 2.2.0 + '@discordjs/util': 1.0.2 + '@discordjs/ws': 1.0.2 + '@sapphire/snowflake': 3.5.1 + '@types/ws': 8.5.9 + discord-api-types: 0.37.61 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + tslib: 2.6.2 + undici: 5.27.2 + ws: 8.14.2 transitivePeerDependencies: - bufferutil - - encoding - utf-8-validate dev: false - /doctrine/3.0.0: + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 dev: true - /duplexify/4.1.2: + /duplexify@4.1.2: resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} dependencies: end-of-stream: 1.4.4 @@ -530,18 +857,18 @@ packages: stream-shift: 1.0.1 dev: false - /end-of-stream/1.4.4: + /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 dev: false - /escape-string-regexp/4.0.0: + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: true - /eslint-plugin-regexp/1.6.0_eslint@8.12.0: + /eslint-plugin-regexp@1.6.0(eslint@8.12.0): resolution: {integrity: sha512-xkaQOzyY4PUukRd8b6zTq+QTtg0dePlCP2dZiM+XGSmvlpDeYiPJHfRDpAfS/sP9YtK6q7DGes1smCyPTD3Lkg==} engines: {node: ^12 || >=14} peerDependencies: @@ -549,7 +876,7 @@ packages: dependencies: comment-parser: 1.3.1 eslint: 8.12.0 - eslint-utils: 3.0.0_eslint@8.12.0 + eslint-utils: 3.0.0(eslint@8.12.0) grapheme-splitter: 1.0.4 jsdoctypeparser: 9.0.0 refa: 0.9.1 @@ -558,7 +885,7 @@ packages: scslre: 0.1.6 dev: true - /eslint-scope/5.1.1: + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} dependencies: @@ -566,7 +893,7 @@ packages: estraverse: 4.3.0 dev: true - /eslint-scope/7.1.1: + /eslint-scope@7.1.1: resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -574,7 +901,7 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.12.0: + /eslint-utils@3.0.0(eslint@8.12.0): resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: @@ -584,17 +911,17 @@ packages: eslint-visitor-keys: 2.1.0 dev: true - /eslint-visitor-keys/2.1.0: + /eslint-visitor-keys@2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} dev: true - /eslint-visitor-keys/3.3.0: + /eslint-visitor-keys@3.3.0: resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.12.0: + /eslint@8.12.0: resolution: {integrity: sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true @@ -608,7 +935,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.12.0 + eslint-utils: 3.0.0(eslint@8.12.0) eslint-visitor-keys: 3.3.0 espree: 9.3.1 esquery: 1.4.0 @@ -638,49 +965,48 @@ packages: - supports-color dev: true - /espree/9.3.1: + /espree@9.3.1: resolution: {integrity: sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.7.0 - acorn-jsx: 5.3.2_acorn@8.7.0 + acorn-jsx: 5.3.2(acorn@8.7.0) eslint-visitor-keys: 3.3.0 dev: true - /esquery/1.4.0: + /esquery@1.4.0: resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 dev: true - /esrecurse/4.3.0: + /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 dev: true - /estraverse/4.3.0: + /estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} dev: true - /estraverse/5.3.0: + /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} dev: true - /esutils/2.0.3: + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: true - /fast-deep-equal/3.1.3: + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - /fast-glob/3.2.11: + /fast-glob@3.2.11: resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} engines: {node: '>=8.6.0'} dependencies: @@ -690,38 +1016,38 @@ packages: merge2: 1.4.1 micromatch: 4.0.5 - /fast-json-stable-stringify/2.1.0: + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true - /fast-levenshtein/2.0.6: + /fast-levenshtein@2.0.6: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} dev: true - /fast-redact/3.1.1: + /fast-redact@3.1.1: resolution: {integrity: sha512-odVmjC8x8jNeMZ3C+rPMESzXVSEU8tSWSHv9HFxP2mm89G/1WwqhrerJDQm9Zus8X6aoRgQDThKqptdNA6bt+A==} engines: {node: '>=6'} dev: false - /fastq/1.13.0: + /fastq@1.13.0: resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} dependencies: reusify: 1.0.4 - /file-entry-cache/6.0.1: + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 dev: true - /fill-range/7.0.1: + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - /flat-cache/3.0.4: + /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: @@ -729,20 +1055,11 @@ packages: rimraf: 3.0.2 dev: true - /flatted/3.2.5: + /flatted@3.2.5: resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==} dev: true - /form-data/3.0.1: - resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /form-data/4.0.0: + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} dependencies: @@ -751,28 +1068,43 @@ packages: mime-types: 2.1.35 dev: false - /fs.realpath/1.0.0: + /fs.realpath@1.0.0: resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} dev: true - /functional-red-black-tree/1.0.1: + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /functional-red-black-tree@1.0.1: resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} dev: true - /glob-parent/5.1.2: + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: false + + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - /glob-parent/6.0.2: + /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 dev: true - /glob/7.2.0: + /glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: fs.realpath: 1.0.0 @@ -783,14 +1115,14 @@ packages: path-is-absolute: 1.0.1 dev: true - /globals/13.13.0: + /globals@13.13.0: resolution: {integrity: sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 dev: true - /globby/11.1.0: + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: @@ -802,26 +1134,64 @@ packages: slash: 3.0.0 dev: true - /grapheme-splitter/1.0.4: + /got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + dev: false + + /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true - /has-flag/4.0.0: + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: false + + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: true - /hjson/3.2.2: + /hjson@3.2.2: resolution: {integrity: sha512-MkUeB0cTIlppeSsndgESkfFD21T2nXPRaBStLtf3cAYA2bVEFdXlodZB0TukwZiobPD1Ksax5DK4RTZeaXCI3Q==} hasBin: true dev: false - /ignore/5.2.0: + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: false + + /http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: false + + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: false + + /ignore@5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} dev: true - /import-fresh/3.3.0: + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} dependencies: @@ -829,60 +1199,83 @@ packages: resolve-from: 4.0.0 dev: true - /imurmurhash/0.1.4: + /imurmurhash@0.1.4: resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} engines: {node: '>=0.8.19'} dev: true - /inflight/1.0.6: + /inflight@1.0.6: resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} dependencies: once: 1.4.0 wrappy: 1.0.2 dev: true - /inherits/2.0.4: + /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /is-extglob/2.1.1: + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + dev: false + + /is-extglob@2.1.1: resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} engines: {node: '>=0.10.0'} - /is-glob/4.0.3: + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - /is-number/7.0.0: + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - /isexe/2.0.0: + /isexe@2.0.0: resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} - /js-yaml/4.1.0: + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true dependencies: argparse: 2.0.1 dev: true - /jsdoctypeparser/9.0.0: + /jsdoctypeparser@9.0.0: resolution: {integrity: sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==} engines: {node: '>=10'} hasBin: true dev: true - /json-schema-traverse/0.4.1: + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false + + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /json-stable-stringify-without-jsonify/1.0.1: + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} dev: true - /levn/0.4.1: + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: false + + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} dependencies: @@ -890,55 +1283,92 @@ packages: type-check: 0.4.0 dev: true - /lodash.merge/4.6.2: + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true - /lru-cache/6.0.0: + /lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + + /lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + dev: false + + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} dependencies: yallist: 4.0.0 dev: true - /merge2/1.4.1: + /magic-bytes.js@1.10.0: + resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==} + dev: false + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - /micromatch/4.0.5: + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} dependencies: braces: 3.0.2 picomatch: 2.3.1 - /mime-db/1.52.0: + /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} dev: false - /mime-types/2.1.35: + /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 dev: false - /minimatch/3.1.2: + /mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + dev: false + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: true - /ms/2.1.2: + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - /natural-compare/1.4.0: + /natural-compare@1.4.0: resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} dev: true - /node-fetch/2.6.7: + /nekos.life@3.0.0: + resolution: {integrity: sha512-7LbvSqLtfK4XRA91nJaGOWthrNADmG7Vx9d54TC77Hx5qFvRCssFUaHraI6bZGjVENBCUaF7CreisoFX+8mnKQ==} + dev: false + + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -950,16 +1380,50 @@ packages: whatwg-url: 5.0.0 dev: false - /on-exit-leak-free/0.2.0: + /nodemon@2.0.22: + resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} + engines: {node: '>=8.10.0'} + hasBin: true + dependencies: + chokidar: 3.6.0 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 5.7.2 + simple-update-notifier: 1.1.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + dev: false + + /nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: false + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: false + + /normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + dev: false + + /on-exit-leak-free@0.2.0: resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} dev: false - /once/1.4.0: - resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 - /optionator/0.9.1: + /optionator@0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} dependencies: @@ -971,52 +1435,57 @@ packages: word-wrap: 1.2.3 dev: true - /parent-module/1.0.1: + /p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + dev: false + + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} dependencies: callsites: 3.1.0 dev: true - /parse-ms/2.1.0: + /parse-ms@2.1.0: resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} engines: {node: '>=6'} dev: false - /path-is-absolute/1.0.1: + /path-is-absolute@1.0.1: resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} engines: {node: '>=0.10.0'} dev: true - /path-key/3.1.1: + /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - /path-type/4.0.0: + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} dev: true - /picocolors/1.0.0: + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: false - /picomatch/2.3.1: + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - /pino-abstract-transport/0.5.0: + /pino-abstract-transport@0.5.0: resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} dependencies: duplexify: 4.1.2 split2: 4.1.0 dev: false - /pino-std-serializers/4.0.0: + /pino-std-serializers@4.0.0: resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} dev: false - /pino/7.9.2: + /pino@7.9.2: resolution: {integrity: sha512-c8wmB2PuhdJurYPRl/eo3+PosHe7Ep6GZvBJFIrp9oV1YRZQ3qm3MujaEolaKUfwX8cDL96WKCWWMedB2drXqw==} hasBin: true dependencies: @@ -1032,45 +1501,59 @@ packages: thread-stream: 0.15.1 dev: false - /prelude-ls/1.2.1: + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: true - /pretty-ms/7.0.1: + /pretty-ms@7.0.1: resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} engines: {node: '>=10'} dependencies: parse-ms: 2.1.0 dev: false - /prisma/3.13.0: - resolution: {integrity: sha512-oO1auBnBtieGdiN+57IgsA9Vr7Sy4HkILi1KSaUG4mpKfEbnkTGnLOxAqjLed+K2nsG/GtE1tJBtB7JxN1a78Q==} - engines: {node: '>=12.6'} + /prisma@5.11.0: + resolution: {integrity: sha512-KCLiug2cs0Je7kGkQBN9jDWoZ90ogE/kvZTUTgz2h94FEo8pczCkPH7fPNXkD1sGU7Yh65risGGD1HQ5DF3r3g==} + engines: {node: '>=16.13'} hasBin: true requiresBuild: true dependencies: - '@prisma/engines': 3.13.0-17.efdf9b1183dddfd4258cd181a72125755215ab7b - ts-pattern: 4.0.2 - dev: true + '@prisma/engines': 5.11.0 - /process-warning/1.0.0: + /process-warning@1.0.0: resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} dev: false - /punycode/2.1.1: + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: false + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + + /punycode@2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} dev: true - /queue-microtask/1.2.3: + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - /quick-format-unescaped/4.0.4: + /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} dev: false - /readable-stream/3.6.0: + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: false + + /readable-stream@3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} dependencies: @@ -1079,67 +1562,84 @@ packages: util-deprecate: 1.0.2 dev: false - /real-require/0.1.0: + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: false + + /real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} dev: false - /refa/0.9.1: + /refa@0.9.1: resolution: {integrity: sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA==} dependencies: regexpp: 3.2.0 dev: true - /regexp-ast-analysis/0.2.4: + /regexp-ast-analysis@0.2.4: resolution: {integrity: sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==} dependencies: refa: 0.9.1 regexpp: 3.2.0 dev: true - /regexp-ast-analysis/0.3.0: + /regexp-ast-analysis@0.3.0: resolution: {integrity: sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA==} dependencies: refa: 0.9.1 regexpp: 3.2.0 dev: true - /regexpp/3.2.0: + /regexpp@3.2.0: resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} engines: {node: '>=8'} dev: true - /resolve-from/4.0.0: + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: false + + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} dev: true - /reusify/1.0.4: + /responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + dependencies: + lowercase-keys: 2.0.0 + dev: false + + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - /rimraf/3.0.2: + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true dependencies: glob: 7.2.0 dev: true - /run-parallel/1.2.0: + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - /safe-buffer/5.2.1: + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false - /safe-stable-stringify/2.3.1: + /safe-stable-stringify@2.3.1: resolution: {integrity: sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==} engines: {node: '>=10'} dev: false - /scslre/0.1.6: + /scslre@0.1.6: resolution: {integrity: sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw==} dependencies: refa: 0.9.1 @@ -1147,7 +1647,17 @@ packages: regexpp: 3.2.0 dev: true - /semver/7.3.5: + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: false + + /semver@7.0.0: + resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} + hasBin: true + dev: false + + /semver@7.3.5: resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} engines: {node: '>=10'} hasBin: true @@ -1155,191 +1665,277 @@ packages: lru-cache: 6.0.0 dev: true - /shebang-command/2.0.0: + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - /shebang-regex/3.0.0: + /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - /slash/3.0.0: + /simple-update-notifier@1.1.0: + resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} + engines: {node: '>=8.10.0'} + dependencies: + semver: 7.0.0 + dev: false + + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: true - /sonic-boom/2.6.0: + /sonic-boom@2.6.0: resolution: {integrity: sha512-6xYZFRmDEtxGqfOKcDQ4cPLrNa0SPEDI+wlzDAHowXE6YV42NeXqg9mP2KkiM8JVu3lHfZ2iQKYlGOz+kTpphg==} dependencies: atomic-sleep: 1.0.0 dev: false - /source-map-support/0.5.21: + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: false - /source-map/0.6.1: + /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} dev: false - /split2/4.1.0: + /split2@4.1.0: resolution: {integrity: sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==} engines: {node: '>= 10.x'} dev: false - /stream-shift/1.0.1: + /stream-shift@1.0.1: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} dev: false - /string_decoder/1.3.0: + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 dev: false - /strip-ansi/6.0.1: + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 dev: true - /strip-json-comments/3.1.1: + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true - /supports-color/7.2.0: + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: false + + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} dependencies: has-flag: 4.0.0 dev: true - /text-table/0.2.0: + /text-table@0.2.0: resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} dev: true - /thread-stream/0.15.1: + /thread-stream@0.15.1: resolution: {integrity: sha512-SCnuIT27gc2h/F/RY2peuC7brgLy+1oXU+7yOIAITz1z5stDpXCF5rAoFcykjuK6ifbTlKAHL7Ccq8oc5Btv1w==} dependencies: real-require: 0.1.0 dev: false - /to-regex-range/5.0.1: + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - /tr46/0.0.3: + /touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: false + + /tr46@0.0.3: resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=} dev: false - /ts-mixer/6.0.1: - resolution: {integrity: sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==} + /ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} dev: false - /ts-pattern/4.0.2: - resolution: {integrity: sha512-eHqR/7A6fcw05vCOfnL6RwgGJbVi9G/YHTdYdjYmElhDdJ1SMn7pWs+6+YuxygaFwQS/g+cIDlu+UD8IVpur1A==} + /ts-node@10.9.2(@types/node@17.0.45)(typescript@4.9.5): + 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 + 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': 17.0.45 + acorn: 8.7.0 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 dev: true - /ts-toolbelt/9.6.0: + /ts-toolbelt@9.6.0: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} dev: true - /tslib/1.14.1: + /tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tslib/2.3.1: + /tslib@2.3.1: resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} dev: false - /tsutils/3.21.0_typescript@4.7.0-beta: + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /tsutils@3.21.0(typescript@4.9.5): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.7.0-beta + typescript: 4.9.5 dev: true - /type-check/0.4.0: + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 dev: true - /type-fest/0.20.2: + /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} dev: true - /typescript-memoize/1.1.0: + /typescript-memoize@1.1.0: resolution: {integrity: sha512-LQPKVXK8QrBBkL/zclE6YgSWn0I8ew5m0Lf+XL00IwMhlotqRLlzHV+BRrljVQIc+NohUAuQP7mg4HQwrx5Xbg==} dev: false - /typescript/4.7.0-beta: - resolution: {integrity: sha512-m+CNL8lzHyHDxYYDTI+pm5hw5/bufYVGan2bokPyJY/y9C/4W/PCWMtYZ0vV9fLXbEL57elMeoaz9Evxs8UQ+A==} + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} hasBin: true dev: true - /uri-js/4.4.1: + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: false + + /undici@5.27.2: + resolution: {integrity: sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==} + engines: {node: '>=14.0'} + dependencies: + '@fastify/busboy': 2.1.1 + dev: false + + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 dev: true - /util-deprecate/1.0.2: + /util-deprecate@1.0.2: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} dev: false - /v8-compile-cache/2.3.0: + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /v8-compile-cache@2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true - /webidl-conversions/3.0.1: + /webidl-conversions@3.0.1: resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=} dev: false - /whatwg-url/5.0.0: + /whatwg-url@5.0.0: resolution: {integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0=} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 dev: false - /which/2.0.2: + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true dependencies: isexe: 2.0.0 - /word-wrap/1.2.3: + /word-wrap@1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} dev: true - /wrappy/1.0.2: - resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - /ws/8.5.0: - resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} + /ws@8.14.2: + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 + utf-8-validate: '>=5.0.2' peerDependenciesMeta: bufferutil: optional: true @@ -1347,10 +1943,22 @@ packages: optional: true dev: false - /yallist/4.0.0: + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - /zod/3.14.3: + /yarn@1.22.22: + resolution: {integrity: sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==} + engines: {node: '>=4.0.0'} + hasBin: true + requiresBuild: true + dev: false + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /zod@3.14.3: resolution: {integrity: sha512-OzwRCSXB1+/8F6w6HkYHdbuWysYWnAF4fkRgKDcSFc54CE+Sv0rHXKfeNUReGCrHukm1LNpi6AYeXotznhYJbQ==} dev: false diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 295e77d..470e5fe 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -9,29 +9,25 @@ datasource db { } model WorkerInfo { - id String @id @db.VarChar(20) - createdAt DateTime @default(now()) - preparations Int @default(0) - deliveries Int @default(0) - deliveryMessage String? - lastCommandUsage DateTime? // New field to track the last command usage time - commandUsageCount Int // New field to track the command usage count - lastCommandName String? // New field to track the last command name - claimUsageCount Int @default(0) // Usage count for "claim" command - brewUsageCount Int @default(0) // Usage count for "brew" command -} + id String @id @db.VarChar(20) + createdAt DateTime @default(now()) + preparations Int @default(0) + deliveries Int @default(0) + deliveryMessage String? + commandUsageCount Int + lastCommandName String? + cafeDeliveryMessage String? +} model UserInfo { - id String @id @db.VarChar(30) - createdAt DateTime @default(now()) - balance Int @default(0) - newBalance Int? - tabLimit Float @default(0) - tab Tab? - donuts Int @default(0) - guildsxp Json @default("{}") - guildsxpData GuildsXP[] - + id String @id @db.VarChar(30) + createdAt DateTime @default(now()) + balance Int @default(0) + newBalance Int? + tabLimit Float @default(0) + donuts Int @default(0) + authUser AuthUser? + tab Tab? } model Tree { @@ -40,7 +36,7 @@ model Tree { water DateTime maxAge Int - @@map(name: "trees") + @@map("trees") } model Tab { @@ -102,6 +98,7 @@ model Orders { flags Int @default(0) putOnTab Boolean? amount Float? + orderFor String? @db.VarChar(20) } model dishes { @@ -111,15 +108,55 @@ model dishes { updatedAt DateTime @db.Timestamp(6) } -model Drink { - id Int @id @default(autoincrement()) - name String @unique - type String - price Float - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt +model GuildsXP { + userId String + guildId String + level Int @default(0) + exp Int @default(0) + notificationChannelId String? + + @@unique([userId, guildId]) +} + +model WorkerStats { + id String @id + ordersBrewed Int + ordersDelivered Int + lastUsed DateTime + lastCommand String? +} + +model MenuItem { + id String @id @default(uuid()) + name String + description String + price Float + category String +} + +model ShopItem { + id String @id @default(uuid()) + name String + price Int + description String + type String + roleId String? +} + +model InventoryItem { + id String @id @default(uuid()) + itemId String + userId String + quantity Int } +model AuthUser { + id Int @id @default(autoincrement()) + token String + expiry DateTime + userID String @unique + user UserInfo @relation(fields: [userID], references: [id]) +} enum CafeStatus { Unprepared @@ -149,31 +186,3 @@ enum OrderStatus { Claimed } -model GuildsXP { - userId String - guildId String - userName String // Add the userName field - level Int @default(0) - exp Int @default(0) - user UserInfo @relation(fields: [userId], references: [id]) - location String? - notificationChannelId String? // New field for notification channel ID - @@unique([userId, guildId]) -} - -model WorkerStats { - id String @id - ordersBrewed Int - ordersDelivered Int - lastUsed DateTime - lastCommand String? -} - - -model MenuItem { - id String @id @default(uuid()) // You can use a UUID for the ID - name String // Name of the menu item - description String // Description of the menu item - price Float // Price of the menu item - category String // Category of the menu item (e.g., appetizer, main course, dessert) -} diff --git a/purgatory/drink.ts b/purgatory/drink.ts new file mode 100644 index 0000000..eef32e7 --- /dev/null +++ b/purgatory/drink.ts @@ -0,0 +1,42 @@ +// @ts-nocheck +import type { Drink } from "@prisma/client"; +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +/** Retrieves all drinks from the database. */ +export async function getAllDrinks(): Promise { + return prisma.drink.findMany(); +} + +/** + * Creates a drink. + * @param data - Drink data. The `createdAt` and `updatedAt` fields are optional, and will be set to the current timestamp if not provided. + */ +export async function createDrink( + data: Omit & + Partial> +): Promise { + return prisma.drink.create({ data }); +} + +/** + * Retrieves a drink by its ID, and updates it. + * @param id - The ID of the drink to update. + * @param data - Drink data. The `createdAt` and `updatedAt` fields are optional, and will be set to the current timestamp if not provided. + */ +export async function updateDrink( + id: number, + data: Omit & + Partial> +): Promise { + return prisma.drink.update({ where: { id }, data }); +} + +/** + * Deletes a drink. + * @param id - The ID of the drink to delete. + */ +export async function deleteDrink(id: number): Promise { + return prisma.drink.delete({ where: { id } }); +} diff --git a/purgatory/ebrew.ts b/purgatory/ebrew.ts new file mode 100644 index 0000000..05a443c --- /dev/null +++ b/purgatory/ebrew.ts @@ -0,0 +1,300 @@ +// @ts-nocheck +/* eslint-disable indent */ +/* eslint-disable quotes */ +import { OrderStatus } from "@prisma/client"; +import { db } from "../src/database/database"; +import { upsertWorkerInfo } from "../src/database/workerInfo"; +import { constants } from "../src/providers/config"; +import { permissions } from "../src/providers/permissions"; +import { Command } from "../src/structures/Command"; +import { randRange } from "../src/utils/utils"; +import { + CommandInteraction, + ComponentType, + EmbedBuilder, + StringSelectMenuBuilder, +} from "discord.js"; + +// Define the getClaimedOrders function without specifying OrderStatus +async function getClaimedOrders(userId: string) { + return await db.orders.findMany({ + where: { + claimer: userId, + status: OrderStatus.Preparing, + }, + }); +} + +export const command = new Command("ebrew", "Brews your claimed order.") + .addSubCommand((subcommand) => + subcommand + .setName("attach") + .setDescription("Attach an image to your order.") + .addAttachmentOption((option) => + option + .setName("attachment") + .setDescription("The image to attach to the order.") + .setRequired(true) + ) + ) + .addSubCommand((subcommand) => + subcommand + .setName("url") + .setDescription("Attach an image to your order by URL.") + .addStringOption((option) => + option + .setName("url") + .setDescription( + "The URL of the image to attach to the order." + ) + .setRequired(true) + ) + ) + .addSubCommand((subcommand) => + subcommand.setName("claim").setDescription("Claim an order.") + ) + .addPermission(permissions.employee) + .setExecutor(async (int: CommandInteraction) => { + // Check the subcommand + const subcommand = int.options.getSubcommand(true); + + if (subcommand === "claim") { + // Get a list of claimed orders for the user using getClaimedOrders + const claimedOrders = await getClaimedOrders(int.user.id); + + // Check if the user has claimed orders + if (claimedOrders.length === 0) { + await int.reply({ + content: "You don't have any claimed orders to brew.", + }); + return; + } + + // Build a select menu with claimed order options + const orderOptions = claimedOrders.map((order) => ({ + label: `Order ${order.id}`, + value: order.id.toString(), + description: `User: ${order.user.substring( + 0, + 15 + )}...\nDetails: ${order.details.substring(0, 50)}...`, + // Include user and details in the description, limiting the length + })); + + const orderSelectMenu = new StringSelectMenuBuilder() + .setCustomId("select_order_to_claim") + .setPlaceholder("Select an order to brew") + .addOptions(orderOptions) + .toJSON(); + + const actionRow = { + type: ComponentType.ActionRow, + components: [orderSelectMenu], + }; + + await int.reply({ + content: "Please select an order to brew:", + components: [actionRow], + ephemeral: true, + }); + + // Create a collector to listen for the user's selection + const filter = (i) => + i.customId === "select_order_to_claim" && + i.user.id === int.user.id; + const collector = int.channel.createMessageComponentCollector({ + filter, + time: 15000, + }); + + collector.on("collect", async (interaction) => { + const selectedOrderId = interaction.values[0]; + + // Fetch the order details using the order ID + const selectedOrder = await db.orders.findUnique({ + where: { + id: selectedOrderId, + }, + }); + + if (!selectedOrder) { + await interaction.update({ + content: "Invalid order selected.", + components: [], + }); + return; + } + + // Check if the order status is not OrderStatus.Preparing + if (selectedOrder.status !== OrderStatus.Preparing) { + await interaction.update({ + content: `You cannot claim an order with status ${selectedOrder.status}.`, + components: [], + }); + return; + } + + // Store the selected order ID in a context variable for future use + int.client.ordersInProcess = { + [int.user.id]: { + orderId: selectedOrderId, + }, + }; + + await interaction.update({ + content: `You selected Order ${selectedOrderId} to brew. Now, you can proceed to attach an image or provide a URL.`, + components: [], + }); + }); + + collector.on("end", async (collected) => { + if (collected.size === 0) { + await int.followUp("You didn't select an order in time."); + } + }); + } else if ( + (subcommand === "attach" || subcommand === "url") && + int.client.ordersInProcess?.[int.user.id]?.orderId + ) { + // Fetch the order ID from the context variable + const selectedOrderId = + int.client.ordersInProcess[int.user.id].orderId; + + // Fetch the order details using the order ID + const order = await db.orders.findUnique({ + where: { + id: selectedOrderId, + }, + }); + + if (!order) { + await int.reply({ content: "Invalid order selected." }); + return; + } + + // Check if the order status is OrderStatus.PendingDelivery or OrderStatus.Brewing + if ( + order.status === OrderStatus.PendingDelivery || + order.status === OrderStatus.Brewing + ) { + await int.reply({ + content: + "You have Already Brewed this order. select an new one!", + }); + return; + } + + let imageUrl: string | undefined; + + if (subcommand === "attach") { + const attachment = int.options.get( + "attachment", + true + )?.attachment; + if (!attachment) { + await int.reply({ + content: "Attachment is missing or not valid.", + }); + return; + } + imageUrl = attachment.url; + } else if (subcommand === "url") { + const url = int.options.getString("url", true); + imageUrl = url; + } + + // Include order description in the confirmation message + const confirmationDescription = `Order Details: ${order.details}`; + + const imagePreviewEmbed = new EmbedBuilder() + .setTitle("Image Preview") + .setImage(imageUrl) // Set the image URL as the preview + .toJSON(); + + const confirmSelectMenu = new StringSelectMenuBuilder() + .setCustomId("confirm_brew") + .setPlaceholder("Select an option") + .addOptions([ + { + label: "Yes", + description: "Proceed with brewing the order", + value: "yes", + }, + { + label: "No", + description: "Cancel the brewing process", + value: "no", + }, + ]) + .toJSON(); + + const confirmActionRow = { + type: ComponentType.ActionRow, + components: [confirmSelectMenu], + }; + + await int.reply({ + content: `Do you want to proceed with brewing this order?\n${confirmationDescription}`, + embeds: [imagePreviewEmbed], // Include the image preview in the message + components: [confirmActionRow], + ephemeral: true, + }); + + const confirmFilter = (i) => + i.customId === "confirm_brew" && i.user.id === int.user.id; + const confirmCollector = + int.channel.createMessageComponentCollector({ + filter: confirmFilter, + time: 15000, + }); + + confirmCollector.on("collect", async (confirmInteraction) => { + if (confirmInteraction.isStringSelectMenu()) { + const selectedValue = confirmInteraction.values[0]; + if (selectedValue === "yes") { + await confirmInteraction.update({ + content: + "You chose to proceed with brewing the order.", + components: [], + }); + + const time = randRange(...constants.brewTimeRangeMs); + await db.orders.update({ + where: { + id: order.id, + }, + data: { + status: OrderStatus.Brewing, + image: imageUrl ?? "default.png", + timeout: new Date(Date.now() + time), + }, + }); + await upsertWorkerInfo(int.user); + + await int.followUp({ + content: "Brewing process started.", + files: imageUrl + ? [{ attachment: imageUrl }] + : undefined, + }); + } else if (selectedValue === "no") { + await confirmInteraction.update({ + content: "You chose to cancel the brewing process.", + components: [], + }); + } + } + }); + + confirmCollector.on("end", async (collected) => { + if (collected.size === 0) { + await int.followUp("You didn't make a selection in time."); + } + }); + } else { + await int.reply({ + content: + "You need to claim an order first before attaching an image or providing a URL.", + }); + } + }); diff --git a/src/commands/orders/worker/eclaim.ts b/purgatory/eclaim.ts similarity index 90% rename from src/commands/orders/worker/eclaim.ts rename to purgatory/eclaim.ts index aa70a29..0ffb5eb 100644 --- a/src/commands/orders/worker/eclaim.ts +++ b/purgatory/eclaim.ts @@ -1,163 +1,162 @@ -/* eslint-disable quotes */ -/* eslint-disable indent */ -import { upsertWorkerInfo } from "../../../database/workerInfo"; -import { Command } from "../../../structures/Command"; -import { permissions } from "../../../providers/permissions"; -import { OrderStatus, getClaimedOrder } from "../../../database/orders"; -import { db } from "../../../database/database"; -import { text } from "../../../providers/config"; -import { client } from "../../../providers/client"; -import { CommandInteraction, StringSelectMenuBuilder, ComponentType, EmbedBuilder } from "discord.js"; - -const claimedOrderLocks = new Map(); // Map to store claim locks for each order ID -const claimedOrders = new Set(); // Set to store claimed order IDs - -export const command = new Command("eclaim", "Claims an order.") - .addPermission(permissions.employee) - .setExecutor(async (int: CommandInteraction) => { - const existingClaim = await getClaimedOrder(int.user); - if (existingClaim) { - console.log(`Existing claim found for ${int.user.id} on order ${existingClaim.id}`); - await int.reply({ content: text.commands.claim.existing, ephemeral: true }); - return; - } - - // Retrieve the selected values from interaction - const orderIds = int.customId === "claim_order" - ? int.values - : int.message?.components - .find((row) => row.components.some((component) => component.customId === "claim_order")) - .components.find((component) => component.customId === "claim_order").value.split(","); - - const orders = await db.orders.findMany({ - where: { - id: { in: orderIds }, - status: OrderStatus.Unprepared, - claimer: null, // Check if the order is not already claimed - }, - select: { - id: true, - user: true, - details: true, - status: true, - }, - }); - - if (orders.length === 0) { - await int.reply({ content: "There are no available orders to claim.", ephemeral: true }); - return; - } - - const options = orders.map(order => { - const details = order.details.length > 50 ? `${order.details.substring(0, 47)}...` : order.details; - const user = order.user.length > 50 ? `${order.user.substring(0, 47)}...` : order.user; - - return { - label: order.id, - description: `Details: ${details}\nUser: ${user}\nStatus: ${order.status}`, - value: order.id, - details: order.details, - }; - }); - const minValues = Math.min(1, orders.length); - const maxValues = Math.min(3, orders.length); - - const selectMenu = new StringSelectMenuBuilder() - .setCustomId("claim_order") - .setPlaceholder("Select orders to claim") - .addOptions(options) - .setMinValues(minValues) // Set minimum selected values - .setMaxValues(maxValues); // Set maximum selected values - - const actionRow = { - type: ComponentType.ActionRow, - components: [selectMenu], - }; - - const embed = new EmbedBuilder() - .setDescription("Please select orders to claim.") - .setColor("#00FF00"); - - try { - const reply = await int.reply({ - embeds: [embed], - components: [actionRow], - ephemeral: true, - }); - - // Schedule a deletion of the reply after a certain time (e.g., 10 seconds) - setTimeout(() => { - reply.delete(); - }, 10000); - } catch (error) { - console.error("Error replying to interaction:", error); - } - }); - -client.on("interactionCreate", async (interaction) => { - if (!interaction.isStringSelectMenu()) return; - - const componentId = interaction.customId; - if (componentId === "claim_order") { - // Retrieve the selected values from interaction - const orderIds = interaction.values || []; - const claimedOrderMessages = []; - - for (let i = 0; i < orderIds.length; i++) { - const orderId = orderIds[i]; - try { - // Check if a claim lock exists for this order - if (claimedOrderLocks.has(orderId) && claimedOrderLocks.get(orderId)) { - claimedOrderMessages.push(`Another user is currently claiming Order ${orderId}. Please try again later.`); - continue; - } - - // Set a claim lock for this order - claimedOrderLocks.set(orderId, true); - - // Check if the order is still unclaimed in the database - const unclaimedOrder = await db.orders.findFirst({ - where: { id: orderId, status: OrderStatus.Unprepared, claimer: null }, - }); - - if (!unclaimedOrder) { - console.log(`Order ${orderId} is already claimed.`); - claimedOrderMessages.push(`Order ${orderId} has already been claimed.`); - claimedOrderLocks.delete(orderId); // Release the claim lock for this order - continue; - } - - // Update the claimed order and release the claim lock - await db.orders.update({ - where: { id: orderId }, - data: { claimer: interaction.user.id, status: OrderStatus.Preparing }, - }); - - claimedOrders.add(orderId); // Store claimed order ID in the Set - claimedOrderLocks.delete(orderId); - - claimedOrderMessages.push(`Order ${orderId} claimed successfully.`); - } catch (error) { - console.error(`Error processing Order ${orderId}:`, error); - claimedOrderMessages.push(`Error processing Order ${orderId}`); - } finally { - claimedOrderLocks.delete(orderId); - } - } - - // Send a single reply summarizing the claimed orders - try { - const reply = await interaction.reply({ - content: `Claiming results:\n${claimedOrderMessages.join('\n')}`, - ephemeral: false, - }); - - // Remove the first reply after a certain time (e.g., 5 seconds) - setTimeout(() => { - reply.delete(); - }, 5000); - } catch (error) { - console.error("Error replying to interaction:", error); - } - } -}); +/* eslint-disable quotes */ +/* eslint-disable indent */ +import {Command} from "../src/structures/Command"; +import {permissions} from "../src/providers/permissions"; +import {getClaimedOrder, OrderStatus} from "../src/database/orders"; +import {db} from "../src/database/database"; +import {text} from "../src/providers/config"; +import {client} from "../src/providers/client"; +import {CommandInteraction, ComponentType, EmbedBuilder, StringSelectMenuBuilder} from "discord.js"; + +const claimedOrderLocks = new Map(); // Map to store claim locks for each order ID +const claimedOrders = new Set(); // Set to store claimed order IDs + +export const command = new Command("eclaim", "Claims an order.") + .addPermission(permissions.employee) + .setExecutor(async (int: CommandInteraction) => { + const existingClaim = await getClaimedOrder(int.user); + if (existingClaim) { + console.log(`Existing claim found for ${int.user.id} on order ${existingClaim.id}`); + await int.reply({ content: text.commands.claim.existing, ephemeral: true }); + return; + } + + // Retrieve the selected values from interaction + const orderIds = int.customId === "claim_order" + ? int.values + : int.message?.components + .find((row) => row.components.some((component) => component.customId === "claim_order")) + .components.find((component) => component.customId === "claim_order").value.split(","); + + const orders = await db.orders.findMany({ + where: { + id: { in: orderIds }, + status: OrderStatus.Unprepared, + claimer: null, // Check if the order is not already claimed + }, + select: { + id: true, + user: true, + details: true, + status: true, + }, + }); + + if (orders.length === 0) { + await int.reply({ content: "There are no available orders to claim.", ephemeral: true }); + return; + } + + const options = orders.map(order => { + const details = order.details.length > 50 ? `${order.details.substring(0, 47)}...` : order.details; + const user = order.user.length > 50 ? `${order.user.substring(0, 47)}...` : order.user; + + return { + label: order.id, + description: `Details: ${details}\nUser: ${user}\nStatus: ${order.status}`, + value: order.id, + details: order.details, + }; + }); + const minValues = Math.min(1, orders.length); + const maxValues = Math.min(3, orders.length); + + const selectMenu = new StringSelectMenuBuilder() + .setCustomId("claim_order") + .setPlaceholder("Select orders to claim") + .addOptions(options) + .setMinValues(minValues) // Set minimum selected values + .setMaxValues(maxValues); // Set maximum selected values + + const actionRow = { + type: ComponentType.ActionRow, + components: [selectMenu], + }; + + const embed = new EmbedBuilder() + .setDescription("Please select orders to claim.") + .setColor("#00FF00"); + + try { + const reply = await int.reply({ + embeds: [embed], + components: [actionRow], + ephemeral: true, + }); + + // Schedule a deletion of the reply after a certain time (e.g., 10 seconds) + setTimeout(() => { + reply.delete(); + }, 10000); + } catch (error) { + console.error("Error replying to interaction:", error); + } + }); + +client.on("interactionCreate", async (interaction) => { + if (!interaction.isStringSelectMenu()) return; + + const componentId = interaction.customId; + if (componentId === "claim_order") { + // Retrieve the selected values from interaction + const orderIds = interaction.values || []; + const claimedOrderMessages = []; + + for (let i = 0; i < orderIds.length; i++) { + const orderId = orderIds[i]; + try { + // Check if a claim lock exists for this order + if (claimedOrderLocks.has(orderId) && claimedOrderLocks.get(orderId)) { + claimedOrderMessages.push(`Another user is currently claiming Order ${orderId}. Please try again later.`); + continue; + } + + // Set a claim lock for this order + claimedOrderLocks.set(orderId, true); + + // Check if the order is still unclaimed in the database + const unclaimedOrder = await db.orders.findFirst({ + where: { id: orderId, status: OrderStatus.Unprepared, claimer: null }, + }); + + if (!unclaimedOrder) { + console.log(`Order ${orderId} is already claimed.`); + claimedOrderMessages.push(`Order ${orderId} has already been claimed.`); + claimedOrderLocks.delete(orderId); // Release the claim lock for this order + continue; + } + + // Update the claimed order and release the claim lock + await db.orders.update({ + where: { id: orderId }, + data: { claimer: interaction.user.id, status: OrderStatus.Preparing }, + }); + + claimedOrders.add(orderId); // Store claimed order ID in the Set + claimedOrderLocks.delete(orderId); + + claimedOrderMessages.push(`Order ${orderId} claimed successfully.`); + } catch (error) { + console.error(`Error processing Order ${orderId}:`, error); + claimedOrderMessages.push(`Error processing Order ${orderId}`); + } finally { + claimedOrderLocks.delete(orderId); + } + } + + // Send a single reply summarizing the claimed orders + try { + const reply = await interaction.reply({ + content: `Claiming results:\n${claimedOrderMessages.join('\n')}`, + ephemeral: false, + }); + + // Remove the first reply after a certain time (e.g., 5 seconds) + setTimeout(() => { + reply.delete(); + }, 5000); + } catch (error) { + console.error("Error replying to interaction:", error); + } + } +}); diff --git a/src/api/server.ts b/src/api/server.ts new file mode 100644 index 0000000..18835f2 --- /dev/null +++ b/src/api/server.ts @@ -0,0 +1,125 @@ +import express from "express"; +import { createServer } from "http"; +import { Server } from "socket.io"; +import { db } from "../database/database"; +import { pinMap } from "../commands/dashboard/auth"; +import { z } from "zod"; + +const app = express(); +const httpServer = createServer(app); +const io = new Server(httpServer, { + cors: { + origin: "http://localhost:3000", + methods: ["GET", "POST"], + }, +}); + +app.get("/orders", async (req, res) => { + return db.orders.findMany(); +}); + +// 7 days expiry +const expiryTime = 7 * 24 * 60 * 60 * 1000; + +export type LoginRequest = { + pin: string; + userID: string; + state: string; + purge?: boolean; +}; + +app.get("/login", async (req, res) => { + // 0-9a-z + const pin = z + .string() + .length(6) + .regex(/^[0-9a-z]*$/) + .safeParse(req.query.pin); + if (!pin.success) { + return res.status(400).send("Invalid pin"); + } + + const userID = z + .string() + .min(17) + .max(18) + .regex(/^\d+$/) + .safeParse(req.query.userID); + if (!userID.success) { + return res.status(400).send("Invalid user ID"); + } + + // does this user exist in the UserInfo table? + const user = await db.userInfo.findUnique({ + where: { + id: userID.data, + }, + }); + + if (!user) { + return res.status(404).send("User not found"); + } + + // is this pin valid? + const pins = [...pinMap.values()]; + if (!pins.includes(pin.data)) { + return res.status(403).send("Pin not found"); + } + + // KILL the pin + pinMap.delete(userID.data); + + // do you already have a token? if so return it + const existingToken = await db.authUser.findFirst({ + where: { + userID: userID.data, + }, + }); + + // blank values are falsy + const purge = req.query.purge === "" || req.query.purge; + if (existingToken && purge) { + await db.authUser.delete({ + where: { + userID: userID.data, + }, + }); + } else if (existingToken) { + // not modified 304 + return res.status(304).send({ + token: existingToken.token, + expiry: existingToken.expiry, + state: req.query.state, // for CSRF protection + }); + } + + // great, the pin and user are valid! create a new AuthUser + // exactly 32 characters, 0-9a-z, expires in 7 days. + const token = new Array(32) + .fill(0) + .map(() => Math.random().toString(36)[2]) + .join(""); + + const authUser = await db.authUser.create({ + data: { + token: token, + expiry: new Date(Date.now() + expiryTime), + userID: userID.data, + }, + }); + + res.status(200).send({ + token: authUser.token, + expiry: authUser.expiry, + state: req.query.state, // for CSRF protection + }); +}); + +io.on("connection", (socket) => { + console.log("someone's here..."); + socket.emit("ping"); +}); + +httpServer.listen(3001, () => { + console.log("Server is running on port 3001"); +}); \ No newline at end of file diff --git a/src/commands/Devs/Select.ts b/src/commands/Devs/Select.ts index 03303d7..a6c19a6 100644 --- a/src/commands/Devs/Select.ts +++ b/src/commands/Devs/Select.ts @@ -1,13 +1,6 @@ -import { development } from "../../providers/env"; -import { execSync } from "child_process"; -import { format } from "../../utils/string"; -import { transpile } from "typescript"; -import { permissions } from "../../providers/permissions"; -import { Command } from "../../structures/Command"; -import { client } from "../../providers/client"; -import { channel } from "diagnostics_channel"; -import { StringSelectMenuBuilder, EmbedBuilder } from "discord.js"; -import { ExtendedCommand } from "../../structures/extendedCommand"; +import {permissions} from "../../providers/permissions"; +import {EmbedBuilder, StringSelectMenuBuilder} from "discord.js"; +import {ExtendedCommand} from "../../structures/extendedCommand"; export const command = new ExtendedCommand( { name: "select", description: "Select Menu Example.", local: true } @@ -22,19 +15,19 @@ export const command = new ExtendedCommand( label: "Option 1", value: "option_1", description: "The first option", - type: 3 // changed from "SELECT_MENU" to 3 + // type: 3 // changed from "SELECT_MENU" to 3 }, { label: "Option 2", value: "option_2", description: "The second option", - type: 3 // changed from "SELECT_MENU" to 3 + // type: 3 // changed from "SELECT_MENU" to 3 }, { label: "Option 3", value: "option_3", description: "The third option", - type: 3 // changed from "SELECT_MENU" to 3 + // type: 3 // changed from "SELECT_MENU" to 3 }, ]); diff --git a/src/commands/Devs/avatar.ts b/src/commands/Devs/avatar.ts deleted file mode 100644 index 7e161a6..0000000 --- a/src/commands/Devs/avatar.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { ExtendedCommand } from "./../../structures/extendedCommand"; -/* eslint-disable quotes */ -/* eslint-disable indent */ -import { client } from "../../providers/client"; -import { permissions } from "../../providers/permissions"; -import { Command } from "../../structures/Command"; -import { CommandInteraction, EmbedBuilder } from "discord.js"; - -export const command = new ExtendedCommand({ name: "avatar", description: "Some info." }) - .addPermission(permissions.developer) // AnyRank - .addSubCommand((subcommand) => - subcommand - .setName("attach") - .setDescription("Attach an image to update the bot's avatar.") - .addAttachmentOption((option) => - option - .setName("attachment") - .setDescription("The image to attach for updating the avatar.") - .setRequired(true) - ) - ) - .setExecutor(async (int: CommandInteraction) => { - // Check the subcommand - const subcommand = int.options.getSubcommand(true); - - if (subcommand === "attach") { - // Defer the reply to avoid potential issues with the interaction being deleted - await int.deferReply({ ephemeral: true }); - - // Fetch the attachment from the options - const attachment = int.options.get("attachment", true)?.attachment; - - if (!attachment) { - await int.editReply({ content: "Attachment is missing or not valid." }); - return; - } - - try { - // Read the attachment and set it as the bot's avatar - const avatarBuffer = await fetch(attachment.url).then((res) => res.arrayBuffer()); - const buffer = Buffer.from(avatarBuffer); // Convert ArrayBuffer to Buffer - await client.user?.setAvatar(buffer); - - // Example: Respond with success message - const embed = new EmbedBuilder() - .setTitle('Bot Avatar Updated') - .setDescription('Bot avatar updated successfully!') - .setColor('#00ff00') // You can customize the color - .setAuthor({ name: int.user.username, iconURL: int.user.displayAvatarURL() }) - .setFooter({ text: 'Update Avatar Command', iconURL: client.user?.displayAvatarURL() }); - - // Reply with the success message and the image embed - await int.editReply({ embeds: [embed] }); - - // Extra logging: Print the bot's current avatar URL after the update - console.log("Bot's current avatar URL:", client.user?.displayAvatarURL()); - } catch (error) { - // Cast error to Error type - const errorObject = error as Error; - - // Example: Respond with error message - console.error('Failed to update avatar:', errorObject); - - const errorEmbed = new EmbedBuilder() - .setTitle('Error Updating Avatar') - .setDescription(`Failed to update bot avatar: ${errorObject.message}`) - .setColor('#ff0000') // You can customize the color - .setAuthor({ name: int.user.username, iconURL: int.user.displayAvatarURL() }) - .setFooter({ text: 'Update Avatar Command', iconURL: client.user?.displayAvatarURL() }); - - // Reply with the error message - await int.editReply({ embeds: [errorEmbed] }); - } - } else { - // Handle other subcommands or the default behavior here - } - }); diff --git a/src/commands/Devs/botinfo.ts b/src/commands/Devs/botinfo.ts index df7dc5d..66ccea8 100644 --- a/src/commands/Devs/botinfo.ts +++ b/src/commands/Devs/botinfo.ts @@ -4,8 +4,10 @@ import os from "os"; import { client } from "../../providers/client"; import { permissions } from "../../providers/permissions"; import { Command } from "../../structures/Command"; +import { ExtendedCommand } from "../../structures/extendedCommand"; +import { config } from "../../providers/config"; -export const command = new Command("botinfo", "Displays information about the bot.") +export const command = new ExtendedCommand({ name: "botinfo", description: "Displays information about the bot.", local: true }) .addPermission(permissions.developer) .setExecutor(async (interaction: CommandInteraction) => { // Get the number of guilds (servers) the bot is in @@ -27,7 +29,7 @@ export const command = new Command("botinfo", "Displays information about the bo .setTitle("Bot Information") .addFields( { name: "Name", value: client.user?.username || "Unknown", inline: true }, - { name: "Version", value: "1.0.0", inline: true }, + { name: "Version", value: "1.3.5", inline: true }, { name: "Guilds", value: guildsSize, inline: true }, { name: "Uptime", value: uptimeString, inline: true }, { name: "Memory Usage", value: `${memoryUsage} MB`, inline: true }, diff --git a/src/commands/Devs/button.ts b/src/commands/Devs/button.ts index 864303e..37e75bd 100644 --- a/src/commands/Devs/button.ts +++ b/src/commands/Devs/button.ts @@ -1,14 +1,6 @@ -import { development } from "../../providers/env"; -import { execSync } from "child_process"; -import { format } from "../../utils/string"; -import { transpile } from "typescript"; -import { permissions } from "../../providers/permissions"; -import { Command } from "../../structures/Command"; -import { client } from "../../providers/client"; -import { channel } from "diagnostics_channel"; -import { ButtonBuilder } from "discord.js"; -import { ButtonStyle, ActionRowBuilder } from "discord.js"; -import { ExtendedCommand } from "../../structures/extendedCommand"; +import {permissions} from "../../providers/permissions"; +import {ActionRowBuilder, ButtonBuilder, ButtonStyle} from "discord.js"; +import {ExtendedCommand} from "../../structures/extendedCommand"; export const command = new ExtendedCommand( { name: "but", description: "hm.", local: true } @@ -30,8 +22,8 @@ export const command = new ExtendedCommand( .setStyle(ButtonStyle.Success) .setCustomId("3"); - const row = new ActionRowBuilder() - .addComponents(button1, button2, button3,); + const row = new ActionRowBuilder() + .addComponents(button1, button2, button3); await int.reply({ content: "Here are three buttons:", diff --git a/src/commands/Devs/currencyedit.ts b/src/commands/Devs/currencyedit.ts new file mode 100644 index 0000000..870440e --- /dev/null +++ b/src/commands/Devs/currencyedit.ts @@ -0,0 +1,68 @@ +/* eslint-disable indent */ +import {permissions} from "../../providers/permissions"; +import {getUserInfo, updateBalance} from "../../database/userInfo"; +import {ExtendedCommand} from "../../structures/extendedCommand"; +import {config} from "../../providers/config"; + +export const command = new ExtendedCommand({ name: "currencyedit", description: "Manage user balance.", servers: [config.servers.extraServer], local: true }) + .addPermission(permissions.developer) + .addSubCommand((subcommand) => + subcommand + .setName("set") + .setDescription("Set user balance.") + .addUserOption((option) => + option + .setName("user") + .setDescription("The user whose balance you want to set.") + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName("amount") + .setDescription("The amount to set as the user's balance.") + .setRequired(true) + ) + ) + .addSubCommand((subcommand) => + subcommand + .setName("check") + .setDescription("Check user balance.") + .addUserOption((option) => + option + .setName("user") + .setDescription("The user whose balance you want to check.") + .setRequired(true) + ) + ) + .setExecutor(async (int) => { + const subcommand = int.options.getSubcommand(true); + + if (subcommand === "set") { + const user = int.options.getUser("user", true); + const amount = int.options.getInteger("amount", true); + + try { + await updateBalance(user.id, amount, 0); + await int.reply(`User ${user.username}'s balance has been set to ${amount}.`); + } catch (error) { + console.error("Error setting user balance:", error); + await int.reply("An error occurred while setting user balance."); + } + } else if (subcommand === "check") { + const user = int.options.getUser("user", true); + + try { + const userInfo = await getUserInfo(user.id); + if (userInfo) { + await int.reply(`User ${user.username}'s balance is ${userInfo.balance}.`); + } else { + await int.reply("User balance not found."); + } + } catch (error) { + console.error("Error checking user balance:", error); + await int.reply("An error occurred while checking user balance."); + } + } else { + await int.reply("This subcommand is not yet implemented."); + } + }); diff --git a/src/commands/Devs/menu.ts b/src/commands/Devs/menu.ts index 1711075..4cd4ea4 100644 --- a/src/commands/Devs/menu.ts +++ b/src/commands/Devs/menu.ts @@ -1,15 +1,14 @@ /* eslint-disable indent */ -import { permissions } from "../../providers/permissions"; -import { Command } from "../../structures/Command"; -import { EmbedBuilder, CommandInteraction } from "discord.js"; -import { db } from "../../database/database"; -import { ExtendedCommand } from "../../structures/extendedCommand"; +import {permissions} from "../../providers/permissions"; +import {EmbedBuilder} from "discord.js"; +import {db} from "../../database/database"; +import {ExtendedCommand} from "../../structures/extendedCommand"; export const command = new ExtendedCommand({ name: "menu", description: "Manage menu Items.", local: true }) .addPermission(permissions.developer) .addSubCommand((subcommand) => subcommand - .setName("add") + .setName("add") .setDescription("Add a new menu item.") .addStringOption((option) => option @@ -83,7 +82,7 @@ export const command = new ExtendedCommand({ name: "menu", description: "Manage .setName("list") .setDescription("List all menu items.") ) - .setExecutor(async (int: CommandInteraction) => { + .setExecutor(async (int) => { const subcommand = int.options.getSubcommand(true); if (subcommand === "add") { diff --git a/src/commands/Devs/terms.ts b/src/commands/Devs/terms.ts index 1af8c27..74c0393 100644 --- a/src/commands/Devs/terms.ts +++ b/src/commands/Devs/terms.ts @@ -2,4 +2,4 @@ import { Command } from "../../structures/Command"; export const command = new Command("tos", "Gives you a link to our tos.") .setExecutor(async int => { int.reply("https://drunk-bartender.org/Terms_of_Service"); - }); + }); \ No newline at end of file diff --git a/src/commands/Devs/transfer.ts b/src/commands/Devs/transfer.ts deleted file mode 100644 index 3308e67..0000000 --- a/src/commands/Devs/transfer.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* eslint-disable indent */ -import { PrismaClient } from "@prisma/client"; -import { CommandInteraction } from "discord.js"; -import { permissions } from "../../providers/permissions"; -import { Command } from "../../structures/Command"; - -const prisma = new PrismaClient(); - -export const command = new Command("transfer", "Transfers data from the old schema to the new schema.") - .addPermission(permissions.admin) - .setExecutor(async (int: CommandInteraction) => { - try { - // Retrieve all the existing user data - const usersData = await prisma.userInfo.findMany(); - - //console.log(`Total user data count: ${usersData.length}`); - - // Transfer the data to the new schema - for (const data of usersData) { - const userId = data.id; - const guildsXPData = data.guildsxp; - - //console.log(`Transferring data for user with ID: ${userId}`); - - const guildsXPDataObject = parseGuildsXPData(guildsXPData); - - //console.log(`GuildsXPDataObject: ${JSON.stringify(guildsXPDataObject)}`); - - for (const guildId in guildsXPDataObject) { - const { id } = guildsXPDataObject[guildId]; - - // console.log(`Transferring data for guild with ID: ${guildId}`); - - // Create or update the guildsXP data in the new schema - await prisma.guildsXP.upsert({ - where: { userId_guildId: { userId, guildId } }, - create: { - guildId: guildId, - userName: "", // Set userName as empty string for now - level: guildsXPDataObject[guildId].level, - exp: guildsXPDataObject[guildId].xp, - user: { connect: { id: userId } }, - }, - update: { - userName: "", // Set userName as empty string for now - level: guildsXPDataObject[guildId].level, - exp: guildsXPDataObject[guildId].xp, - }, - }); - - // console.log(`Data transferred for guild with ID: ${guildId}`); - } - - // Update the guildsxp field to be empty - await prisma.userInfo.update({ - where: { id: userId }, - data: { guildsxp: "{}" }, - }); - - //console.log(`Data transferred for user with ID: ${userId}`); - } - - await int.reply("Data transfer completed successfully."); - } catch (error) { - console.error("Error transferring data:", error); - await int.reply("Error transferring data. Please check the logs for more information."); - } finally { - await prisma.$disconnect(); - } - }); - -// Function to parse the guildsXPData string and handle potential errors -function parseGuildsXPData(guildsXPData: string | null): Record { - try { - if (guildsXPData === null) { - // Handle the case where guildsXPData is null - return {}; - } - - const parsedData = JSON.parse(guildsXPData); - - if (typeof parsedData === "object" && !Array.isArray(parsedData)) { - return parsedData; - } - } catch (error) { - console.error("Error parsing guildsXPData:", error); - } - - return {}; -} diff --git a/src/commands/Devs/workst.ts b/src/commands/Devs/workst.ts index d0c5847..e728432 100644 --- a/src/commands/Devs/workst.ts +++ b/src/commands/Devs/workst.ts @@ -1,17 +1,15 @@ /* eslint-disable indent */ -import { WorkerInfo } from "@prisma/client"; -import { permissions } from "../../providers/permissions"; -import { Command } from "../../structures/Command"; -import { getWorkerInfo } from "../../database/workerInfo"; // Update with the correct path -import { CommandInteraction, EmbedBuilder } from "discord.js"; -import { ExtendedCommand } from "../../structures/extendedCommand"; +import {permissions} from "../../providers/permissions"; +import {getWorkerInfo} from "../../database/workerInfo"; // Update with the correct path +import {EmbedBuilder} from "discord.js"; +import {ExtendedCommand} from "../../structures/extendedCommand"; export const command = new ExtendedCommand( { name: "workst", description: "view a worker's stats by their id.", local: true } ) .addPermission(permissions.employee) - .setExecutor(async (int: CommandInteraction) => { + .setExecutor(async (int) => { try { const userId = int.options.getString("user_id"); @@ -32,8 +30,8 @@ export const command = new ExtendedCommand( .addFields([ { name: "Preparations", value: workerInfo.preparations.toString(), inline: true }, { name: "Deliveries", value: workerInfo.deliveries.toString(), inline: true }, - { name: "Claim Usage Count", value: workerInfo.claimUsageCount.toString(), inline: true }, - { name: "Brew Usage Count", value: workerInfo.brewUsageCount.toString(), inline: true } + // { name: "Claim Usage Count", value: workerInfo.claimUsageCount.toString(), inline: true }, + // { name: "Brew Usage Count", value: workerInfo.brewUsageCount.toString(), inline: true } ]) .setTimestamp(); diff --git a/src/commands/Devs/ws.ts b/src/commands/Devs/ws.ts index 2e55eb8..8b09ee9 100644 --- a/src/commands/Devs/ws.ts +++ b/src/commands/Devs/ws.ts @@ -1,45 +1,103 @@ -/* eslint-disable quotes */ /* eslint-disable indent */ -import { CommandInteraction, EmbedBuilder, UserResolvable } from "discord.js"; -import { db } from "../../database/database"; -import { getWorkerStats } from "../../database/workerstats"; +import { ColorResolvable, CommandInteraction, EmbedBuilder } from "discord.js"; +import { getWorkerStats, getWorkerStatsList, upsertWorkerStats } from "../../database/workerstats"; import { resolveUserId } from "../../utils/id"; -import { Command } from "../../structures/Command"; import { permissions } from "../../providers/permissions"; import { ExtendedCommand } from "../../structures/extendedCommand"; -export const command = new ExtendedCommand( - { name: "ws", description: "View worker statistics.", local: true } -) - +export const command = new ExtendedCommand({ + name: "ws", + description: "Manage worker statistics.", + local: true +}) .addPermission(permissions.admin) - .addUserOption((option) => - option - .setName("user") - .setDescription("The user to view statistics for.") - .setRequired(false) + .addSubCommand(subcommand => + subcommand + .setName("stats") + .setDescription("View statistics for a user.") + .addUserOption(option => + option + .setName("user") + .setDescription("The user to view statistics for.") + .setRequired(false) + ) + ) + .addSubCommand(subcommand => + subcommand + .setName("list") + .setDescription("List users with worker statistics.") ) .setExecutor(async (int: CommandInteraction) => { - const targetUser = int.options.getUser("user", false); + const subcommand = (int.options as any).getSubcommand(true); - let userId: string; - if (targetUser) { - userId = resolveUserId(targetUser); - } else { - userId = int.user.id; - } + // Update lastUsed timestamp + const userId = resolveUserId(int.user); + await upsertWorkerStats(userId, { lastUsed: new Date() }); + + if (subcommand === "stats") { + const targetUser = int.options.getUser("user", false); + + let userId: string; + let username: string; + if (targetUser) { + userId = resolveUserId(targetUser); + username = targetUser.username; + } else { + userId = int.user.id; + username = int.user.username; + } - const workerStats = await getWorkerStats(userId); + const workerStats = await getWorkerStats(userId); + if (!workerStats) { + await int.reply({ content: "No worker statistics found for this user.", ephemeral: true }); + return; + } - const embed = new EmbedBuilder() - .setTitle(`${targetUser ? targetUser.tag : int.user.username}'s Worker Statistics`) - .addFields([ - { name: "Orders Brewed", value: workerStats.ordersBrewed.toString(), inline: true }, - { name: "Orders Delivered", value: workerStats.ordersDelivered.toString(), inline: true }, - { name: "Last Used", value: workerStats.lastUsed.toLocaleString(), inline: true }, - { name: "Last Command", value: workerStats.lastCommand || "None", inline: true }, - ]) - .toJSON(); + // Calculate days since last used + const lastUsed = new Date(workerStats.lastUsed); + const now = new Date(); + const daysSinceLastUsed = Math.floor((now.getTime() - lastUsed.getTime()) / (1000 * 3600 * 24)); - await int.reply({ embeds: [embed] }); + // Determine activity status and color + let activityStatus: string; + let activityColor: ColorResolvable; + if (daysSinceLastUsed > 5) { + activityStatus = "Inactive"; + activityColor = "Red"; // Red color + } else { + activityStatus = "Active"; + activityColor = "Green"; // Green color + } + + const embed = new EmbedBuilder() + .setTitle(`${username}'s Worker Statistics`) + .addFields([ + { name: "Orders Brewed", value: workerStats.ordersBrewed.toString(), inline: true }, + { name: "Orders Delivered", value: workerStats.ordersDelivered.toString(), inline: true }, + { name: "Last Used", value: lastUsed.toLocaleString(), inline: true }, + { name: "Days Since Last Used", value: `${daysSinceLastUsed} days`, inline: true }, + { name: "Last Command", value: workerStats.lastCommand || "None", inline: true }, + { name: "Activity Status", value: `**${activityStatus}**`, inline: true }, // Add activity status field with bold text + ]) + .setColor(activityColor) // Set color of the embed + .toJSON(); + + await int.reply({ embeds: [embed] }); + } else if (subcommand === "list") { + const workerStatsList = await getWorkerStatsList(); + if (workerStatsList.length === 0) { + await int.reply({ content: "No users found with worker statistics.", ephemeral: true }); + return; + } + + const userList = workerStatsList.map(stats => `<@${stats.id}> ID: ${stats.id}`).join("\n"); + const embed = new EmbedBuilder() + .setTitle("Users with Worker Statistics") + .setDescription(userList) + .toJSON(); + + await int.reply({ embeds: [embed] }); + } else { + await int.reply({ content: "Invalid sub-command.", ephemeral: true }); + } }); \ No newline at end of file diff --git a/src/commands/crime.ts b/src/commands/crime.ts deleted file mode 100644 index 374715b..0000000 --- a/src/commands/crime.ts +++ /dev/null @@ -1,40 +0,0 @@ -//crime.ts -import { db } from "../../database/database"; -import { upsertUserInfo } from "../../database/userInfo"; -import { constants, text } from "../../providers/config"; -import { Command } from "../../structures/Command"; -import { format } from "../../utils/string"; -import pms from "pretty-ms"; -import { randRange, sampleArray } from "../../utils/utils"; -const cooldowns: Record = {}; - -export const command = new Command("crime", "Try your chances on doing crime!") - .setExecutor(async int => { - if (int.user.id in cooldowns && cooldowns[int.user.id] >= Date.now()) { - await int.reply( - format( - text.errors.cooldown, - pms(cooldowns[int.user.id] - Date.now(), { compact: true, secondsDecimalDigits: 1 }) - ) - ); - return; - } - const result = [ - "Succesful", - "Failure" - ]; - const awnser = result[Math.floor(Math.random() * result.length)]; - if (awnser === "Failure") { - const info = await upsertUserInfo(int.user, int.guild?.id || ''); - const obtained = randRange(...constants.crime.amountRange); - cooldowns[int.user.id] = Date.now() + constants.crime.cooldownMs; - await db.userInfo.update({ where: { id: info.id }, data: { balance: { decrement: obtained } } }); - await int.reply(format(sampleArray(text.commands.crime.failure), `\`$${-obtained}\``)); - } else { - const info = await upsertUserInfo(int.user, int.guild?.id || ''); - const obtained = randRange(...constants.crime.amountRange); - cooldowns[int.user.id] = Date.now() + constants.crime.cooldownMs; - await db.userInfo.update({ where: { id: info.id }, data: { balance: { increment: obtained } } }); - await int.reply(format(sampleArray(text.commands.crime.sucess), `\`$${obtained}\``)); - } - }); diff --git a/src/commands/daily.ts b/src/commands/daily.ts deleted file mode 100644 index 532f62d..0000000 --- a/src/commands/daily.ts +++ /dev/null @@ -1,27 +0,0 @@ -//daily.ts -import { db } from "../../database/database"; -import { upsertUserInfo } from "../../database/userInfo"; -import { constants, text } from "../../providers/config"; -import { Command } from "../../structures/Command"; -import { format } from "../../utils/string"; -import pms from "pretty-ms"; -import { randRange, sampleArray } from "../../utils/utils"; -const cooldowns: Record = {}; - -export const command = new Command("daily", "Get your daily income!.") - .setExecutor(async int => { - if (int.user.id in cooldowns && cooldowns[int.user.id] >= Date.now()) { - await int.reply( - format( - text.errors.cooldown, - pms(cooldowns[int.user.id] - Date.now(), { compact: true, secondsDecimalDigits: 1 }) - ) - ); - return; - } - const info = await upsertUserInfo(int.user, int.guild?.id || ''); - const obtained = randRange(...constants.daily.amountRange); - cooldowns[int.user.id] = Date.now() + constants.daily.cooldownMs; - await db.userInfo.update({ where: { id: info.id }, data: { balance: { increment: obtained } } }); - await int.reply(format(sampleArray(text.commands.daily.responses), `\`$${obtained}\``)); - }); \ No newline at end of file diff --git a/src/commands/dashboard/auth.ts b/src/commands/dashboard/auth.ts new file mode 100644 index 0000000..7c80c66 --- /dev/null +++ b/src/commands/dashboard/auth.ts @@ -0,0 +1,40 @@ +/* eslint-disable indent */ +import { Snowflake } from "discord.js"; +import { LifetimeMap } from "../../structures/LifetimeMap"; +import { ExtendedCommand } from "../../structures/extendedCommand"; +import { config } from "../../providers/config"; + +export const pinMap = new LifetimeMap(15 * 60 * 1000); + +export const command = new ExtendedCommand({ + name: "login", + description: "Generates a pin required to login to the DB dashboard.", +}) + .addOption("boolean", (o) => + o + .setName("refresh") + .setDescription("Generate a new pin.") + .setRequired(false) + ) + .setExecutor(async (int) => { + if (pinMap.has(int.user.id) && !int.options.getBoolean("refresh")) { + await int.reply({ + ephemeral: true, + content: + "A pin's already been generated. If you've lost it, include the refresh option. Otherwise, wait for the current pin to expire.", + }); + } // generate a random 6-character pin + else { + let pin = Math.random().toString(36).substring(2, 8); + // unlikely, but check for collisions + // convert iterator to array to check for collisions + const pins = [...pinMap.values()]; + while (pins.includes(pin)) + pin = Math.random().toString(36).substring(2, 8); + pinMap.set(int.user.id, pin); + await int.reply({ + ephemeral: true, + content: `Your pin was generated successfully! Head to ${config.dashboardUrl}/login and enter the following pin: \`${pin}\`. It will expire in 15 minutes.`, + }); + } + }); \ No newline at end of file diff --git a/src/commands/economy/crime.ts b/src/commands/economy/crime.ts index 374715b..6c6e119 100644 --- a/src/commands/economy/crime.ts +++ b/src/commands/economy/crime.ts @@ -25,13 +25,13 @@ export const command = new Command("crime", "Try your chances on doing crime!") ]; const awnser = result[Math.floor(Math.random() * result.length)]; if (awnser === "Failure") { - const info = await upsertUserInfo(int.user, int.guild?.id || ''); + const info = await upsertUserInfo(int.user); const obtained = randRange(...constants.crime.amountRange); cooldowns[int.user.id] = Date.now() + constants.crime.cooldownMs; await db.userInfo.update({ where: { id: info.id }, data: { balance: { decrement: obtained } } }); await int.reply(format(sampleArray(text.commands.crime.failure), `\`$${-obtained}\``)); } else { - const info = await upsertUserInfo(int.user, int.guild?.id || ''); + const info = await upsertUserInfo(int.user); const obtained = randRange(...constants.crime.amountRange); cooldowns[int.user.id] = Date.now() + constants.crime.cooldownMs; await db.userInfo.update({ where: { id: info.id }, data: { balance: { increment: obtained } } }); diff --git a/src/commands/economy/daily.ts b/src/commands/economy/daily.ts index 532f62d..582df96 100644 --- a/src/commands/economy/daily.ts +++ b/src/commands/economy/daily.ts @@ -6,22 +6,33 @@ import { Command } from "../../structures/Command"; import { format } from "../../utils/string"; import pms from "pretty-ms"; import { randRange, sampleArray } from "../../utils/utils"; + const cooldowns: Record = {}; -export const command = new Command("daily", "Get your daily income!.") - .setExecutor(async int => { - if (int.user.id in cooldowns && cooldowns[int.user.id] >= Date.now()) { - await int.reply( - format( - text.errors.cooldown, - pms(cooldowns[int.user.id] - Date.now(), { compact: true, secondsDecimalDigits: 1 }) - ) - ); - return; - } - const info = await upsertUserInfo(int.user, int.guild?.id || ''); - const obtained = randRange(...constants.daily.amountRange); - cooldowns[int.user.id] = Date.now() + constants.daily.cooldownMs; - await db.userInfo.update({ where: { id: info.id }, data: { balance: { increment: obtained } } }); - await int.reply(format(sampleArray(text.commands.daily.responses), `\`$${obtained}\``)); - }); \ No newline at end of file +export const command = new Command( + "daily", + "Get your daily income!." +).setExecutor(async (int) => { + if (int.user.id in cooldowns && cooldowns[int.user.id] >= Date.now()) { + await int.reply( + format( + text.errors.cooldown, + pms(cooldowns[int.user.id] - Date.now(), { + compact: true, + secondsDecimalDigits: 1, + }) + ) + ); + return; + } + const info = await upsertUserInfo(int.user); + const obtained = randRange(...constants.daily.amountRange); + cooldowns[int.user.id] = Date.now() + constants.daily.cooldownMs; + await db.userInfo.update({ + where: { id: info.id }, + data: { balance: { increment: obtained } }, + }); + await int.reply( + format(sampleArray(text.commands.daily.responses), `\`$${obtained}\``) + ); +}); diff --git a/src/commands/economy/drinkroullete.ts b/src/commands/economy/drinkroulette.ts similarity index 93% rename from src/commands/economy/drinkroullete.ts rename to src/commands/economy/drinkroulette.ts index 2e3d5a7..fab5b73 100644 --- a/src/commands/economy/drinkroullete.ts +++ b/src/commands/economy/drinkroulette.ts @@ -1,34 +1,35 @@ -import { db } from "../../database/database"; -import { generateOrderId, hasActiveOrder, } from "../../database/orders"; -import { text } from "../../providers/config"; -import { mainChannels, mainRoles } from "../../providers/discord"; -import { Command } from "../../structures/Command"; -import { format } from "../../utils/string"; -import { sampleArray } from "../../utils/utils"; - -export const command = new Command("drinkroullete", "Get a random drink ordered!") - .setExecutor(async int => { - if (await hasActiveOrder(int.user)) { - await int.reply(text.commands.order.exists); - return; - } - const drink = format(sampleArray(text.commands.drinkingr.drinks)); - const order = await db.orders.create({ - data: { - id: await generateOrderId(), - user: int.user.id, - details: drink, - channel: int.channelId, - guild: int.guildId, - }, - }); - await mainChannels.brewery.send( - format(text.commands.order.created, { - details: drink, - duty: mainRoles.duty.toString(), - id: order.id, - tag: int.user.username, - }) - ); - await int.reply(`You got ${order.details}! Please enjoy your free gain!`); - }); +/* eslint-disable linebreak-style */ +import { db } from "../../database/database"; +import { generateOrderId, hasActiveOrder, } from "../../database/orders"; +import { text } from "../../providers/config"; +import { mainChannels, mainRoles } from "../../providers/discord"; +import { Command } from "../../structures/Command"; +import { format } from "../../utils/string"; +import { sampleArray } from "../../utils/utils"; + +export const command = new Command("drinkroullete", "Get a random drink ordered!") + .setExecutor(async int => { + if (await hasActiveOrder(int.user)) { + await int.reply(text.commands.order.exists); + return; + } + const drink = format(sampleArray(text.commands.drinkingr.drinks), ""); //todo: check if this is correct pls + const order = await db.orders.create({ + data: { + id: await generateOrderId(), + user: int.user.id, + details: drink, + channel: int.channelId, + guild: int.guildId, + }, + }); + await mainChannels.brewery.send( + format(text.commands.order.created, { + details: drink, + duty: mainRoles.duty.toString(), + id: order.id, + tag: int.user.username, + }) + ); + await int.reply(`You got ${order.details}! Please enjoy your free gain!`); + }); diff --git a/src/commands/economy/give.ts b/src/commands/economy/give.ts index 85463ea..5ac1cd1 100644 --- a/src/commands/economy/give.ts +++ b/src/commands/economy/give.ts @@ -1,34 +1,48 @@ -/* eslint-disable indent */ +import { User } from "discord.js"; import { db } from "../../database/database"; -import { getUserInfo } from "../../database/userInfo"; +import { getUserInfo, updateBalance } from "../../database/userInfo"; import { text } from "../../providers/config"; import { Command } from "../../structures/Command"; export const command = new Command("give", "Give someone some money.") + .addUserOption(o => o.setName("receiver").setDescription("Select the user you want to give money to.").setRequired(true)) .addOption("integer", o => o.setName("money").setDescription("The amount to give.").setRequired(true)) - .addOption("string", o => o.setName("receiver").setDescription("Please use their id").setRequired(true)) .setExecutor(async int => { const user = int.user; + const receiver = int.options.getUser("receiver") as User; // Extract user directly from the option const tip = int.options.get("money", true).value as number; - const receiver = int.options.get("receiver", true).value as string; - const info = await getUserInfo(int.user); - if (!info || info.balance < tip) { + + const userInfo = await getUserInfo(int.user); + if (!userInfo || userInfo.balance < tip) { await int.reply(text.common.notEnoughBalance); return; } + if (tip > 5000) { await int.reply("Funny this safety thing stopping your transaction of 5000+"); return; } + await db.userInfo.update({ where: { id: int.user.id }, data: { balance: { decrement: tip } } }); - await db.userInfo.update({ - where: { id: receiver }, - data: { balance: { increment: tip } } - }); - await int.reply(`You successfully transferred ${tip} to <@${receiver}>`); - return; // Ensure the function returns Promise + const receiverUserInfo = await getUserInfo(receiver.id); + if (receiverUserInfo) { + await db.userInfo.update({ + where: { id: receiver.id }, + data: { + balance: { increment: tip }, + ...(receiverUserInfo.donuts !== undefined && { donuts: receiverUserInfo.donuts }) + } + }); + } else { + await db.userInfo.update({ + where: { id: receiver.id }, + data: { balance: { increment: tip } } + }); + } + + await int.reply(`You successfully transferred ${tip} to <@${receiver.id}>`); }); diff --git a/src/commands/economy/work.ts b/src/commands/economy/work.ts index 7361990..608e170 100644 --- a/src/commands/economy/work.ts +++ b/src/commands/economy/work.ts @@ -8,22 +8,35 @@ import { Command } from "../../structures/Command"; import { format } from "../../utils/string"; import pms from "pretty-ms"; import { randRange, sampleArray } from "../../utils/utils"; + const cooldowns: Record = {}; -export const command = new Command("work", "Gets you some money.") - .setExecutor(async int => { +export const command = new Command("work", "Gets you some money.").setExecutor( + async (int) => { if (int.user.id in cooldowns && cooldowns[int.user.id] >= Date.now()) { await int.reply( format( text.errors.cooldown, - pms(cooldowns[int.user.id] - Date.now(), { compact: true, secondsDecimalDigits: 1 }) + pms(cooldowns[int.user.id] - Date.now(), { + compact: true, + secondsDecimalDigits: 1, + }) ) ); return; } - const info = await upsertUserInfo(int.user, int.guild?.id || ''); + const info = await upsertUserInfo(int.user); const obtained = randRange(...constants.work.amountRange); cooldowns[int.user.id] = Date.now() + constants.work.cooldownMs; - await db.userInfo.update({ where: { id: info.id }, data: { balance: { increment: obtained } } }); - await int.reply(format(sampleArray(text.commands.work.responses), `\`$${obtained}\``)); - }); + await db.userInfo.update({ + where: { id: info.id }, + data: { balance: { increment: obtained } }, + }); + await int.reply( + format( + sampleArray(text.commands.work.responses), + `\`$${obtained}\`` + ) + ); + } +); diff --git a/src/commands/order.disabled b/src/commands/order.disabled new file mode 100644 index 0000000..154a090 --- /dev/null +++ b/src/commands/order.disabled @@ -0,0 +1,306 @@ + +import { OrderStatus } from "@prisma/client"; +import { CommandInteraction, StringSelectMenuBuilder, ComponentType, EmbedBuilder } from "discord.js"; +import { db } from "../../database/database"; +import { hasActiveOrder, generateOrderId } from "../../database/orders"; +import { getUserBalance, updateBalance } from "../../database/userInfo"; +import { client } from "../../providers/client"; +import { text } from "../../providers/config"; +import { mainChannels, mainRoles } from "../../providers/discord"; +import { Command } from "../../structures/Command"; +import { format } from "../../utils/string"; +// Cached menu items +let cachedMenuItems: any[] = []; + +// Fixed price for custom orders +const customOrderPrice = 6.00; + +export const command = new Command("order", "Orders a drink.") + .setExecutor(async (int: CommandInteraction) => { + // Check if the user already has an active order using the hasActiveOrder function + const userHasActiveOrder = await hasActiveOrder(int.user.id); + if (userHasActiveOrder) { + await int.reply({ content: text.commands.order.exists, ephemeral: true }); + return; + } + + // Check if the channel has the "Embed Links" permission enabled + if (!int.channel.permissionsFor(int.client.user).has("EmbedLinks")) { + await int.reply("This channel doesn't have Embed Links enabled. You can't place an order here."); + return; + } + + // Check if the user's DMs are open by attempting to send a test message + try { + // Attempt to send the test message directly to the user's DMs + //console.log("Sending test message to user's DMs..."); + await int.user.send("This is a test message."); + } catch (error) { + // Handle the error if sending the message fails due to closed DMs + //console.error("Error sending test message to user's DMs:", error); + await int.reply("Please check your Privacy settings on the server to receive the order confirmation."); + return; + } + + // Fetch menu items if not cached + if (!cachedMenuItems.length) { + cachedMenuItems = await getDropdownOptions(); + } + + // If there are no options available, inform the user and return + if (cachedMenuItems.length === 0) { + await int.reply("There are no options available to select."); + return; + } + + // Create a StringSelectMenuBuilder for the dropdown menu + const selectMenu = new StringSelectMenuBuilder() + .setCustomId("order_item") + .setPlaceholder("Select a drink"); + + // Add options to the dropdown menu + cachedMenuItems.forEach(option => { + selectMenu.addOptions(option); + }); + + // Add custom order option with fixed price + selectMenu.addOptions({ + label: `Custom Order ???? ${customOrderPrice.toFixed(2)}`, // Label with custom order and fixed price + value: "Custom Order", + description: "Create a custom order", + }); + + // Create an action row with the dropdown menu + const actionRow = { + type: ComponentType.ActionRow, + components: [selectMenu], + }; + + // Create an embed with instructions + const embed = new EmbedBuilder() + .setDescription("Please select a drink.") + .setColor("#00FF00"); + + // Reply to the interaction with the embed and dropdown menu + try { + await int.reply({ + embeds: [embed], + components: [actionRow], + ephemeral: true, + }); + } catch (error) { + console.error("Error replying to interaction:", error); + } + }); + +async function getDropdownOptions() { + try { + // Fetch menu items and their prices from the database + const menuItems = await db.menuItem.findMany(); + + // Map menu items to options for the dropdown menu + const options = menuItems.map(item => ({ + label: `???? ${item.name} ???? ${item.price.toFixed(2)}`, // Name of the menu item with price, all in bold + value: item.name, // Use the name of the menu item as the value + description: `Description: ???? ${item.description}`, // Description of the menu item + price: item.price, // Include the price in the option object + })); + return options; + } catch (error) { + console.error("Error fetching menu items:", error); + return []; // Return an empty array in case of error + } +} + +// Handle interaction for order selection +client.on("interactionCreate", async (interaction) => { + if (!interaction.isStringSelectMenu()) return; + + const componentId = interaction.customId; + if (componentId === "order_item") { + // Check if the user already has an active order using the hasActiveOrder function + const userHasActiveOrder = await hasActiveOrder(interaction.user.id); + if (userHasActiveOrder) { + await interaction.reply(text.commands.order.exists); + return; + } + + // Disable the dropdown menu to prevent further selections + const selectMenu = interaction.message.components?.find(component => component.type === ComponentType.ActionRow)?.components + .find(component => component.customId === "order_item"); + if (selectMenu && selectMenu instanceof StringSelectMenuBuilder) { + selectMenu.setDisabled(true); + } + + const drink = interaction.values[0]; // Assuming only one drink can be selected + + // If custom order is selected, handle it separately + if (drink === "Custom Order") { + await handleCustomOrder(interaction); + return; + } + + const orderId = await generateOrderId(); // Generate a unique order ID + + // Fetch the price of the selected menu item + let orderPrice; + if (drink === "Custom Order") { + orderPrice = customOrderPrice; + } else { + const menuItem = await db.menuItem.findFirst({ where: { name: drink } }); + if (!menuItem) { + await interaction.reply({ content: "Invalid menu item selected. Please try again.", ephemeral: true }); + return; + } + orderPrice = menuItem.price; + } + + // Check if the user has sufficient balance + const userId = interaction.user.id; + const userBalance = await getUserBalance(userId); + if (userBalance.balance < orderPrice) { + await interaction.reply({ content: "You don't have enough balance to place this order.", ephemeral: true }); + return; + } + + // Deduct the order price from the user's balance + const updatedBalance = userBalance.balance - orderPrice; + await updateBalance(userId, updatedBalance, 0); + // Send a message to the user informing them about the deducted balance + const message = await interaction.message.channel.send(`You have $${updatedBalance.toFixed(2)} left after placing your order.`); + setTimeout(() => { + message.delete().catch(console.error); // Delete the message after a certain timeout + }, 5000); // Delete the message after 5 seconds + + // Create the order + const order = await db.orders.create({ + data: { + id: orderId, + user: userId, + details: drink, + channel: interaction.channelId, + guild: interaction.guildId, + status: OrderStatus.Unprepared, // Initial status set to PendingDelivery + }, + }); + + try { + // Attempt to send the "Order has been placed successfully" message directly to the user + console.log("Sending order confirmation to user..."); + const embed = new EmbedBuilder() + .setTitle("Order Placement") + .setColor("Random") + .addFields( + { name: "Order Details", value: `Your order with ID ${order.id} | ${drink}\nStatus: Has been placed successfully` } + ); + await interaction.user.send({ embeds: [embed] }); + } catch (error) { + // Handle the error if sending the message fails due to closed DMs + await interaction.reply("Please check your Privacy settings on the server to receive the order confirmation."); + return; + } + + + await interaction.reply(format(text.commands.order.success, { id: order.id, details: drink })); + + if (interaction.member?.nickname?.toLowerCase() === "bart") { + await interaction.followUp("I will end you"); + } + + await mainChannels.brewery.send( + format(text.commands.order.created, { + details: drink, + duty: mainRoles.duty.toString(), + id: order.id, + tag: interaction.user.username, + }) + ); + + } +}); + +// Function to handle custom order +async function handleCustomOrder(interaction) { + // Prompt the user to provide details for the custom order + console.log("Prompting user for custom order details..."); + await interaction.reply("Please type what you would like to order."); + + // Collect user's message for custom order + const filter = (message) => message.author.id === interaction.user.id; + const collector = interaction.channel.createMessageCollector({ filter, time: 60000 }); // Adjust time as needed + + collector.on("collect", async (message) => { + const customOrderDetails = message.content.trim(); + console.log("Message content:", customOrderDetails); // Log custom order details + + + const orderId = await generateOrderId(); // Generate a unique order ID + const userId = interaction.user.id; // Get user ID + + try { + // Proceed with custom order processing + console.log("Processing custom order..."); + const orderPrice = customOrderPrice; // Fixed price for custom orders + const userBalance = await getUserBalance(userId); + if (userBalance.balance < orderPrice) { + await interaction.reply({ content: "You don't have enough balance to place this order.", ephemeral: true }); + return; + } + + // Deduct the order price from the user's balance + const updatedBalance = userBalance.balance - orderPrice; + await updateBalance(userId, updatedBalance, 0); + + // Send a message to the user informing them about the deducted balance + const message = await interaction.channel.send(`You have $${updatedBalance.toFixed(2)} left after placing your order.`); + setTimeout(() => { + message.delete().catch(console.error); // Delete the message after a certain timeout + }, 5000); // Delete the message after 5 seconds + + const order = await db.orders.create({ + data: { + id: orderId, + user: userId, + details: customOrderDetails, + channel: interaction.channelId, + guild: interaction.guildId, + status: OrderStatus.Unprepared, + }, + }); + + // Attempt to send the "Order has been placed successfully" message directly to the user + //console.log("Sending order confirmation to user..."); + const embed = new EmbedBuilder() + .setTitle("Order Placement") + .setColor("Random") + .addFields( + { name: "Order Details", value: `Your order with ID ${order.id} | ${customOrderDetails}\nStatus: Has been placed successfully` } + ); + await interaction.user.send({ embeds: [embed] }); + + // Send order confirmation to brewery channel + //console.log("Sending order confirmation to brewery channel..."); + await mainChannels.brewery.send( + format(text.commands.order.created, { + details: customOrderDetails, + duty: mainRoles.duty.toString(), + id: order.id, + tag: interaction.user.username, + }) + ); + + // Stop collecting messages + collector.stop(); + } catch (error) { + await interaction.reply("An error occurred while processing your order. Please try again later."); + } + }); + + // Handle collector end event + collector.on("end", (collected, reason) => { + if (reason === "time") { + interaction.channel.send("You took too long to provide the custom order details. Order cancelled."); + } + }); +} + diff --git a/src/commands/orders/order.ts b/src/commands/orders/order.ts index 1e6ffaa..b8da876 100644 --- a/src/commands/orders/order.ts +++ b/src/commands/orders/order.ts @@ -1,194 +1,62 @@ -/* eslint-disable indent */ import { db } from "../../database/database"; -import { generateOrderId, OrderStatus } from "../../database/orders"; +import { generateOrderId, hasActiveOrder } from "../../database/orders"; import { text } from "../../providers/config"; import { mainChannels, mainRoles } from "../../providers/discord"; import { Command } from "../../structures/Command"; import { format } from "../../utils/string"; -import { CommandInteraction, ComponentType, EmbedBuilder, StringSelectMenuBuilder } from "discord.js"; -import { getUserInfo, updateBalance } from "../../database/userInfo"; -import { client } from "../../providers/client"; - -// Map to store active orders by user ID -const activeOrders = new Map(); - -// Cached menu items -let cachedMenuItems: any[] = []; export const command = new Command("order", "Orders a drink.") - .setExecutor(async (int: CommandInteraction) => { - // Check if the user already has an active order - if (activeOrders.has(int.user.id)) { - await int.reply(text.commands.order.exists); - return; - } - - // Check if the channel has the "Embed Links" permission enabled - if (!int.channel.permissionsFor(int.client.user).has("EmbedLinks")) { - await int.reply("This channel doesn't have Embed Links enabled. You can't place an order here."); - return; - } - - // Fetch menu items if not cached - if (!cachedMenuItems.length) { - cachedMenuItems = await getDropdownOptions(); - } - - // If there are no options available, inform the user and return - if (cachedMenuItems.length === 0) { - await int.reply("There are no options available to select."); - return; - } - - // Create a StringSelectMenuBuilder for the dropdown menu - const selectMenu = new StringSelectMenuBuilder() - .setCustomId("order_item") - .setPlaceholder("Select a drink"); - - // Add options to the dropdown menu - cachedMenuItems.forEach(option => { - selectMenu.addOptions(option); - }); - - // Create an action row with the dropdown menu - const actionRow = { - type: ComponentType.ActionRow, - components: [selectMenu], - }; - - // Create an embed with instructions - const embed = new EmbedBuilder() - .setDescription("Please select a drink.") - .setColor("#00FF00"); - - // Reply to the interaction with the embed and dropdown menu - try { - await int.reply({ - embeds: [embed], - components: [actionRow], - ephemeral: true, - }); - } catch (error) { - console.error("Error replying to interaction:", error); - } - }); - -// Function to fetch options for the dropdown menu including menu items and their prices -async function getDropdownOptions() { - try { - // Fetch menu items and their prices from the database - const menuItems = await db.menuItem.findMany(); - - // Map menu items to options for the dropdown menu - const options = menuItems.map(item => ({ - label: `📔 ${item.name} 💲 ${item.price.toFixed(2)}`, // Name of the menu item with price, all in bold - value: item.name, // Use the name of the menu item as the value - description: `Description: 📝 ${item.description}`, // Description of the menu item - price: item.price, // Include the price in the option object - })); - return options; - } catch (error) { - console.error("Error fetching menu items:", error); - return []; // Return an empty array in case of error - } -} - -// Handle interaction for order selection -client.on("interactionCreate", async (interaction) => { - if (!interaction.isStringSelectMenu()) return; - - const componentId = interaction.customId; - if (componentId === "order_item") { - // Check if the user already has an active order - const userId = interaction.user.id; - if (activeOrders.has(userId)) { - await interaction.reply(text.commands.order.exists); - return; - } - - // Disable the dropdown menu to prevent further selections - const selectMenu = interaction.message.components?.find(component => component.type === ComponentType.ActionRow)?.components - .find(component => component.customId === "order_item"); - if (selectMenu && selectMenu instanceof StringSelectMenuBuilder) { - selectMenu.setDisabled(true); - } - - const selectedItem = cachedMenuItems.find(item => item.value === interaction.values[0]); - if (!selectedItem) { - console.error("Selected menu item not found."); - return; - } - - const drink = selectedItem.value; // Assuming only one drink can be selected - const orderId = await generateOrderId(); // Generate a unique order ID - - // Fetch user's balance - const userInfo = await getUserInfo(userId); - - // Check if the user has enough balance - if (userInfo.balance < selectedItem.price) { - await interaction.reply("You don't have enough balance to order this item."); - return; - } - - // Deduct the cost of the ordered item from the user's balance - const newBalance = userInfo.balance - selectedItem.price; - - // Update user's balance in the database - await updateBalance(userId, newBalance, 0); // Provide a default value for newDonuts - // Updated to match the new function signature - // Create the order - const order = await db.orders.create({ - data: { - id: orderId, - user: userId, - details: drink, - channel: interaction.channelId, - guild: interaction.guildId, - status: OrderStatus.Unprepared, // Initial status set to PendingDelivery - }, - }); - - try { - // Attempt to send the "Order has been placed successfully" message directly to the user - const embed = new EmbedBuilder() - .setTitle("Order Placement") - .setColor("Random") //default 0099ff - .addFields( - { name: "Order Details", value: `Your order with ID ${order.id} | ${drink}\nStatus: Has been placed successfully` } - ); - await interaction.user.send({ embeds: [embed] }); - } catch (error) { - // Handle the error if sending the message fails due to closed DMs - await interaction.reply("Your DMs are closed. Please enable them to receive the order confirmation."); - return; - } - - const updatedUserInfo = await getUserInfo(userId); - await interaction.reply(`You have purchased ${drink} and your balance is now ${updatedUserInfo.balance}.`); - - if (interaction.member?.nickname?.toLowerCase() === "bart") { - await interaction.followUp("I will end you"); - } - - await mainChannels.brewery.send( - format(text.commands.order.created, { - details: drink, - duty: mainRoles.duty.toString(), - id: order.id, - tag: interaction.user.username, - }) - ); - - // Mark the user as having an active order - activeOrders.set(userId, true - ); - - // Remove the user from activeOrders after 30 seconds if their order is not cancelled or deleted - setTimeout(() => { - if (activeOrders.has(userId)) { - activeOrders.delete(userId); - } - }, 30000); // 30 seconds timeout for non-cancelled or non-deleted orders - } -}); + .addOption("string", (o) => + o.setName("drink").setDescription("The drink to order.").setRequired(true) + ) + .setExecutor(async (int) => { + if (await hasActiveOrder(int.user)) { + await int.reply(text.commands.order.exists); + return; + } + + // Check the number of existing orders + /* + const orderCount = await db.cafeOrders.count(); + const maxOrderLimit = 25; + + if (orderCount >= maxOrderLimit) { + await int.reply(`The maximum order limit of ${maxOrderLimit} has been reached. Try again later.`); + return; + } + */ + + const drink = int.options.getString("drink", true); + + // Check the length of the drink description + const maxDescriptionLength = 100; // Adjust this value as needed + if (drink.length > maxDescriptionLength) { + await int.reply(`Your order details are too long. Please limit them to ${maxDescriptionLength} characters.`); + return; + } + + const order = await db.orders.create({ + data: { + id: await generateOrderId(), + user: int.user.id, + details: drink, + channel: int.channelId, + guild: int.guildId, + }, + }); + + await int.reply(format(text.commands.order.success, { id: order.id, details: drink })); + + if (int.member.nickname?.toLowerCase() === "bart") { + await int.followUp("I will end you"); + } + + await mainChannels.brewery.send( + format(text.commands.order.created, { + details: drink, + duty: mainRoles.duty.toString(), + id: order.id, + tag: int.user.tag, + }) + ); + }); diff --git a/src/commands/orders/worker/brew.ts b/src/commands/orders/worker/brew.ts index ed6f6b6..b01702d 100644 --- a/src/commands/orders/worker/brew.ts +++ b/src/commands/orders/worker/brew.ts @@ -1,239 +1,237 @@ /* eslint-disable indent */ /* eslint-disable quotes */ -import { OrderStatus } from "@prisma/client"; -import { db } from "../../../database/database"; -import { generateOrderId, getClaimedOrder, hasActiveOrder, matchActiveOrder } from "../../../database/orders"; -import { upsertWorkerInfo } from "../../../database/workerInfo"; -import { client } from "../../../providers/client"; -import { config, constants, text } from "../../../providers/config"; -import { mainGuild } from "../../../providers/discord"; -import { permissions } from "../../../providers/permissions"; -import { Command } from "../../../structures/Command"; -import { format } from "../../../utils/string"; -import { randRange } from "../../../utils/utils"; -import { StringSelectMenuBuilder, CommandInteraction, ComponentType, EmbedBuilder } from "discord.js"; -import { upsertWorkerStats, handleBrew, handleDeliver } from "../../../database/workerstats"; // Import the workerstats functions -import { ExtendedCommand } from "../../../structures/extendedCommand"; +import {OrderStatus} from "@prisma/client"; +import {db} from "../../../database/database"; +import {getClaimedOrder} from "../../../database/orders"; +import {upsertWorkerInfo} from "../../../database/workerInfo"; +import {constants} from "../../../providers/config"; +import {permissions} from "../../../providers/permissions"; +import {randRange} from "../../../utils/utils"; +import {CollectedMessageInteraction, ComponentType, EmbedBuilder, StringSelectMenuBuilder} from "discord.js"; +import {upsertWorkerStats} from "../../../database/workerstats"; // Import the workerstats functions +import {ExtendedCommand} from "../../../structures/extendedCommand"; +import {IllegalStateError} from "../../../utils/error"; export const command = new ExtendedCommand( - { name: "brew", description: "Brews your claimed order.", local: true } - + {name: "brew", description: "Brews your claimed order.", local: true} ) - .addSubCommand((subcommand) => - subcommand - .setName("attach") - .setDescription("Attach an image to your order.") - .addAttachmentOption((option) => - option - .setName("attachment") - .setDescription("The image to attach to the order.") - .setRequired(true) - ) - ) - .addSubCommand((subcommand) => - subcommand - .setName("url") - .setDescription("Attach an image to your order by URL.") - .addStringOption((option) => - option - .setName("url") - .setDescription("The URL of the image to attach to the order.") - .setRequired(true) - ) - ) - .addPermission(permissions.employee) - .setExecutor(async (int: CommandInteraction) => { - const order = await getClaimedOrder(int.user); - if (!order) { - await int.reply({ content: "You don't have a claimed order." }); - return; - } - - // Set last command to "brew" when brewing - await upsertWorkerStats(int.user, { lastCommand: "brew" }); - - const subcommand = int.options.getSubcommand(true); - let imageUrl: string | undefined; - - if (subcommand === "attach") { - const attachment = int.options.get("attachment", true)?.attachment; - if (!attachment) { - await int.reply({ content: "Attachment is missing or not valid." }); - return; - } - imageUrl = attachment.url; - - // Create an embed with the image preview - const imagePreviewEmbed = new EmbedBuilder() - .setTitle("Image Preview") - .setImage(imageUrl) // Set the image URL as the preview - .toJSON(); - - const confirmationDescription = `Order Details: ${order.details}`; - - const confirmSelectMenu = new StringSelectMenuBuilder() - .setCustomId("confirm_brew") - .setPlaceholder("Select an option") - .addOptions([ - { - label: "Yes", - description: "Proceed with brewing the order", - value: "yes", - }, - { - label: "No", - description: "Cancel the brewing process", - value: "no", - }, - ]) - .toJSON(); - - const confirmActionRow = { - type: ComponentType.ActionRow, - components: [confirmSelectMenu], - }; - - await int.reply({ - content: `Do you want to proceed with brewing this order?\n${confirmationDescription}`, - embeds: [imagePreviewEmbed], // Include the image preview in the message - components: [confirmActionRow], - ephemeral: true, - }); - - const confirmFilter = (i) => i.customId === "confirm_brew" && i.user.id === int.user.id; - const confirmCollector = int.channel.createMessageComponentCollector({ filter: confirmFilter, time: 15000 }); - - confirmCollector.on("collect", async (confirmInteraction) => { - if (confirmInteraction.isStringSelectMenu()) { - const selectedValue = confirmInteraction.values[0]; - if (selectedValue === "yes") { - await confirmInteraction.update({ - content: "You chose to proceed with brewing the order.", - components: [], - }); - - const time = randRange(...constants.brewTimeRangeMs); - await db.orders.update({ - where: { - id: order.id, - }, - data: { - status: OrderStatus.Brewing, - image: imageUrl ?? "default.png", - timeout: new Date(Date.now() + time), - }, - }); - - // Update worker stats when brewing an order - await handleBrew(int.user); - await upsertWorkerInfo(int.user); - - await int.followUp({ - content: "Brewing process started.", - files: imageUrl ? [{ attachment: imageUrl }] : undefined, - }); - } else if (selectedValue === "no") { - await confirmInteraction.update({ - content: "You chose to cancel the brewing process.", - components: [], - }); - } - } - }); - - confirmCollector.on("end", async (collected) => { - if (collected.size === 0) { - await int.followUp("You didn't make a selection in time."); - } - }); - - } else if (subcommand === "url") { - const url = int.options.getString("url", true); - imageUrl = url; - - // Create an embed with the image preview - const imagePreviewEmbed = new EmbedBuilder() - .setTitle("Image Preview") - .setImage(imageUrl) // Set the image URL as the preview - .toJSON(); - - const confirmationDescription = `Order Details: ${order.details}`; - - const confirmSelectMenu = new StringSelectMenuBuilder() - .setCustomId("confirm_brew_url") - .setPlaceholder("Select an option") - .addOptions([ - { - label: "Yes", - description: "Proceed with brewing the order", - value: "yes", - }, - { - label: "No", - description: "Cancel the brewing process", - value: "no", - }, - ]) - .toJSON(); - - const confirmActionRow = { - type: ComponentType.ActionRow, - components: [confirmSelectMenu], - }; - - await int.reply({ - content: `Do you want to proceed with brewing this order?\n${confirmationDescription}`, - embeds: [imagePreviewEmbed], // Include the image preview in the message - components: [confirmActionRow], - ephemeral: true, - }); - - const confirmFilter = (i) => i.customId === "confirm_brew_url" && i.user.id === int.user.id; - const confirmCollector = int.channel.createMessageComponentCollector({ filter: confirmFilter, time: 15000 }); - - confirmCollector.on("collect", async (confirmInteraction) => { - if (confirmInteraction.isStringSelectMenu()) { - const selectedValue = confirmInteraction.values[0]; - if (selectedValue === "yes") { - await confirmInteraction.update({ - content: "You chose to proceed with brewing the order.", - components: [], - }); - - const time = randRange(...constants.brewTimeRangeMs); - await db.orders.update({ - where: { - id: order.id, - }, - data: { - status: OrderStatus.Brewing, - image: imageUrl ?? "default.png", - timeout: new Date(Date.now() + time), - }, - }); - - // Update worker stats when brewing an order - await handleBrew(int.user); - await upsertWorkerStats(int.user, { ordersBrewed: 1 }); // Increment the ordersBrewed count - await upsertWorkerInfo(int.user); - - await int.followUp({ - content: "Brewing process started.", - files: imageUrl ? [{ attachment: imageUrl }] : undefined, - }); - } else if (selectedValue === "no") { - await confirmInteraction.update({ - content: "You chose to cancel the brewing process.", - components: [], - }); - } - } - }); - - confirmCollector.on("end", async (collected) => { - if (collected.size === 0) { - await int.followUp("You didn't make a selection in time."); - } - }); - } - }); \ No newline at end of file + .addSubCommand((subcommand) => + subcommand + .setName("attach") + .setDescription("Attach an image to your order.") + .addAttachmentOption((option) => + option + .setName("attachment") + .setDescription("The image to attach to the order.") + .setRequired(true) + ) + ) + .addSubCommand((subcommand) => + subcommand + .setName("url") + .setDescription("Attach an image to your order by URL.") + .addStringOption((option) => + option + .setName("url") + .setDescription("The URL of the image to attach to the order.") + .setRequired(true) + ) + ) + .addPermission(permissions.employee) + .setExecutor(async (int) => { + const order = await getClaimedOrder(int.user); + if (!order) { + await int.reply({content: "You don't have a claimed order."}); + return; + } + + // Set last command to "brew" when brewing + await upsertWorkerStats(int.user, {ordersBrewed: 1, lastCommand: "brew"}); + + const subcommand = int.options.getSubcommand(true); + let imageUrl: string | undefined; + + if (subcommand === "attach") { + const attachment = int.options.get("attachment", true)?.attachment; + if (!attachment) { + await int.reply({content: "Attachment is missing or not valid."}); + return; + } + imageUrl = attachment.url; + + // Create an embed with the image preview + const imagePreviewEmbed = new EmbedBuilder() + .setTitle("Image Preview") + .setImage(imageUrl) // Set the image URL as the preview + .toJSON(); + + const confirmationDescription = `Order Details: ${order.details}`; + + const confirmSelectMenu = new StringSelectMenuBuilder() + .setCustomId("confirm_brew") + .setPlaceholder("Select an option") + .addOptions([ + { + label: "Yes", + description: "Proceed with brewing the order", + value: "yes", + }, + { + label: "No", + description: "Cancel the brewing process", + value: "no", + }, + ]); + + const confirmActionRow = { + type: ComponentType.ActionRow, + components: [confirmSelectMenu], + }; + + await int.reply({ + content: `Do you want to proceed with brewing this order?\n${confirmationDescription}`, + embeds: [imagePreviewEmbed], // Include the image preview in the message + components: [confirmActionRow], + ephemeral: true, + }); + + if (!int.channel) throw new IllegalStateError("Channel is not available."); + + const confirmFilter = (i: CollectedMessageInteraction) => i.customId === "confirm_brew" && i.user.id === int.user.id; + const confirmCollector = int.channel.createMessageComponentCollector({filter: confirmFilter, time: 15000}); + + confirmCollector.on("collect", async (confirmInteraction) => { + if (confirmInteraction.isStringSelectMenu()) { + const selectedValue = confirmInteraction.values[0]; + if (selectedValue === "yes") { + await confirmInteraction.update({ + content: "You chose to proceed with brewing the order.", + components: [], + }); + + const time = randRange(...constants.brewTimeRangeMs); + await db.orders.update({ + where: { + id: order.id, + }, + data: { + status: OrderStatus.Brewing, + image: imageUrl ?? "default.png", + timeout: new Date(Date.now() + time), + }, + }); + await int.followUp({ + content: "Brewing process started.", + files: imageUrl ? [{attachment: imageUrl}] : undefined, + }); + } else if (selectedValue === "no") { + await confirmInteraction.update({ + content: "You chose to cancel the brewing process.", + components: [], + }); + } + } + }); + + confirmCollector.on("end", async (collected) => { + if (collected.size === 0) { + await int.followUp("You didn't make a selection in time."); + } + }); + + } else if (subcommand === "url") { + const url = int.options.getString("url", true); + imageUrl = url; + + // Create an embed with the image preview + const imagePreviewEmbed = new EmbedBuilder() + .setTitle("Image Preview") + .setImage(imageUrl) // Set the image URL as the preview + .toJSON(); + + const confirmationDescription = `Order Details: ${order.details}`; + + const confirmSelectMenu = new StringSelectMenuBuilder() + .setCustomId("confirm_brew_url") + .setPlaceholder("Select an option") + .addOptions([ + { + label: "Yes", + description: "Proceed with brewing the order", + value: "yes", + }, + { + label: "No", + description: "Cancel the brewing process", + value: "no", + }, + ]); + + const confirmActionRow = { + type: ComponentType.ActionRow, + components: [confirmSelectMenu], + }; + + await int.reply({ + content: `Do you want to proceed with brewing this order?\n${confirmationDescription}`, + embeds: [imagePreviewEmbed], // Include the image preview in the message + components: [confirmActionRow], + ephemeral: true, + }); + + if (!int.channel) throw new IllegalStateError("Channel is not available."); + + const confirmFilter = (i: CollectedMessageInteraction) => i.customId === "confirm_brew_url" && i.user.id === int.user.id; + const confirmCollector = int.channel.createMessageComponentCollector({filter: confirmFilter, time: 15000}); + + confirmCollector.on("collect", async (confirmInteraction) => { + if (confirmInteraction.isStringSelectMenu()) { + const selectedValue = confirmInteraction.values[0]; + if (selectedValue === "yes") { + await confirmInteraction.update({ + content: "You chose to proceed with brewing the order.", + components: [], + }); + + const time = randRange(...constants.brewTimeRangeMs); + await db.orders.update({ + where: { + id: order.id, + }, + data: { + status: OrderStatus.Brewing, + image: imageUrl ?? "default.png", + timeout: new Date(Date.now() + time), + }, + }); + + // Update worker info + await upsertWorkerInfo(int.user); + await db.workerInfo.update({ + where: { + id: int.user.id, + }, + data: { + preparations: {increment: 1}, + }, + }); + await int.followUp({ + content: "Brewing process started.", + files: imageUrl ? [{attachment: imageUrl}] : undefined, + }); + } else if (selectedValue === "no") { + await confirmInteraction.update({ + content: "You chose to cancel the brewing process.", + components: [], + }); + } + } + }); + + confirmCollector.on("end", async (collected) => { + if (collected.size === 0) { + await int.followUp("You didn't make a selection in time."); + } + }); + } + }); diff --git a/src/commands/orders/worker/claim.ts b/src/commands/orders/worker/claim.ts index a206a02..d9d6552 100644 --- a/src/commands/orders/worker/claim.ts +++ b/src/commands/orders/worker/claim.ts @@ -8,8 +8,7 @@ import { client } from "../../../providers/client"; import { CommandInteraction, StringSelectMenuBuilder, ComponentType, EmbedBuilder } from "discord.js"; import { ExtendedCommand } from "../../../structures/extendedCommand"; -const claimedOrderLocks = new Map(); -const claimedOrders = new Set(); +const claimedOrders = new Map(); // Map to store claimed orders with user IDs export const command = new ExtendedCommand( { name: "claim", description: "Claims an order.", local: true } @@ -87,13 +86,6 @@ client.on("interactionCreate", async (interaction) => { return; } - if (claimedOrderLocks.has(orderId) && claimedOrderLocks.get(orderId)) { - await interaction.reply({ content: "Another user is currently claiming this order. Please try again later.", ephemeral: true }); - return; - } - - claimedOrderLocks.set(orderId, true); - const order = await db.orders.findUnique({ where: { id: orderId, @@ -106,32 +98,46 @@ client.on("interactionCreate", async (interaction) => { }); if (!order) { - claimedOrderLocks.delete(orderId); await interaction.reply({ content: "Invalid order selected.", ephemeral: true }); return; } if (order.user === interaction.user.id && !permissions.developer.hasPermission(interaction.user)) { - claimedOrderLocks.delete(orderId); await interaction.reply({ content: text.common.interactOwn, ephemeral: true }); return; } + // Check if another user is claiming the order at the same time + if (claimedOrders.has(orderId)) { + const existingClaimerId = claimedOrders.get(orderId); + if (existingClaimerId) { + // Auto-select one of the users to successfully claim the order + const selectedClaimerId = Math.random() < 0.5 ? existingClaimerId : interaction.user.id; + // Update the claimedOrders map with the selected user ID + claimedOrders.set(orderId, selectedClaimerId); + // Update the order in the database with the selected user ID + await db.orders.update({ + where: { id: orderId }, + data: { claimer: selectedClaimerId, status: OrderStatus.Preparing }, + }); + // Inform the users about the result + await interaction.reply({ + content: `${text.commands.claim.success.replace("{id}", order.id)}`, + ephemeral: false, + }); + return; + } + } + + // If no other user is claiming the order at the same time, proceed as usual + claimedOrders.set(orderId, interaction.user.id); await db.orders.update({ where: { id: orderId }, data: { claimer: interaction.user.id, status: OrderStatus.Preparing }, }); - - claimedOrders.add(orderId); - claimedOrderLocks.delete(orderId); - - try { - await interaction.reply({ - content: `${text.commands.claim.success.replace("{id}", order.id)}`, - ephemeral: false, - }); - } catch (error) { - console.error("Error replying to interaction:", error); - } + await interaction.reply({ + content: `${text.commands.claim.success.replace("{id}", order.id)}`, + ephemeral: false, + }); } }); diff --git a/src/commands/orders/worker/ebrew.ts b/src/commands/orders/worker/ebrew.ts deleted file mode 100644 index 36f07c8..0000000 --- a/src/commands/orders/worker/ebrew.ts +++ /dev/null @@ -1,261 +0,0 @@ -/* eslint-disable indent */ -/* eslint-disable quotes */ -import { OrderStatus } from "@prisma/client"; -import { db } from "../../../database/database"; -import { upsertWorkerInfo } from "../../../database/workerInfo"; -import { client } from "../../../providers/client"; -import { config, constants, text } from "../../../providers/config"; -import { permissions } from "../../../providers/permissions"; -import { Command } from "../../../structures/Command"; -import { format } from "../../../utils/string"; -import { randRange } from "../../../utils/utils"; -import { StringSelectMenuBuilder, CommandInteraction, ComponentType, EmbedBuilder } from "discord.js"; - -// Define the getClaimedOrders function without specifying OrderStatus -async function getClaimedOrders(userId: string) { - return await db.orders.findMany({ - where: { - claimer: userId, - status: OrderStatus.Preparing, - }, - }); -} - -export const command = new Command( - "ebrew", - "Brews your claimed order." -) - .addSubCommand((subcommand) => - subcommand - .setName("attach") - .setDescription("Attach an image to your order.") - .addAttachmentOption((option) => - option - .setName("attachment") - .setDescription("The image to attach to the order.") - .setRequired(true) - ) - ) - .addSubCommand((subcommand) => - subcommand - .setName("url") - .setDescription("Attach an image to your order by URL.") - .addStringOption((option) => - option - .setName("url") - .setDescription("The URL of the image to attach to the order.") - .setRequired(true) - ) - ) - .addSubCommand((subcommand) => - subcommand - .setName("claim") - .setDescription("Claim an order.") - ) - .addPermission(permissions.employee) - .setExecutor(async (int: CommandInteraction) => { - // Check the subcommand - const subcommand = int.options.getSubcommand(true); - - if (subcommand === "claim") { - // Get a list of claimed orders for the user using getClaimedOrders - const claimedOrders = await getClaimedOrders(int.user.id); - - // Check if the user has claimed orders - if (claimedOrders.length === 0) { - await int.reply({ content: "You don't have any claimed orders to brew." }); - return; - } - - // Build a select menu with claimed order options - const orderOptions = claimedOrders.map(order => ({ - label: `Order ${order.id}`, - value: order.id.toString(), - description: `User: ${order.user.substring(0, 15)}...\nDetails: ${order.details.substring(0, 50)}...`, - // Include user and details in the description, limiting the length - })); - - const orderSelectMenu = new StringSelectMenuBuilder() - .setCustomId("select_order_to_claim") - .setPlaceholder("Select an order to brew") - .addOptions(orderOptions) - .toJSON(); - - const actionRow = { - type: ComponentType.ActionRow, - components: [orderSelectMenu], - }; - - await int.reply({ - content: "Please select an order to brew:", - components: [actionRow], - ephemeral: true, - }); - - // Create a collector to listen for the user's selection - const filter = (i) => i.customId === "select_order_to_claim" && i.user.id === int.user.id; - const collector = int.channel.createMessageComponentCollector({ filter, time: 15000 }); - - collector.on("collect", async (interaction) => { - const selectedOrderId = interaction.values[0]; - - // Fetch the order details using the order ID - const selectedOrder = await db.orders.findUnique({ - where: { - id: selectedOrderId, - }, - }); - - if (!selectedOrder) { - await interaction.update({ content: "Invalid order selected.", components: [] }); - return; - } - - // Check if the order status is not OrderStatus.Preparing - if (selectedOrder.status !== OrderStatus.Preparing) { - await interaction.update({ - content: `You cannot claim an order with status ${selectedOrder.status}.`, - components: [], - }); - return; - } - - // Store the selected order ID in a context variable for future use - int.client.ordersInProcess = { - [int.user.id]: { - orderId: selectedOrderId, - }, - }; - - await interaction.update({ - content: `You selected Order ${selectedOrderId} to brew. Now, you can proceed to attach an image or provide a URL.`, - components: [], - }); - }); - - collector.on("end", async (collected) => { - if (collected.size === 0) { - await int.followUp("You didn't select an order in time."); - } - }); - - } else if ((subcommand === "attach" || subcommand === "url") && int.client.ordersInProcess?.[int.user.id]?.orderId) { - // Fetch the order ID from the context variable - const selectedOrderId = int.client.ordersInProcess[int.user.id].orderId; - - // Fetch the order details using the order ID - const order = await db.orders.findUnique({ - where: { - id: selectedOrderId, - }, - }); - - if (!order) { - await int.reply({ content: "Invalid order selected." }); - return; - } - - // Check if the order status is OrderStatus.PendingDelivery or OrderStatus.Brewing - if (order.status === OrderStatus.PendingDelivery || order.status === OrderStatus.Brewing) { - await int.reply({ content: "You have Already Brewed this order. select an new one!" }); - return; - } - - let imageUrl: string | undefined; - - if (subcommand === "attach") { - const attachment = int.options.get("attachment", true)?.attachment; - if (!attachment) { - await int.reply({ content: "Attachment is missing or not valid." }); - return; - } - imageUrl = attachment.url; - } else if (subcommand === "url") { - const url = int.options.getString("url", true); - imageUrl = url; - } - - // Include order description in the confirmation message - const confirmationDescription = `Order Details: ${order.details}`; - - const imagePreviewEmbed = new EmbedBuilder() - .setTitle("Image Preview") - .setImage(imageUrl) // Set the image URL as the preview - .toJSON(); - - const confirmSelectMenu = new StringSelectMenuBuilder() - .setCustomId("confirm_brew") - .setPlaceholder("Select an option") - .addOptions([ - { - label: "Yes", - description: "Proceed with brewing the order", - value: "yes", - }, - { - label: "No", - description: "Cancel the brewing process", - value: "no", - }, - ]) - .toJSON(); - - const confirmActionRow = { - type: ComponentType.ActionRow, - components: [confirmSelectMenu], - }; - - await int.reply({ - content: `Do you want to proceed with brewing this order?\n${confirmationDescription}`, - embeds: [imagePreviewEmbed], // Include the image preview in the message - components: [confirmActionRow], - ephemeral: true, - }); - - const confirmFilter = (i) => i.customId === "confirm_brew" && i.user.id === int.user.id; - const confirmCollector = int.channel.createMessageComponentCollector({ filter: confirmFilter, time: 15000 }); - - confirmCollector.on("collect", async (confirmInteraction) => { - if (confirmInteraction.isStringSelectMenu()) { - const selectedValue = confirmInteraction.values[0]; - if (selectedValue === "yes") { - await confirmInteraction.update({ - content: "You chose to proceed with brewing the order.", - components: [], - }); - - const time = randRange(...constants.brewTimeRangeMs); - await db.orders.update({ - where: { - id: order.id, - }, - data: { - status: OrderStatus.Brewing, - image: imageUrl ?? "default.png", - timeout: new Date(Date.now() + time), - }, - }); - await upsertWorkerInfo(int.user); - - await int.followUp({ - content: "Brewing process started.", - files: imageUrl ? [{ attachment: imageUrl }] : undefined, - }); - } else if (selectedValue === "no") { - await confirmInteraction.update({ - content: "You chose to cancel the brewing process.", - components: [], - }); - } - } - }); - - confirmCollector.on("end", async (collected) => { - if (collected.size === 0) { - await int.followUp("You didn't make a selection in time."); - } - }); - } else { - await int.reply({ content: "You need to claim an order first before attaching an image or providing a URL." }); - } - }); diff --git a/src/commands/orders/worker/editstatus.ts b/src/commands/orders/worker/editstatus.ts index e58540a..3b39a81 100644 --- a/src/commands/orders/worker/editstatus.ts +++ b/src/commands/orders/worker/editstatus.ts @@ -1,11 +1,8 @@ /* eslint-disable indent */ -import { OrderStatus, matchActiveOrder } from "../../../database/orders"; -import { text } from "../../../providers/config"; -import { permissions } from "../../../providers/permissions"; -import { Command } from "../../../structures/Command"; -import { CommandInteraction } from "discord.js"; -import { db } from "../../../database/database"; -import { ExtendedCommand } from "../../../structures/extendedCommand"; +import {matchActiveOrder, OrderStatus} from "../../../database/orders"; +import {permissions} from "../../../providers/permissions"; +import {db} from "../../../database/database"; +import {ExtendedCommand} from "../../../structures/extendedCommand"; export const command = new ExtendedCommand( { name: "editstatus", description: "Edit the status of an order.", local: true } @@ -31,9 +28,15 @@ export const command = new ExtendedCommand( // Add other choices here if needed ) ) - .setExecutor(async (int: CommandInteraction) => { + .setExecutor(async (int) => { const orderId = int.options.getString("order_id", true); - const newStatus = int.options.getString("status", true); + const newStatus = int.options.getString("status", true) as OrderStatus; + + // assert newStatus is a valid OrderStatus to make sure this is type-safe + if (!Object.values(OrderStatus).includes(newStatus as OrderStatus)) { + await int.reply({content: "Invalid status provided."}); + return; + } const order = await matchActiveOrder(orderId); if (!order) { diff --git a/src/commands/orders/worker/leaderboard.ts b/src/commands/orders/worker/leaderboard.ts index 307bd97..cc7b6b0 100644 --- a/src/commands/orders/worker/leaderboard.ts +++ b/src/commands/orders/worker/leaderboard.ts @@ -1,15 +1,14 @@ /* eslint-disable indent */ -import { permissions } from "../../../providers/permissions"; -import { CommandInteraction, EmbedBuilder, Message } from "discord.js"; -import { ButtonBuilder, ButtonStyle, ActionRowBuilder } from "discord.js"; -import { Command } from "../../../structures/Command"; -import { getWorkerInfos } from "../../../database/workerInfo"; -import { ExtendedCommand } from "../../../structures/extendedCommand"; +import {permissions} from "../../../providers/permissions"; +import {ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, Message} from "discord.js"; +import {getWorkerInfos} from "../../../database/workerInfo"; +import {ExtendedCommand} from "../../../structures/extendedCommand"; + const PAGE_SIZE = 5; // Number of workers per page async function refreshWorkerInfos() { // Refresh worker infos from the database - await getWorkerInfos(true); + await getWorkerInfos(); // Wait for 1 second before retrieving the worker infos again await new Promise((resolve) => setTimeout(resolve, 1000)); } @@ -18,7 +17,7 @@ export const command = new ExtendedCommand( { name: "leaderboard", description: "hm", local: true } ) .addPermission(permissions.developer) - .setExecutor(async (int: CommandInteraction) => { + .setExecutor(async (int) => { // Refresh worker infos from the database await refreshWorkerInfos(); diff --git a/src/commands/orders/worker/unclaim.ts b/src/commands/orders/worker/unclaim.ts index 49b1ca5..5cbf8f2 100644 --- a/src/commands/orders/worker/unclaim.ts +++ b/src/commands/orders/worker/unclaim.ts @@ -1,5 +1,3 @@ -/* eslint-disable quotes */ -/* eslint-disable indent */ import { upsertWorkerInfo } from "../../../database/workerInfo"; import { Command } from "../../../structures/Command"; import { permissions } from "../../../providers/permissions"; @@ -10,7 +8,6 @@ import { client } from "../../../providers/client"; import { CommandInteraction, StringSelectMenuBuilder, ComponentType, EmbedBuilder } from "discord.js"; import { ExtendedCommand } from "../../../structures/extendedCommand"; -const claimedOrderLocks = new Map(); // Map to store claim locks for each order ID const claimedOrders = new Set(); // Set to store claimed order IDs export const command = new ExtendedCommand( @@ -24,17 +21,33 @@ export const command = new ExtendedCommand( return; } - const orders = await db.orders.findMany({ - where: { - claimer: int.user.id, - status: OrderStatus.Preparing, - }, - select: { - id: true, - user: true, - details: true, - }, - }); + let orders; + if (await permissions.admin.hasPermission(int.user)) { + // If the user is an admin, fetch all claimed orders + orders = await db.orders.findMany({ + where: { + status: OrderStatus.Preparing, + }, + select: { + id: true, + user: true, + details: true, + }, + }); + } else { + // If the user is not an admin, fetch only their own claimed orders + orders = await db.orders.findMany({ + where: { + claimer: int.user.id, + status: OrderStatus.Preparing, + }, + select: { + id: true, + user: true, + details: true, + }, + }); + } if (orders.length === 0) { await int.reply({ content: "You don't have any orders to unclaim.", ephemeral: true }); @@ -89,52 +102,49 @@ client.on("interactionCreate", async (interaction) => { for (const orderId of orderIds) { try { - // Check if the order is claimed by the user - const order = await db.orders.findFirst({ - where: { - id: orderId, - claimer: interaction.user.id, - status: OrderStatus.Preparing, - }, - }); - - if (!order) { - unclaimedOrderMessages.push(`Order ${orderId} is not claimed by you.`); - continue; - } - - // Check if a claim lock exists for this order - if (claimedOrderLocks.has(orderId) && claimedOrderLocks.get(orderId)) { - unclaimedOrderMessages.push(`Another process is currently unclaiming Order ${orderId}. Please try again later.`); - continue; + if (await permissions.admin.hasPermission(interaction.user)) { + // If the user is an admin, forcefully unclaim the order + await db.orders.update({ + where: { id: orderId }, + data: { claimer: null, status: OrderStatus.Unprepared }, + }); + + unclaimedOrderMessages.push(`Order ${orderId} forcefully unclaimed by admin.`); + } else { + // Check if the order is claimed by the user + const order = await db.orders.findFirst({ + where: { + id: orderId, + claimer: interaction.user.id, + status: OrderStatus.Preparing, + }, + }); + + if (!order) { + unclaimedOrderMessages.push(`Order ${orderId} is not claimed by you.`); + continue; + } + + // Update the claimed order + await db.orders.update({ + where: { id: orderId }, + data: { claimer: null, status: OrderStatus.Unprepared }, + }); + + unclaimedOrderMessages.push(`Order ${orderId} unclaimed successfully.`); } - // Set an unclaim lock for this order - claimedOrderLocks.set(orderId, true); - - // Update the claimed order and release the unclaim lock - await db.orders.update({ - where: { id: orderId }, - data: { claimer: null, status: OrderStatus.Unprepared }, - }); - + // Remove the order from claimed orders set claimedOrders.delete(orderId); - - // Release the unclaim lock for this order - claimedOrderLocks.delete(orderId); - - unclaimedOrderMessages.push(`Order ${orderId} unclaimed successfully.`); } catch (error) { console.error(`Error processing Order ${orderId}:`, error); unclaimedOrderMessages.push(`Error processing Order ${orderId}`); - } finally { - claimedOrderLocks.delete(orderId); } } // Send a single reply summarizing the unclaimed orders await interaction.reply({ - content: `Unclaiming results:\n${unclaimedOrderMessages.join('\n')}`, + content: `Unclaiming results:\n${unclaimedOrderMessages.join("\n")}`, ephemeral: false, }); } diff --git a/src/commands/orders/worker/wash.ts b/src/commands/orders/worker/wash.ts index 983d4a0..4854ca0 100644 --- a/src/commands/orders/worker/wash.ts +++ b/src/commands/orders/worker/wash.ts @@ -1,12 +1,16 @@ -import { CommandInteraction } from 'discord.js'; -import { PrismaClient } from '@prisma/client'; +/* eslint-disable indent */ +/* eslint-disable quotes */ +import { PrismaClient } from "@prisma/client"; import { permissions } from "../../../providers/permissions"; import { Command } from "../../../structures/Command"; import { getUserBalance, updateBalance } from "../../../database/userInfo"; +import { ExtendedCommand } from "../../../structures/extendedCommand"; const prisma = new PrismaClient(); +export const command = new ExtendedCommand( + { name: "wash", description: "Wash a dish.", local: true } +) -export const command = new Command('wash', 'Wash a dish.') .addAlias('clean') .addPermission(permissions.employee) .addOption("string", (o) => o @@ -19,7 +23,7 @@ export const command = new Command('wash', 'Wash a dish.') .addOption("boolean", (o) => o.setName("inactive").setDescription("Include inactive orders too.") ) - .setExecutor(async (interaction: CommandInteraction) => { + .setExecutor(async (interaction) => { const all = await prisma.dishes.findMany({ take: 10 }); if (!all.length) { await interaction.reply("There are currently no dishes to wash."); @@ -46,7 +50,7 @@ export const command = new Command('wash', 'Wash a dish.') setTimeout(async () => { const userInfo = await getUserBalance(interaction.user); - const donuts = userInfo.donuts + 60; + const donuts = userInfo.donuts ? userInfo.donuts + 60 : 60; await updateBalance(interaction.user, userInfo.balance, donuts); await interaction.followUp(`${interaction.user}, dish ${dish.id} has finished washing. You received 60 donuts.`); diff --git a/src/commands/orders/worker/workerstats.ts b/src/commands/orders/worker/workerstats.ts index a2b522f..971d9db 100644 --- a/src/commands/orders/worker/workerstats.ts +++ b/src/commands/orders/worker/workerstats.ts @@ -1,22 +1,21 @@ /* eslint-disable quotes */ /* eslint-disable indent */ -import { CommandInteraction, EmbedBuilder } from "discord.js"; -import { permissions } from "../../../providers/permissions"; -import { Command } from "../../../structures/Command"; -import { PrismaClient, Prisma } from '@prisma/client'; -import { getWorkerInfo, getWorkerInfos } from "../../../database/workerInfo"; -import { ExtendedCommand } from "../../../structures/extendedCommand"; +import {EmbedBuilder} from "discord.js"; +import {permissions} from "../../../providers/permissions"; +import {PrismaClient} from "@prisma/client"; +import {getWorkerInfos} from "../../../database/workerInfo"; +import {ExtendedCommand} from "../../../structures/extendedCommand"; const prisma = new PrismaClient(); export const command = new ExtendedCommand( { name: "workerstats", description: "Checks the global worker stats.", local: true } ) - .addSyntax("monthly", "text") + .addSyntax("monthly", "string") .addPermission(permissions.employee) .addShortcuts("ws") - .setExecutor(async (int: CommandInteraction) => { - const args = int.options.getString("monthly")?.includes("m") ? ["monthly", ...int.options.getString("monthly").split(" ").slice(1)] : []; + .setExecutor(async (int) => { + const args = int.options.getString("monthly")?.includes("m") ? ["monthly", ...int.options.getString("monthly", true).split(" ").slice(1)] : []; const workerInfos = await getWorkerInfos(); // Retrieve the workerInfos let data = workerInfos; let isMonthly = false; diff --git a/src/commands/public/notifi.ts b/src/commands/public/notifi.ts index 0a4019b..6ff0ae6 100644 --- a/src/commands/public/notifi.ts +++ b/src/commands/public/notifi.ts @@ -23,7 +23,6 @@ export const command = new Command("notifi", return; } - // Update the notification channel in the database await prisma.guildsXP.upsert({ where: { userId_guildId: { @@ -34,12 +33,10 @@ export const command = new Command("notifi", create: { userId: int.user.id, guildId: int.guild.id, - userName: int.user.username, level: 0, exp: 0, - location: 'default', notificationChannelId: channelId, // Set the notification channel ID - }, + } as any, // Explicitly specifying the type of 'data' update: { notificationChannelId: channelId, // Update the notification channel ID }, diff --git a/src/commands/public/profile.ts b/src/commands/public/profile.ts index 294f93e..1fcb5db 100644 --- a/src/commands/public/profile.ts +++ b/src/commands/public/profile.ts @@ -19,15 +19,20 @@ export const command = new Command("profile", "Shows your profile.") const guildId = int.guild.id; // Check if the user exists in the userInfo table - const userInfo = await prisma.userInfo.findUnique({ + let userInfo = await prisma.userInfo.findUnique({ where: { id: userId, }, }); + // Create user info if it doesn't exist if (!userInfo) { - await int.reply("You don't have a profile yet."); - return; + userInfo = await prisma.userInfo.create({ + data: { + id: userId, + // Add any additional fields you want to initialize + }, + }); } // Check if the user's guildsXP data exists in the database @@ -46,24 +51,10 @@ export const command = new Command("profile", "Shows your profile.") data: { userId: userId, guildId: guildId, - userName: int.user.username, level: 0, exp: 0, user: { connect: { id: userId } }, // Connect the guildsXP to the UserInfo - }, - }); - } else if (!userGuildData.userName) { - // If the userName is blank, update it with the user's username - userGuildData = await prisma.guildsXP.update({ - where: { - userId_guildId: { - userId: userId, - guildId: guildId, - }, - }, - data: { - userName: int.user.username, - }, + } as any, // Explicitly specifying the type of 'data' }); } @@ -72,7 +63,7 @@ export const command = new Command("profile", "Shows your profile.") // Create a new embed using EmbedBuilder const embed = new EmbedBuilder() - .setTitle(`${int.user.username}'s Profile`) + .setTitle("Profile") .setThumbnail(int.user.displayAvatarURL()) .addFields( { name: "Experience", value: `${userGuildData.exp}/${nextLevelExp}`, inline: true }, diff --git a/src/commands/test.ts b/src/commands/test.ts deleted file mode 100644 index 41754b3..0000000 --- a/src/commands/test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Command } from "../structures/Command"; -import { actionRowOf, cbButton, cbSelectMenu } from "../utils/components"; - -export const command = new Command("test", "foo bar baz").setExecutor(async int => { - await int.reply({ - components: [ - actionRowOf( - cbButton(ctx => { - ctx.disable(); - }) - .setLabel("Testing BUtton") - .setEmoji("📈") - .setStyle("DANGER") - ), - actionRowOf( - cbSelectMenu(async ctx => { - await ctx.disable(); - await ctx.int.followUp(ctx.int.values.join(", ")); - }) - .setMaxValues(2) - .setMinValues(1) - .setPlaceholder("i am in severe pain") - .setOptions( - ...[...Array(10)].map((_, x) => ({ - label: `label ${x}`, - value: `${x}`, - description: `description ${x}`, - emoji: ["🕗", "♍", "🌎", "😑", "🔸", "💞", "🍤", "⛔", "🍊", "⏳"][x], - })) - ) - ), - ], - }); -}); diff --git a/src/commands/work.ts b/src/commands/work.ts deleted file mode 100644 index 7361990..0000000 --- a/src/commands/work.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable quotes */ -/* eslint-disable linebreak-style */ -//work.ts -import { db } from "../../database/database"; -import { upsertUserInfo } from "../../database/userInfo"; -import { constants, text } from "../../providers/config"; -import { Command } from "../../structures/Command"; -import { format } from "../../utils/string"; -import pms from "pretty-ms"; -import { randRange, sampleArray } from "../../utils/utils"; -const cooldowns: Record = {}; - -export const command = new Command("work", "Gets you some money.") - .setExecutor(async int => { - if (int.user.id in cooldowns && cooldowns[int.user.id] >= Date.now()) { - await int.reply( - format( - text.errors.cooldown, - pms(cooldowns[int.user.id] - Date.now(), { compact: true, secondsDecimalDigits: 1 }) - ) - ); - return; - } - const info = await upsertUserInfo(int.user, int.guild?.id || ''); - const obtained = randRange(...constants.work.amountRange); - cooldowns[int.user.id] = Date.now() + constants.work.cooldownMs; - await db.userInfo.update({ where: { id: info.id }, data: { balance: { increment: obtained } } }); - await int.reply(format(sampleArray(text.commands.work.responses), `\`$${obtained}\``)); - }); diff --git a/src/database/blacklist.ts b/src/database/blacklist.ts index 47b643d..b4508c8 100644 --- a/src/database/blacklist.ts +++ b/src/database/blacklist.ts @@ -1,13 +1,24 @@ -import type { UserResolvable } from "discord.js"; -import { IllegalStateError } from "../utils/error"; -import { resolveUserId } from "../utils/id"; -import { db } from "./database"; +import type {UserResolvable} from "discord.js"; +import {IllegalStateError} from "../utils/error"; +import {resolveUserId} from "../utils/id"; +import {db} from "./database"; +/** + * A set of blacklisted user IDs. + */ export const blacklist = new Set(); +/** + * Adds a user to the blacklist. + * @param user - The user to add to the blacklist. + * @param blacklister - The user who blacklisted the user. + * @param reason - The reason for blacklisting the user. + */ export const createBlacklist = async (user: UserResolvable, blacklister: UserResolvable, reason: string) => { blacklist.add(resolveUserId(user)); - await db.blacklist.create({ data: { id: resolveUserId(user), blacklister: resolveUserId(blacklister), reason } }); + await db.blacklist.create({data: {id: resolveUserId(user), blacklister: resolveUserId(blacklister), reason}}); }; -db.blacklist.findMany().then(b => b.map(v => blacklist.add(v.id))).catch(x => { throw new IllegalStateError(`Failed to fetch blacklists: ${x}`); }); \ No newline at end of file +db.blacklist.findMany().then(b => b.map(v => blacklist.add(v.id))).catch(x => { + throw new IllegalStateError(`Failed to fetch blacklists: ${x}`); +}); \ No newline at end of file diff --git a/src/database/database.ts b/src/database/database.ts index ec13b38..5f7bcb5 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -1,5 +1,8 @@ -import { PrismaClient } from "@prisma/client"; +import {PrismaClient} from "@prisma/client"; +/** + * who would've guessed, it's the database + */ export const db = new PrismaClient(); //todo \ No newline at end of file diff --git a/src/database/order.ts b/src/database/order.ts index 5d61947..2dc756a 100644 --- a/src/database/order.ts +++ b/src/database/order.ts @@ -1,13 +1,13 @@ -import type { Order, } from "@prisma/client"; -import { CafeStatus, CafeOrders, PrismaClient } from "@prisma/client"; -import type { Client, User, UserResolvable, Channel } from "discord.js"; +import type { CafeOrders } from "@prisma/client"; // Update to CafeOrders +import { CafeStatus, PrismaClient } from "@prisma/client"; // Update to CafeStatus +import type { Channel, Client, User, UserResolvable } from "discord.js"; import { EmbedBuilder, GuildChannel } from "discord.js"; import { client } from "../providers/client"; import { text } from "../providers/config"; import { resolveUserId } from "../utils/id"; import { format } from "../utils/string"; import { db } from "./database"; -import type { EmbedField } from "discord.js"; + const prisma = new PrismaClient(); export const activeCafeStatus = [ CafeStatus.Unprepared, @@ -16,6 +16,7 @@ export const activeCafeStatus = [ CafeStatus.Fermenting, CafeStatus.PendingDelivery, CafeStatus.Delivering, + CafeStatus.Claimed ]; export const hasActiveOrder = async (user: UserResolvable) => @@ -89,7 +90,7 @@ export const getLatestOrder = async (user: UserResolvable) => const embedText = text.common.orderEmbed; const embedFields = text.common.orderEmbed.fields; -const rawOrderEmbed = (order: Order) => +const rawOrderEmbed = (order: CafeOrders) => // Update to CafeOrders new EmbedBuilder() .setTitle(format(embedText.title, order.id)) .setDescription(format(embedText.description, order.id)) @@ -113,7 +114,7 @@ const formatChannel = (channel: Channel | string) => : channel.id ); -export const orderEmbedSync = async (order: CafeOrders, client: Client) => { +export const orderEmbedSync = async (order: CafeOrders, client: Client) => { // Update to CafeOrders const embed = rawOrderEmbed(order) .addFields({ name: embedFields.customer, value: formatUser((await client.users.fetch(order.user).catch(() => null)) ?? order.user), inline: true }) .addFields({ name: embedFields.channel, value: formatChannel((await client.channels.fetch(order.channel).catch(() => null)) ?? order.channel), inline: true }) @@ -125,7 +126,7 @@ export const orderEmbedSync = async (order: CafeOrders, client: Client) => { const nulli = () => null; -export const orderEmbedAsync = async (order: CafeOrders, client: Client): Promise => { +export const orderEmbedAsync = async (order: CafeOrders, client: Client): Promise => { // Update to CafeOrders const user = await client.users.fetch(order.user).catch(() => null); const channel = await client.channels.fetch(order.channel).catch(() => null); const guild = await client.guilds.fetch(order.guild).catch(() => null); @@ -154,7 +155,7 @@ export const orderEmbedAsync = async (order: CafeOrders, client: Client }; export const requiredOrderPlaceholders = ["mention", "image"]; -export const orderPlaceholders = async (order: CafeOrders) => Object.assign(Object.create(null), { +export const orderPlaceholders = async (order: CafeOrders) => Object.assign(Object.create(null), { // Update to CafeOrders preparer: order.claimer ? formatUser((await client.users.fetch(order.claimer).catch(nulli)) ?? order.claimer) : "Unknown", deliverer: order.deliverer ? formatUser((await client.users.fetch(order.deliverer).catch(nulli)) ?? order.deliverer) : "Unknown", id: order.id, @@ -170,4 +171,4 @@ export const OrderFlags = { Rated: 0b100, }; -export { CafeStatus }; \ No newline at end of file +export { CafeStatus }; diff --git a/src/database/orders.ts b/src/database/orders.ts index 6166984..99a2b69 100644 --- a/src/database/orders.ts +++ b/src/database/orders.ts @@ -89,7 +89,7 @@ export const getLatestOrder = async (user: UserResolvable) => const embedText = text.common.orderEmbed; const embedFields = text.common.orderEmbed.fields; -const rawOrderEmbed = (order: Orders) => +const rawOrderEmbed = (order: Orders) => new EmbedBuilder() .setTitle(format(embedText.title, order.id)) .setDescription(format(embedText.description, order.id)) diff --git a/src/database/preloadimage.ts b/src/database/preloadimage.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/database/userInfo.ts b/src/database/userInfo.ts index 9fc2644..2b7ceb9 100644 --- a/src/database/userInfo.ts +++ b/src/database/userInfo.ts @@ -1,3 +1,4 @@ +/* eslint-disable indent */ /* eslint-disable quotes */ import { PrismaClient, UserInfo } from '@prisma/client'; import type { User, UserResolvable } from 'discord.js'; @@ -8,31 +9,26 @@ const prisma = new PrismaClient(); export const getUserInfo = async (user: UserResolvable) => prisma.userInfo.findFirst({ where: { id: resolveUserId(user) } }); -export const upsertUserInfo = async (user: User, guildId: string): Promise => { - const existingUserInfo = await prisma.userInfo.findUnique({ +export const upsertUserInfo = async (user: User): Promise => { + let userInfo = await prisma.userInfo.findUnique({ where: { id: resolveUserId(user), }, }); - if (existingUserInfo) { - return existingUserInfo; + if (!userInfo) { + userInfo = await prisma.userInfo.create({ + data: { + id: resolveUserId(user), + } + }); } - const createdUserInfo = await prisma.userInfo.create({ - data: { - id: resolveUserId(user), - userId: user.id, - userName: user.username, - guildId: guildId, - }, - }); - - return createdUserInfo; + return userInfo; }; -export const getUserBalance = async (user: UserResolvable): Promise<{ balance: number; donuts: number }> => { +export const getUserBalance = async (user: UserResolvable): Promise<{ balance: number; donuts?: number }> => { const userInfo = await prisma.userInfo.findUnique({ where: { id: resolveUserId(user), @@ -43,17 +39,19 @@ export const getUserBalance = async (user: UserResolvable): Promise<{ balance: n }, }); - const balance = userInfo?.balance ?? 0; - const donuts = userInfo?.donuts ?? 0; + // Parse balance and donuts as numbers + const balance = userInfo ? Number(userInfo.balance) : 0; + const donuts = userInfo ? Number(userInfo.donuts) : undefined; return { balance, donuts }; }; + // Update user balance function export const updateBalance = async ( user: UserResolvable, newBalance: number, - newDonuts: number + newDonuts?: number // Making newDonuts optional ): Promise => { // Check if newBalance is a valid number if (isNaN(newBalance) || typeof newBalance !== 'number') { @@ -63,7 +61,7 @@ export const updateBalance = async ( // Ensure balance is a whole number const balance = Math.floor(newBalance); - const donuts = Math.floor(newDonuts); + const donuts = newDonuts !== undefined ? Math.floor(newDonuts) : undefined; // Update the user's balance in the database const updatedUserInfo = await prisma.userInfo.update({ @@ -72,10 +70,30 @@ export const updateBalance = async ( }, data: { balance: balance, - donuts: donuts, + // Update donuts only if newDonuts is provided + ...(donuts !== undefined && { donuts: donuts }), }, }); + return updatedUserInfo; }; +// Create guild-specific data function +export const createGuildData = async ( + userId: string, + guildId: string, + level: number, + exp: number, + notificationChannelId?: string +): Promise => { + await prisma.guildsXP.create({ + data: { + userId: userId, + guildId: guildId, + level: level, + exp: exp, + notificationChannelId: notificationChannelId, + } as any, // Explicitly specifying the type of 'data' + }); +}; diff --git a/src/events/ExpCreate.ts b/src/events/ExpCreate.ts index d4435e9..2089f16 100644 --- a/src/events/ExpCreate.ts +++ b/src/events/ExpCreate.ts @@ -2,7 +2,6 @@ /* eslint-disable indent */ import { PrismaClient } from "@prisma/client"; import { client } from "../providers/client"; - const prisma = new PrismaClient(); // Map to hold cooldown Sets per guild @@ -47,8 +46,7 @@ client.on('messageCreate', async (message) => { balance: 0, tabLimit: 0.0, donuts: 0, - guildsxp: "{}", - }, + } as any, // Explicitly specifying the type of 'data' }); } @@ -63,21 +61,21 @@ client.on('messageCreate', async (message) => { create: { userId: userId, guildId: guildId, - userName: message.author.username, level: 0, exp: 0, - }, + } as any, // Explicitly specifying the type of 'data' update: {}, }); // Increase their XP - guildsXPData.exp += Math.floor(Math.random() * 20) + 1; + const xpGain = Math.floor(Math.random() * 20) + 1; + guildsXPData.exp += xpGain; // Check if the user has enough XP to level up - if (guildsXPData.exp >= guildsXPData.level * 100) { + while (guildsXPData.exp >= guildsXPData.level * 100) { // If they do, increase their level and reset their XP guildsXPData.level += 1; - guildsXPData.exp = 0; + guildsXPData.exp -= guildsXPData.level * 100; // Get the ID of the notification channel from the database const notificationChannelId = guildsXPData.notificationChannelId; @@ -93,6 +91,11 @@ client.on('messageCreate', async (message) => { } } + // Ensure exp is not negative + if (guildsXPData.exp < 0) { + guildsXPData.exp = 0; + } + // Update the user's data in the database await prisma.guildsXP.update({ where: { diff --git a/src/events/GuildCreate.ts b/src/events/GuildCreate.ts new file mode 100644 index 0000000..fd17339 --- /dev/null +++ b/src/events/GuildCreate.ts @@ -0,0 +1,25 @@ +/* eslint-disable indent */ +/* eslint-disable quotes */ +import { Guild, ChannelType, EmbedBuilder } from "discord.js"; +import { client } from "../providers/client"; + +client.on("guildCreate", async (guild: Guild) => { + console.log(`Bot joined a new guild. Current guild count: ${client.guilds.cache.size}`); + + const channel = guild.systemChannel; + if (channel && channel.type === ChannelType.GuildText) { + const embed = new EmbedBuilder() + .setTitle("Thank you for inviting me!") + .setDescription("We are also looking for employees if you are interested in joining us!\nIf you want, you can join our support server!\n[***Our Server!***](https://discord.gg/sNbK4rRHYt)\nWe are online 24/7") + .setColor("Random") + .setFooter({ text: "Drunk Bartender Official", iconURL: client.user?.displayAvatarURL() }) + .setTimestamp() + .toJSON(); + + channel.send({ embeds: [embed] }); + } +}); + +client.on("guildDelete", async (guild: Guild) => { + console.log(`Bot removed from a guild. Current guild count: ${client.guilds.cache.size}`); +}); diff --git a/src/events/ServerConfig.ts b/src/events/ServerConfig.ts index 22522d7..9a1a8e7 100644 --- a/src/events/ServerConfig.ts +++ b/src/events/ServerConfig.ts @@ -1,3 +1,5 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore todo: this file isn't being used, so ts-ignore until it is /* eslint-disable indent */ import * as fs from "fs"; @@ -5,34 +7,34 @@ interface GuildConfig { orderChannelId?: string; } -interface ServerConfig { - guilds: Record; -} - export class ServerConfig { private static readonly configFile = "config.json"; - private config: ServerConfig; + private config: ServerConfig | null; + private guilds: { + [guildId: string]: GuildConfig; + } = {}; constructor() { this.config = this.loadConfig(); } - private loadConfig(): ServerConfig { + private loadConfig(): ServerConfig | null { try { const data = fs.readFileSync(ServerConfig.configFile, "utf-8"); return JSON.parse(data); } catch (error) { console.error("Error loading config file:", error); - return { guilds: {} }; + return null; } } public getOrderChannel(guildId: string): string | undefined { - return this.config.guilds[guildId]?.orderChannelId; + return this.config?.guilds[guildId]?.orderChannelId; } public setOrderChannel(guildId: string, channelId: string): void { - if (!this.config.guilds[guildId]) { + if (!this.config?.guilds[guildId]) { + if (!this.config) return; this.config.guilds[guildId] = {}; } this.config.guilds[guildId].orderChannelId = channelId; diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index 9ffc5a1..648e466 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -3,26 +3,46 @@ import { commandRegistry } from "../providers/commandManager"; import { text } from "../providers/config"; import { blacklist } from "../database/blacklist"; import { StopCommandExecution } from "../utils/error"; +import { ChatInputCommandInteraction } from "discord.js"; + +// Custom logging functions +function logInteractionAlreadyReplied() { + console.log("The reply to this interaction has already been sent or deferred."); +} + +function logBlacklistedUserInteraction(userId: string) { + console.log(`Interaction failed due to user being blacklisted: ${userId}`); +} + +function logException(message: string) { + console.log(`Interaction failed with exception: ${message}`); +} + client.on("interactionCreate", async (int) => { try { if (!int.inCachedGuild()) { - if (int.isCommand()) int.reply("Error B417"); + if (int.isCommand()) await int.reply("Error B417"); return; } + if (int.isCommand()) { if (blacklist.has(int.user.id)) { await int.reply(text.errors.blacklisted); + return; // Return after replying to prevent further execution } + const command = commandRegistry.get(int.commandName); if (!command) throw new Error(`Unregistered command ${int.commandName}`); - // TODO remove this and use discord builtin when permissions get better + + // TODO remove this and use Discord's built-in permissions when permissions get better for (const perm of command.permissions) await perm.check(int); - await command.executor(int); + + await command.executor(int as ChatInputCommandInteraction<"cached">); } } catch (e) { if (!(e instanceof StopCommandExecution)) { - if (int.isCommand()) int.reply({ content: text.errors.exception, ephemeral: true }).catch(); + if (int.isCommand()) await int.reply({ content: text.errors.exception, ephemeral: true }); console.error(e); } } diff --git a/src/events/ready.ts b/src/events/ready.ts index 7e43083..cafc78a 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -23,9 +23,9 @@ client.on("ready", async () => { typedEntries(config.roles).map(async x => [ x[0], (await mainGuild.roles.fetch(x[1])) ?? - (() => { - throw new IllegalStateError(`Role ${x[0]} was not found.`); - })(), + (() => { + throw new IllegalStateError(`Role ${x[0]} was not found.`); + })(), ]) ) ) @@ -48,6 +48,8 @@ client.on("ready", async () => { else if (typeof texts[k] === "object") parseTexts(texts[k] as TextObject); } }; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore todo parseTexts(text.commands); parseTexts(text.errors); parseTexts(text.common); diff --git a/src/index.ts b/src/index.ts index 51c9a72..0dfa6e3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,9 @@ import "./providers/client"; -import { development } from "./providers/env"; -import { production } from "./providers/env"; +import { development, production } from "./providers/env"; import "source-map-support/register"; +// experimental API +// import "./providers/apiServer"; + if (development) console.warn("Starting in development mode!"); if (production) console.warn("Starting in production mode!"); + diff --git a/src/providers/apiServer.ts b/src/providers/apiServer.ts new file mode 100644 index 0000000..086a684 --- /dev/null +++ b/src/providers/apiServer.ts @@ -0,0 +1,25 @@ +/* eslint-disable linebreak-style */ +/* eslint-disable quotes */ +// Import the framework and instantiate it +import Fastify from "fastify"; + +const fastify = Fastify({ + logger: true +}); + +// Declare a route +fastify.get("/", async function handler(request, reply) { + return { hello: "world" }; +}); + +// Run the server! +try { + fastify.listen({ port: 3000 }).then(() => { + console.log(`Server listening on port 3000.`); + }); +} catch (err) { + fastify.log.error(err); + process.exit(1); +} + +export default fastify; \ No newline at end of file diff --git a/src/providers/client.ts b/src/providers/client.ts index 2428f90..629d33b 100644 --- a/src/providers/client.ts +++ b/src/providers/client.ts @@ -1,9 +1,8 @@ -import { REST } from "@discordjs/rest"; -import { Client, GatewayIntentBits, Partials } from "discord.js"; -import { config } from "./config"; -import { join } from "path"; -import { sync } from "fast-glob"; -import fs from "fs/promises"; +import {REST} from "@discordjs/rest"; +import {Client, GatewayIntentBits, Partials} from "discord.js"; +import {config} from "./config"; +import {join} from "path"; +import {sync} from "fast-glob"; if (globalThis._$clientLoaded) throw new Error("The client was loaded twice. This should never happen."); globalThis._$clientLoaded = true; @@ -13,7 +12,8 @@ export const client = new Client({ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers, - GatewayIntentBits.MessageContent + // GatewayIntentBits.MessageContent + // ^ This intent is not needed for slash commands and will cry like a baby if you try to use it ], partials: [Partials.User, Partials.Channel, Partials.GuildMember, Partials.Message], }); diff --git a/src/providers/commandManager.ts b/src/providers/commandManager.ts index d444c16..4ebbd38 100644 --- a/src/providers/commandManager.ts +++ b/src/providers/commandManager.ts @@ -42,6 +42,7 @@ const registerCommands = async (commands: (Command | ExtendedCommand)[]) => { const globalCommands = commands.filter((x) => !(x instanceof ExtendedCommand && x.local)); const localCommands = commands.filter((x) => x instanceof ExtendedCommand && x.local); + const serverCommands = commands.filter((x) => x instanceof ExtendedCommand && x.servers); // New line for server commands // Register global commands await rest.put(Routes.applicationCommands(client.application.id), { body: globalCommands.map((x) => x.toJSON()) }); @@ -51,6 +52,15 @@ const registerCommands = async (commands: (Command | ExtendedCommand)[]) => { body: localCommands.map((x) => x.toJSON()), }); + // Register server commands for specific servers + for (const serverId of Object.values(config.servers)) { + const serverName = "TestServer"; // Replace this with the name of the server + await rest.put(Routes.applicationGuildCommands(client.application.id, serverId), { + body: serverCommands.map((x) => x.toJSON()), + }); + console.log(`Registered local commands for ${serverName}: ${serverCommands.map((x) => x.name).join(", ")}`); // Log the loaded commands for the server + } + commands.forEach((x) => commandRegistry.set(x.name, x)); for (const cmd of (await applicationCommandManager.fetch({})).values()) { applicationCommandRegistry.set(cmd.name, cmd); @@ -60,6 +70,8 @@ const registerCommands = async (commands: (Command | ExtendedCommand)[]) => { console.log(`Registered local commands for the main server: ${localCommands.map((x) => x.name).join(", ")}`); }; +const commandNames: string[] = []; + export const loadCommands = async (): Promise<(Command | ExtendedCommand)[]> => { const commands: (Command | ExtendedCommand)[] = []; // Ensure commands array is of type Command or ExtendedCommand const commandFiles = sync(commandFolder); @@ -68,6 +80,10 @@ export const loadCommands = async (): Promise<(Command | ExtendedCommand)[]> => if (!(data.command instanceof Command || (data.command as any) instanceof ExtendedCommand)) { throw new Error(`File ${file} does not export 'command'.`); } + if (commandNames.includes(data.command.name)) { + console.log(`Duplicate command name found: ${data.command.name}. Skipping...`); + continue; + } else commandNames.push(data.command.name); console.log(`Registered command ${basename(file, ".js")}.`); commands.push(data.command); } diff --git a/src/providers/config.ts b/src/providers/config.ts index 2919580..597a8f1 100644 --- a/src/providers/config.ts +++ b/src/providers/config.ts @@ -13,13 +13,13 @@ export const snowflake = z.union([ ]); const pFormattable = (n: T = 1 as T) => - z.string().refine(x => x.split("{}").length - 1 === n, { + z.string().refine((x) => x.split("{}").length - 1 === n, { message: `Formattable must contain ${n} placeholders`, }) as z.ZodType>; const nFormattable = (...keys: T) => z.string().refine( - x => { + (x) => { for (const key of keys) { if (!x.includes(`{${key}}`)) { return false; @@ -29,19 +29,31 @@ const nFormattable = (...keys: T) => }, { message: `Formattable must contain ${keys.join(", ")}`, - }, - ) as z.ZodType>;; + } + ) as z.ZodType>; const textSchema = z .object({ bot: z.object({ status: z.object({ - type: z.enum(["PLAYING", "STREAMING", "LISTENING", "WATCHING", "COMPETING"]), + type: z.enum([ + "PLAYING", + "STREAMING", + "LISTENING", + "WATCHING", + "COMPETING", + ]), name: z.string(), }), }), statuses: z.record( - z.union([z.never(), z.never(), ...Object.values(OrderStatus).map(x => z.literal(x))]).optional(), + z + .union([ + z.never(), + z.never(), + ...Object.values(OrderStatus).map((x) => z.literal(x)), + ]) + .optional(), z.string() ), common: z.object({ @@ -78,8 +90,11 @@ const textSchema = z success2: nFormattable("details", "id", "price"), success_tab: nFormattable("details", "id"), customOrderSuccess: nFormattable("customOrderDetails", "id"), - customOrderSuccess1: nFormattable("customOrderDetails", "id", "price"), - + customOrderSuccess1: nFormattable( + "customOrderDetails", + "id", + "price" + ), }), list: z.object({ title: z.string(), @@ -115,7 +130,6 @@ const textSchema = z success: z.string(), default: z.string(), multiSuccess: z.string(), - }), deliverymessage: z.object({ get: z.string(), @@ -151,7 +165,6 @@ const textSchema = z title: pFormattable(), footer: pFormattable(), }), - }), tip: z.object({ success: pFormattable(2), @@ -175,11 +188,13 @@ const textSchema = z successNoDm: z.string(), }), - rate: z.object({ - success: z.string(), - alreadyRated: z.string(), - invalidRating: z.string(), - }).passthrough(), + rate: z + .object({ + success: z.string(), + alreadyRated: z.string(), + invalidRating: z.string(), + }) + .passthrough(), drinkingr: z.object({ drinks: z.array(pFormattable()), @@ -207,6 +222,7 @@ const configSchema = z token: z.string(), mainServer: snowflake, developers: snowflake.array(), + dashboardUrl: z.string().url(), databaseUrl: z.string().url(), emojis: z.record(z.string(), snowflake), roles: z.object({ @@ -222,6 +238,9 @@ const configSchema = z feedback: snowflake, tips: snowflake, }), + servers: z.object({ + extraServer: snowflake, // Add the extra server here + }), }) .strict(); @@ -248,13 +267,23 @@ const constantsSchema = z export const configFolder = path.join(__dirname, "../../config/"); export const parseHjson = (schema: z.ZodType, file: string) => { - const sp = schema.safeParse(HJSON.parse(fs.readFileSync(path.join(configFolder, file), "utf-8"))); + const sp = schema.safeParse( + HJSON.parse(fs.readFileSync(path.join(configFolder, file), "utf-8")) + ); if (sp.success) return sp.data; - console.error(pc.bgRed(pc.yellow(`Issue(s) found when scanning config ${pc.white(pc.bold(file))}.`))); + console.error( + pc.bgRed( + pc.yellow( + `Issue(s) found when scanning config ${pc.white( + pc.bold(file) + )}.` + ) + ) + ); console.error(formatZodError(sp.error)); throw new IllegalStateError(`${file} is invalid.`); }; export const text = parseHjson(textSchema, "text.hjson"); export const config = parseHjson(configSchema, "config.hjson"); -export const constants = parseHjson(constantsSchema, "constants.hjson"); +export const constants = parseHjson(constantsSchema, "constants.hjson"); \ No newline at end of file diff --git a/src/providers/discord.ts b/src/providers/discord.ts index 96a30ff..be69564 100644 --- a/src/providers/discord.ts +++ b/src/providers/discord.ts @@ -3,16 +3,26 @@ import { notInitialized, typedEntries, typedFromEntries } from "../utils/utils"; import { client } from "./client"; import { config } from "./config"; +/** + * The guild's main guild. + */ export let mainGuild = client.guilds.cache.get(config.mainServer) ?? notInitialized("mainGuild"); +/** Updates the main guild. */ export const setMainGuild = (guild: Guild) => (mainGuild = guild); +/** The guild's main emojis. */ export const mainEmojis: Record = {}; + +/** The guild's main channels. */ export const mainChannels = typedFromEntries( typedEntries(config.channels).map( x => [x[0], (client.channels.cache.get(x[1]) ?? notInitialized(`mainChannels.${x[0]}`)) as TextBasedChannel] as const ) ); + +/** The guild's main roles. */ export let mainRoles: Record = notInitialized("mainRoles"); +/** Updates the main roles. */ export const setMainRoles = (roles: typeof mainRoles) => (mainRoles = roles); \ No newline at end of file diff --git a/src/providers/drink.ts b/src/providers/drink.ts deleted file mode 100644 index 0dca1de..0000000 --- a/src/providers/drink.ts +++ /dev/null @@ -1,25 +0,0 @@ -// drink.ts - -import { PrismaClient, Drink } from "@prisma/client"; - -const prisma = new PrismaClient(); - -// Function to retrieve all drinks -export async function getAllDrinks(): Promise { - return prisma.drink.findMany(); -} - -// Function to create a new drink -export async function createDrink(data: Partial): Promise { - return prisma.drink.create({ data }); -} - -// Function to update an existing drink -export async function updateDrink(id: number, data: Partial): Promise { - return prisma.drink.update({ where: { id }, data }); -} - -// Function to delete a drink -export async function deleteDrink(id: number): Promise { - return prisma.drink.delete({ where: { id } }); -} diff --git a/src/providers/env.ts b/src/providers/env.ts index 49eda08..32ace9f 100644 --- a/src/providers/env.ts +++ b/src/providers/env.ts @@ -1,3 +1,6 @@ -export const env = process.env.NODE_ENV ?? "production "; +/** The current development environment, will default to production if `process.env.NODE_ENV` is unset. */ +export const env = process.env.NODE_ENV ?? "production"; +/** Whether the current environment is development. */ export const development = env === "development"; +/** Whether the current environment is production. */ export const production = env === "production"; diff --git a/src/structures/Command.ts b/src/structures/Command.ts index c820b35..9b07a2f 100644 --- a/src/structures/Command.ts +++ b/src/structures/Command.ts @@ -1,11 +1,11 @@ /* eslint-disable quotes */ /* eslint-disable indent */ -import { SlashCommandBuilder } from "@discordjs/builders"; -import type { CommandInteraction } from "discord.js"; -import type { Permission } from "../providers/permissions"; -import { capitalize } from "../utils/string"; +import {SlashCommandBuilder} from "@discordjs/builders"; +import type {ChatInputCommandInteraction} from "discord.js"; +import type {Permission} from "../providers/permissions"; +import {capitalize} from "../utils/string"; -export type CommandExecutor = (interaction: CommandInteraction<"cached">) => void | Promise; +export type CommandExecutor = (interaction: ChatInputCommandInteraction<"cached">) => void | Promise; export type CommandOptionType = Extract< keyof SlashCommandBuilder, diff --git a/src/structures/CustomDrinkData.ts b/src/structures/CustomDrinkData.ts deleted file mode 100644 index 4ef2159..0000000 --- a/src/structures/CustomDrinkData.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const CustomdrinksData = [ - { name: "Drink1", type: "custom", price: 10 }, - { name: "Drink2", type: "custom", price: 8 }, - { name: "Drink3", type: "custom", price: 13 }, - { name: "Drink4", type: "custom", price: 10.99 }, -]; \ No newline at end of file diff --git a/src/structures/DrinksData.ts b/src/structures/DrinksData.ts deleted file mode 100644 index 41b69d3..0000000 --- a/src/structures/DrinksData.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const drinksData = [ - { name: "Drink11", type: "normal", price: 10 }, - { name: "Drink22", type: "normal", price: 8 }, - { name: "Drink33", type: "normal", price: 12 }, - { name: "Drink32", type: "normal", price: 13 }, -]; \ No newline at end of file diff --git a/src/structures/LifetimeMap.ts b/src/structures/LifetimeMap.ts index d65262c..3a30fa9 100644 --- a/src/structures/LifetimeMap.ts +++ b/src/structures/LifetimeMap.ts @@ -2,27 +2,48 @@ import { z } from "zod"; const numberSchema = z.number(); +/** + * A map that deletes its entries after a certain amount of time. + */ export class LifetimeMap extends Map { #timeoutMap = new Map(); + + /** + * Creates a new LifetimeMap. + * @param lifetime The lifetime, in ms. + */ constructor( - /** The lifetime, in ms. */ public lifetime: number ) { super(); numberSchema.parse(lifetime); } + /** + * Clears the map and cancels all timeouts. + */ clear(): void { this.#timeoutMap.forEach(v => clearTimeout(v)); this.#timeoutMap.clear(); super.clear(); } + + /** + * Deletes a key from the map and cancels the timeout. + * @param key The key to delete. + */ delete(key: K): boolean { const timeout = this.#timeoutMap.get(key); if (timeout) clearTimeout(timeout); this.#timeoutMap.delete(key); return super.delete(key); } + + /** + * Sets a key-value pair in the map and sets a timeout to delete it. + * @param key The key to set. + * @param value The value to set. + */ set(key: K, value: V): this { if (this.#timeoutMap.has(key)) { clearInterval(this.#timeoutMap.get(key)!); diff --git a/src/structures/extendedCommand.ts b/src/structures/extendedCommand.ts index 7ac2a6e..56cd431 100644 --- a/src/structures/extendedCommand.ts +++ b/src/structures/extendedCommand.ts @@ -7,7 +7,7 @@ interface CommandOptions { name: string; description?: string; local?: boolean; - // New property to specify whether the command should be registered locally + servers?: string[]; // New property to specify servers where the command should be registered locally // Other properties as needed } @@ -16,11 +16,15 @@ export class ExtendedCommand extends Command { // Add new properties specific to your modifications global: boolean; local: boolean; // New property to specify whether the command should be registered locally + servers: string[] | undefined; // New property to specify servers where the command should be registered locally // Constructor - constructor({ name, description, local = false, ...options }: CommandOptions) { + constructor({ name, description, local = false, servers, ...options }: CommandOptions) { super(name, description, options); this.global = !local; // Set global property based on the value of local this.local = local; + + // Ensure servers is an array and set it to the provided value, or set it as undefined if not provided + this.servers = Array.isArray(servers) ? servers : undefined; } -} \ No newline at end of file +} diff --git a/src/utils/array.ts b/src/utils/array.ts index c7de74b..e1d2151 100644 --- a/src/utils/array.ts +++ b/src/utils/array.ts @@ -1,5 +1,7 @@ /** * Checks if two arrays contain the same elements. + * @param arr1 - The first array. + * @param arr2 - The second array. */ export const arraysSimilar = (arr1: readonly T[], arr2: readonly T[]) => { if (arr1.length !== arr2.length) return false; diff --git a/src/utils/components.ts b/src/utils/components.ts index 99840db..0765a3f 100644 --- a/src/utils/components.ts +++ b/src/utils/components.ts @@ -1,6 +1,13 @@ -import type { ButtonInteraction, Constructable, MessageActionRowComponent, MessageComponentInteraction, SelectMenuInteraction } from "discord.js"; -import { MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js"; -import { componentCallbacks } from "../events/interactionCreate"; +// @ts-nocheck TODO: Remove this comment when the issue is fixed +import type { + ButtonInteraction, + Constructable, + MessageActionRowComponent, + MessageComponentInteraction, + SelectMenuInteraction +} from "discord.js"; +import {MessageActionRow, MessageButton, MessageSelectMenu} from "discord.js"; +import {componentCallbacks} from "../events/interactionCreate"; export type InteractionByType = C extends MessageButton ? ButtonInteraction<"cached"> diff --git a/src/utils/error.ts b/src/utils/error.ts index 291ef5f..c0ee0ca 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -1,12 +1,19 @@ +/** + * Represents an error that occurs when the application is in an illegal state. + */ export class IllegalStateError extends Error { override name = "IllegalStateError"; constructor(message: string, options?: ErrorOptions) { super(message, options); } } + +/** + * Custom error that can be used to stop command execution. + */ export class StopCommandExecution extends Error { override name = "StopCommandExecution"; constructor(message?: string, options?: ErrorOptions) { super(message, options); } -} \ No newline at end of file +} diff --git a/src/utils/id.ts b/src/utils/id.ts index 2a21790..75e8622 100644 --- a/src/utils/id.ts +++ b/src/utils/id.ts @@ -1,7 +1,13 @@ -import type { UserResolvable } from "discord.js"; -import { ThreadMember } from "discord.js"; -import { GuildMember, Message, User } from "discord.js"; +import type {UserResolvable} from "discord.js"; +import {GuildMember, Message, ThreadMember, User} from "discord.js"; +/** + * Resolves the user ID from a UserResolvable object. + * + * @param user - The UserResolvable object. + * @returns The resolved user ID. + * @throws Error if an invalid argument is provided. + */ export const resolveUserId = (user: UserResolvable) => typeof user === "string" ? user @@ -13,4 +19,6 @@ export const resolveUserId = (user: UserResolvable) => ? user.id : user instanceof ThreadMember ? user.id - : (() => { throw new Error(`Invalid argument ${user} provided.`); })(); + : (() => { + throw new Error(`Invalid argument ${user} provided.`); + })(); diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 74d1aab..43943f9 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,4 +1,4 @@ -import { IllegalStateError } from "./error"; +import {IllegalStateError} from "./error"; const notInitializedSymbol = Symbol("notInitialized"); export const notInitialized = (identifier?: string) => { @@ -38,6 +38,10 @@ export const typedFromEntries = (arr: rea Object.fromEntries(arr) as { [k in K]: V }; export const typedKeys = (obj: T) => Object.keys(obj) as (keyof T)[]; +/** + * Returns a random element from the given array. + * @param arr - The array to get a random element from. + */ export const sampleArray = (arr: T[]) => arr[Math.floor(Math.random() * arr.length)]; export const randRange = (lowerInclusive: number, upperExclusive: number) => diff --git a/src/utils/zod.ts b/src/utils/zod.ts index 74a7f8f..412f93a 100644 --- a/src/utils/zod.ts +++ b/src/utils/zod.ts @@ -1,17 +1,46 @@ import type { ZodError, ZodIssue } from "zod"; import pc from "picocolors"; +/** + * Formats a ZodError object into a human-readable string representation. + * @param err The ZodError object to format. + * @returns A formatted string representation of the ZodError. + */ export const formatZodError = (err: ZodError) => - `${pc.red(`${err.issues.length} issue(s) found.`)}\n${err.issues.map(formatZodIssue).join("\n")}`; + `${pc.red(`${err.issues.length} issue(s) found.`)}\n${err.issues + .map(formatZodIssue) + .join("\n")}`; -export const formatZodIssue = (iss: ZodIssue) => - `${pc.red(`Error at ${pc.bold(iss.path.join(".")) || "Unknown"}: `)}${getZodIssueMessage(iss)}`; +/** + * Formats a ZodIssue into an error message string. + * + * @param iss - The ZodIssue to format. + * @returns The formatted error message string. + */ +export const formatZodIssue = (iss: ZodIssue) => + `${pc.red( + `Error at ${pc.bold(iss.path.join(".")) || "Unknown"}: ` + )}${getZodIssueMessage(iss)}`; +/** + * Returns an issue message based on the ZodIssue code. + * @param iss The ZodIssue object. + * @returns The corresponding issue message. + */ export const getZodIssueMessage = (iss: ZodIssue) => { switch (iss.code) { - case "invalid_type": return `Expected ${pc.green(iss.expected)}, received ${pc.yellow(iss.received)}`; - case "unrecognized_keys": return `Unrecognized keys: ${iss.keys.map(x => pc.yellow(x)).join(", ")}`; - case "invalid_enum_value": return `Invalid enum value. Valid entries are ${iss.options.map(x => pc.green(x)).join(", ")}`; + case "invalid_type": + return `Expected ${pc.green(iss.expected)}, received ${pc.yellow( + iss.received + )}`; + case "unrecognized_keys": + return `Unrecognized keys: ${iss.keys + .map((x) => pc.yellow(x)) + .join(", ")}`; + case "invalid_enum_value": + return `Invalid enum value. Valid entries are ${iss.options + .map((x) => pc.green(x)) + .join(", ")}`; } return iss.message; -}; \ No newline at end of file +}; diff --git a/tsconfig.json b/tsconfig.json index 3bb8865..265fd7c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,25 +1,25 @@ { - "include": ["./src/**/*.ts", "src/commands/orders/order.disabled"], + "include": ["./src/**/*.ts", "src/events/GuildCreate.ts.disabled"], "exclude": ["./node_modules/**", "genenv.js"], "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Projects */ - "incremental": true /* Enable incremental compilation */, - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - "tsBuildInfoFile": "./.cache/.tsbuildinfo" /* Specify the folder for .tsbuildinfo incremental compilation files. */, - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + "incremental": true, + /* Enable incremental compilation */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + "tsBuildInfoFile": "./.cache/.tsbuildinfo", + /* Specify the folder for .tsbuildinfo incremental compilation files. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": [ + "target": "esnext", + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "lib": [ "esnext" - ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - // "jsx": "preserve", /* Specify what JSX code is generated. */ - "experimentalDecorators": true /* Enable experimental support for TC39 stage 2 draft decorators. */, - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + ], + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ + "experimentalDecorators": true, + /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ @@ -28,14 +28,15 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ - "module": "commonjs" /* Specify what module code is generated. */, - "rootDir": "./src/" /* Specify the root folder within your source files. */, - // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "module": "commonjs", + /* Specify what module code is generated. */ "rootDir": "./src/", + /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */, // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + "types": [], + /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "resolveJsonModule": true, /* Enable importing .json files */ // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ @@ -49,10 +50,10 @@ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - "sourceMap": true /* Create source map files for emitted JavaScript files. */, - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist/" /* Specify an output folder for all emitted files. */, - // "removeComments": true, /* Disable emitting comments. */ + "sourceMap": true, + /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist/", + /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ @@ -73,13 +74,12 @@ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + "esModuleInterop": true, + /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, + /* Ensure that casing is correct in imports. */ /* Type Checking */ + "strict": true, + /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type. */ // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ @@ -100,6 +100,7 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + /* Skip type checking all .d.ts files. */ } } diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index beca823..0000000 --- a/yarn.lock +++ /dev/null @@ -1,1893 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@discordjs/builders@^1.5.0-dev.1677499471-ffdb197.0", "@discordjs/builders@^1.7.0": - version "1.7.0" - resolved "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz" - integrity sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw== - dependencies: - "@discordjs/formatters" "^0.3.3" - "@discordjs/util" "^1.0.2" - "@sapphire/shapeshift" "^3.9.3" - discord-api-types "0.37.61" - fast-deep-equal "^3.1.3" - ts-mixer "^6.0.3" - tslib "^2.6.2" - -"@discordjs/collection@1.5.3": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.5.3.tgz#5a1250159ebfff9efa4f963cfa7e97f1b291be18" - integrity sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ== - -"@discordjs/collection@^0.4.0": - version "0.4.0" - resolved "https://registry.npmjs.org/@discordjs/collection/-/collection-0.4.0.tgz" - integrity sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw== - -"@discordjs/collection@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz" - integrity sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w== - -"@discordjs/formatters@^0.3.3": - version "0.3.3" - resolved "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz" - integrity sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w== - dependencies: - discord-api-types "0.37.61" - -"@discordjs/rest@^0.3.0": - version "0.3.0" - resolved "https://registry.npmjs.org/@discordjs/rest/-/rest-0.3.0.tgz" - integrity sha512-F9aeP3odlAlllM1ciBZLdd+adiAyBj4VaZBejj4UMj4afE2wfCkNTGvYYiRxrXUE9fN7e/BuDP2ePl0tVA2m7Q== - dependencies: - "@discordjs/collection" "^0.4.0" - "@sapphire/async-queue" "^1.1.9" - "@sapphire/snowflake" "^3.0.1" - discord-api-types "^0.26.1" - form-data "^4.0.0" - node-fetch "^2.6.5" - tslib "^2.3.1" - -"@discordjs/rest@^2.1.0": - version "2.2.0" - resolved "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz" - integrity sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A== - dependencies: - "@discordjs/collection" "^2.0.0" - "@discordjs/util" "^1.0.2" - "@sapphire/async-queue" "^1.5.0" - "@sapphire/snowflake" "^3.5.1" - "@vladfrangu/async_event_emitter" "^2.2.2" - discord-api-types "0.37.61" - magic-bytes.js "^1.5.0" - tslib "^2.6.2" - undici "5.27.2" - -"@discordjs/util@^1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz" - integrity sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw== - -"@discordjs/ws@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@discordjs/ws/-/ws-1.0.2.tgz#3933b12d4686aabf6a95dfe5fb6e744342a661d1" - integrity sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q== - dependencies: - "@discordjs/collection" "^2.0.0" - "@discordjs/rest" "^2.1.0" - "@discordjs/util" "^1.0.2" - "@sapphire/async-queue" "^1.5.0" - "@types/ws" "^8.5.9" - "@vladfrangu/async_event_emitter" "^2.2.2" - discord-api-types "0.37.61" - tslib "^2.6.2" - ws "^8.14.2" - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.41.0": - version "8.41.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz" - integrity sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA== - -"@fastify/busboy@^2.0.0": - version "2.1.1" - resolved "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz" - integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== - -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.1" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@noble/hashes@^1.1.5": - version "1.3.1" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@paralleldrive/cuid2@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.1.tgz" - integrity sha512-GJhHYlMhyT2gWemDL7BGMWfTNhspJKkikLKh9wAy3z4GTTINvTYALkUd+eGQK7aLeVkVzPuSA0VCT3H5eEWbbw== - dependencies: - "@noble/hashes" "^1.1.5" - -"@prisma/client@latest": - version "5.11.0" - resolved "https://registry.npmjs.org/@prisma/client/-/client-5.11.0.tgz" - integrity sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw== - -"@prisma/debug@5.11.0": - version "5.11.0" - resolved "https://registry.npmjs.org/@prisma/debug/-/debug-5.11.0.tgz" - integrity sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A== - -"@prisma/engines-version@5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102": - version "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" - resolved "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102.tgz" - integrity sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA== - -"@prisma/engines@5.11.0": - version "5.11.0" - resolved "https://registry.npmjs.org/@prisma/engines/-/engines-5.11.0.tgz" - integrity sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw== - dependencies: - "@prisma/debug" "5.11.0" - "@prisma/engines-version" "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" - "@prisma/fetch-engine" "5.11.0" - "@prisma/get-platform" "5.11.0" - -"@prisma/fetch-engine@5.11.0": - version "5.11.0" - resolved "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.11.0.tgz" - integrity sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w== - dependencies: - "@prisma/debug" "5.11.0" - "@prisma/engines-version" "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" - "@prisma/get-platform" "5.11.0" - -"@prisma/get-platform@5.11.0": - version "5.11.0" - resolved "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.11.0.tgz" - integrity sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw== - dependencies: - "@prisma/debug" "5.11.0" - -"@sapphire/async-queue@^1.1.9", "@sapphire/async-queue@^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@^3.8.1", "@sapphire/shapeshift@^3.9.3": - version "3.9.7" - resolved "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz" - integrity sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g== - dependencies: - fast-deep-equal "^3.1.3" - lodash "^4.17.21" - -"@sapphire/snowflake@3.5.1", "@sapphire/snowflake@^3.0.1", "@sapphire/snowflake@^3.5.1": - version "3.5.1" - resolved "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz" - integrity sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA== - -"@sindresorhus/is@^4.0.0": - version "4.6.0" - resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== - -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - -"@types/cacheable-request@^6.0.1": - version "6.0.3" - resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" - "@types/node" "*" - "@types/responselike" "^1.0.0" - -"@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== - -"@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" - -"@types/node@*", "@types/node@^17.0.42": - version "17.0.45" - resolved "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz" - integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== - -"@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/uuid@^9.0.1": - version "9.0.1" - resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz" - integrity sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA== - -"@types/ws@8.5.9", "@types/ws@^8.5.9": - version "8.5.9" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.9.tgz#384c489f99c83225a53f01ebc3eddf3b8e202a8c" - integrity sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg== - dependencies: - "@types/node" "*" - -"@typescript-eslint/eslint-plugin@^5.16.0": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz" - integrity sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/type-utils" "5.59.7" - "@typescript-eslint/utils" "5.59.7" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.16.0": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz" - integrity sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ== - dependencies: - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/typescript-estree" "5.59.7" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz" - integrity sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/visitor-keys" "5.59.7" - -"@typescript-eslint/type-utils@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz" - integrity sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.7" - "@typescript-eslint/utils" "5.59.7" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz" - integrity sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A== - -"@typescript-eslint/typescript-estree@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz" - integrity sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/visitor-keys" "5.59.7" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz" - integrity sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/typescript-estree" "5.59.7" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz" - integrity sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - eslint-visitor-keys "^3.3.0" - -"@vladfrangu/async_event_emitter@^2.2.2": - version "2.2.4" - resolved "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz" - integrity sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug== - -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.4.1, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -atomic-sleep@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" - integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -comment-parser@^1.1.2: - version "1.3.1" - resolved "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz" - integrity sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-env@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" - integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== - dependencies: - cross-spawn "^7.0.1" - -cross-spawn@^7.0.1, cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@^4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -defer-to-connect@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -discord-api-types@0.37.61, discord-api-types@^0.37.35: - version "0.37.61" - resolved "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz" - integrity sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw== - -discord-api-types@^0.26.1: - version "0.26.1" - resolved "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz" - integrity sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ== - -discord.js@^14.14.1: - version "14.14.1" - resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.14.1.tgz#9a2bea23bba13819705ab87612837610abce9ee3" - integrity sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w== - dependencies: - "@discordjs/builders" "^1.7.0" - "@discordjs/collection" "1.5.3" - "@discordjs/formatters" "^0.3.3" - "@discordjs/rest" "^2.1.0" - "@discordjs/util" "^1.0.2" - "@discordjs/ws" "^1.0.2" - "@sapphire/snowflake" "3.5.1" - "@types/ws" "8.5.9" - discord-api-types "0.37.61" - fast-deep-equal "3.1.3" - lodash.snakecase "4.1.1" - tslib "2.6.2" - undici "5.27.2" - ws "8.14.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -duplexify@^4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz" - integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== - dependencies: - end-of-stream "^1.4.1" - inherits "^2.0.3" - readable-stream "^3.1.1" - stream-shift "^1.0.0" - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-plugin-regexp@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.15.0.tgz" - integrity sha512-YEtQPfdudafU7RBIFci81R/Q1yErm0mVh3BkGnXD2Dk8DLwTFdc2ITYH1wCnHKim2gnHfPFgrkh+b2ozyyU7ag== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - comment-parser "^1.1.2" - grapheme-splitter "^1.0.4" - jsdoctypeparser "^9.0.0" - refa "^0.11.0" - regexp-ast-analysis "^0.6.0" - scslre "^0.2.0" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@^8.12.0: - version "8.41.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz" - integrity sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.41.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.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== - -fast-glob@^3.2.11, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-redact@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz" - integrity sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -form-data@^4.0.0: - 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" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -got@^11.8.3: - version "11.8.6" - resolved "https://registry.npmjs.org/got/-/got-11.8.6.tgz" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -hjson@^3.2.2: - version "3.2.2" - resolved "https://registry.npmjs.org/hjson/-/hjson-3.2.2.tgz" - integrity sha512-MkUeB0cTIlppeSsndgESkfFD21T2nXPRaBStLtf3cAYA2bVEFdXlodZB0TukwZiobPD1Ksax5DK4RTZeaXCI3Q== - -http-cache-semantics@^4.0.0: - version "4.1.1" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" - integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsdoctypeparser@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz" - integrity sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz" - integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== - dependencies: - json-buffer "3.0.1" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.snakecase@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== - -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -magic-bytes.js@^1.5.0: - version "1.10.0" - resolved "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz" - integrity sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -nekos.life@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/nekos.life/-/nekos.life-3.0.0.tgz" - integrity sha512-7LbvSqLtfK4XRA91nJaGOWthrNADmG7Vx9d54TC77Hx5qFvRCssFUaHraI6bZGjVENBCUaF7CreisoFX+8mnKQ== - -node-fetch@^2.6.5: - version "2.6.11" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== - dependencies: - whatwg-url "^5.0.0" - -nodemon@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz" - integrity sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA== - dependencies: - chokidar "^3.5.2" - debug "^4" - ignore-by-default "^1.0.1" - minimatch "^3.1.2" - pstree.remy "^1.1.8" - semver "^7.5.3" - simple-update-notifier "^2.0.0" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.5" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -on-exit-leak-free@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz" - integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-ms@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz" - integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pino-abstract-transport@v0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz" - integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== - dependencies: - duplexify "^4.1.2" - split2 "^4.0.0" - -pino-std-serializers@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz" - integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== - -pino@^7.9.2: - version "7.11.0" - resolved "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz" - integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== - dependencies: - atomic-sleep "^1.0.0" - fast-redact "^3.0.0" - on-exit-leak-free "^0.2.0" - pino-abstract-transport v0.5.0 - pino-std-serializers "^4.0.0" - process-warning "^1.0.0" - quick-format-unescaped "^4.0.3" - real-require "^0.1.0" - safe-stable-stringify "^2.1.0" - sonic-boom "^2.2.1" - thread-stream "^0.15.1" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -pretty-ms@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz" - integrity sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q== - dependencies: - parse-ms "^2.1.0" - -prisma@latest: - version "5.11.0" - resolved "https://registry.npmjs.org/prisma/-/prisma-5.11.0.tgz" - integrity sha512-KCLiug2cs0Je7kGkQBN9jDWoZ90ogE/kvZTUTgz2h94FEo8pczCkPH7fPNXkD1sGU7Yh65risGGD1HQ5DF3r3g== - dependencies: - "@prisma/engines" "5.11.0" - -process-warning@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz" - integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== - -pstree.remy@^1.1.8: - version "1.1.8" - resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-format-unescaped@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz" - integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== - -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - -readable-stream@^3.1.1: - 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" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -real-require@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/real-require/-/real-require-0.1.0.tgz" - integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== - -refa@^0.11.0: - version "0.11.0" - resolved "https://registry.npmjs.org/refa/-/refa-0.11.0.tgz" - integrity sha512-486O8/pQXwj9jV0mVvUnTsxq0uknpBnNJ0eCUhkZqJRQ8KutrT1PhzmumdCeM1hSBF2eMlFPmwECRER4IbKXlQ== - dependencies: - "@eslint-community/regexpp" "^4.5.0" - -regexp-ast-analysis@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.6.0.tgz" - integrity sha512-OLxjyjPkVH+rQlBLb1I/P/VTmamSjGkvN5PTV5BXP432k3uVz727J7H29GA5IFiY0m7e1xBN7049Wn59FY3DEQ== - dependencies: - "@eslint-community/regexpp" "^4.5.0" - refa "^0.11.0" - -resolve-alpn@^1.0.0: - version "1.2.1" - resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-stable-stringify@^2.1.0: - version "2.4.3" - resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== - -scslre@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/scslre/-/scslre-0.2.0.tgz" - integrity sha512-4hc49fUMmX3jM0XdFUAPBrs1xwEcdHa0KyjEsjFs+Zfc66mpFpq5YmRgDtl+Ffo6AtJIilfei+yKw8fUn3N88w== - dependencies: - "@eslint-community/regexpp" "^4.5.0" - refa "^0.11.0" - regexp-ast-analysis "^0.6.0" - -semver@^7.3.7, semver@^7.5.3: - version "7.6.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -simple-update-notifier@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz" - integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== - dependencies: - semver "^7.5.3" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -sonic-boom@^2.2.1: - version "2.8.0" - resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz" - integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== - dependencies: - atomic-sleep "^1.0.0" - -source-map-support@^0.5.21: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split2@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" - integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thread-stream@^0.15.1: - version "0.15.2" - resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz" - integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== - dependencies: - real-require "^0.1.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-mixer@^6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz" - integrity sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ== - -ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -ts-toolbelt@^9.6.0: - version "9.6.0" - resolved "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz" - integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== - -tsconfig-paths@^4.1.2: - version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@2.6.2, tslib@^2.3.1, tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -typescript-memoize@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/typescript-memoize/-/typescript-memoize-1.1.1.tgz" - integrity sha512-GQ90TcKpIH4XxYTI2F98yEQYZgjNMOGPpOgdjIBhaLaWji5HPWlRnZ4AeA1hfBxtY7bCGDJsqDDHk/KaHOl5bA== - -typescript@^4.9.5: - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -undefsafe@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz" - integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== - -undici@5.27.2: - version "5.27.2" - resolved "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz" - integrity sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ== - dependencies: - "@fastify/busboy" "^2.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" - integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.5" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@8.14.2, ws@^8.14.2: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yarn@^1.22.18: - version "1.22.19" - resolved "https://registry.npmjs.org/yarn/-/yarn-1.22.19.tgz" - integrity sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ== - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zod@^3.14.3: - version "3.22.4" - resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz" - integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==