From 81f8e0377c3b6d1a39b739f58da7f8f29bfb50c2 Mon Sep 17 00:00:00 2001 From: ITOH Date: Fri, 4 Feb 2022 15:00:04 +0100 Subject: [PATCH] style: move to `deno fmt` (#1992) * Create deno.json * run format * run format * ci: only check formatting * f * Update settings.json * Update settings.json --- .github/CONTRIBUTING.md | 28 ++- .github/ISSUE_TEMPLATE/bug_report.md | 3 +- .github/ISSUE_TEMPLATE/feature_request.md | 14 +- .github/workflows/format.yml | 18 ++ .github/workflows/prettier.yml | 29 --- .vscode/settings.json | 2 +- README.md | 83 +++++--- deno.json | 10 + plugins/cache/README.md | 7 +- plugins/cache/mod.ts | 15 +- plugins/cache/src/setupCacheEdits.ts | 10 +- plugins/cache/src/setupCacheRemovals.ts | 10 +- plugins/fileloader/README.md | 2 +- plugins/fileloader/mod.ts | 34 ++-- plugins/helpers/README.md | 2 +- plugins/helpers/mod.ts | 51 ++--- plugins/helpers/src/channels.ts | 7 +- plugins/helpers/src/getMembersPaginated.ts | 26 ++- plugins/helpers/src/moveMember.ts | 2 +- .../helpers/src/sendAutoCompleteChoices.ts | 8 +- plugins/helpers/src/sendDirectMessage.ts | 2 +- plugins/helpers/src/threads.ts | 2 +- plugins/permissions/README.md | 6 +- plugins/permissions/src/channels/mod.ts | 20 +- plugins/permissions/src/channels/stage.ts | 2 +- .../channels/threads/getArchivedThreads.ts | 4 +- .../permissions/src/channels/threads/mod.ts | 14 +- plugins/permissions/src/components.ts | 11 +- .../permissions/src/connectToVoiceChannels.ts | 10 +- plugins/permissions/src/editMember.ts | 5 +- plugins/permissions/src/emojis.ts | 2 +- plugins/permissions/src/guilds/editGuild.ts | 2 +- plugins/permissions/src/guilds/events.ts | 5 +- plugins/permissions/src/messages/create.ts | 7 +- plugins/permissions/src/permissions.ts | 40 ++-- site/babel.config.js | 2 +- site/docs/big-bot-guide/_category_.json | 6 +- site/docs/big-bot-guide/cache.md | 45 +++-- site/docs/big-bot-guide/events.md | 125 +++++++----- site/docs/big-bot-guide/gateway.md | 155 ++++++++------- site/docs/big-bot-guide/rest.md | 52 ++--- site/docs/big-bot-guide/step-by-step.md | 29 +-- site/docs/general/_category_.json | 6 +- .../general/frequently-asked-questions.md | 131 +++++-------- site/docs/general/getting-started.md | 45 ++--- site/docs/general/migrating.md | 108 ++++------- site/docs/intro.md | 21 +-- site/sidebars.js | 3 +- site/src/components/HomepageFeatures.tsx | 4 +- site/src/pages/index.tsx | 26 +-- src/bot.ts | 97 +++++----- src/handlers/channels/CHANNEL_DELETE.ts | 2 +- src/handlers/guilds/GUILD_BAN_REMOVE.ts | 2 +- .../integrations/INTEGRATION_CREATE.ts | 2 +- .../integrations/INTEGRATION_UPDATE.ts | 2 +- src/handlers/members/GUILD_MEMBERS_CHUNK.ts | 6 +- src/handlers/members/GUILD_MEMBER_UPDATE.ts | 2 +- src/handlers/misc/READY.ts | 2 +- src/handlers/roles/GUILD_ROLE_CREATE.ts | 2 +- src/handlers/roles/GUILD_ROLE_UPDATE.ts | 2 +- src/helpers/channels/createChannel.ts | 36 ++-- src/helpers/channels/deleteChannel.ts | 2 +- .../channels/deleteChannelOverwrite.ts | 2 +- src/helpers/channels/editChannel.ts | 12 +- src/helpers/channels/editChannelOverwrite.ts | 4 +- src/helpers/channels/followChannel.ts | 2 +- src/helpers/channels/getChannelWebhooks.ts | 2 +- src/helpers/channels/getChannels.ts | 2 +- src/helpers/channels/getStageInstance.ts | 2 +- src/helpers/channels/swapChannels.ts | 2 +- .../channels/threads/getActiveThreads.ts | 6 +- .../channels/threads/getArchivedThreads.ts | 20 +- .../channels/threads/getThreadMember.ts | 2 +- .../channels/threads/getThreadMembers.ts | 2 +- .../threads/startThreadWithMessage.ts | 4 +- .../threads/startThreadWithoutMessage.ts | 2 +- src/helpers/channels/updateStageInstance.ts | 2 +- src/helpers/channels/updateVoiceState.ts | 2 +- .../discovery/addDiscoverySubcategory.ts | 2 +- src/helpers/discovery/editDiscovery.ts | 2 +- src/helpers/discovery/getDiscovery.ts | 2 +- .../discovery/getDiscoveryCategories.ts | 4 +- .../discovery/removeDiscoverySubcategory.ts | 2 +- src/helpers/discovery/validDiscoveryTerm.ts | 2 +- src/helpers/emojis/getEmoji.ts | 2 +- src/helpers/guilds/editGuild.ts | 2 +- src/helpers/guilds/editWelcomeScreen.ts | 2 +- src/helpers/guilds/editWidget.ts | 13 +- src/helpers/guilds/getAuditLogs.ts | 16 +- .../guilds/getAvailableVoiceRegions.ts | 2 +- src/helpers/guilds/getBans.ts | 2 +- src/helpers/guilds/getGuild.ts | 4 +- src/helpers/guilds/getGuildPreview.ts | 2 +- src/helpers/guilds/getPruneCount.ts | 8 +- src/helpers/guilds/getVanityUrl.ts | 2 +- src/helpers/guilds/getVoiceRegions.ts | 4 +- src/helpers/guilds/getWelcomeScreen.ts | 2 +- src/helpers/guilds/getWidget.ts | 2 +- src/helpers/guilds/guildBannerUrl.ts | 16 +- src/helpers/guilds/guildIconUrl.ts | 16 +- src/helpers/guilds/guildSplashUrl.ts | 16 +- .../scheduledEvents/createScheduledEvent.ts | 14 +- .../scheduledEvents/deleteScheduledEvent.ts | 2 +- .../scheduledEvents/editScheduledEvent.ts | 13 +- .../scheduledEvents/getScheduledEvent.ts | 9 +- .../scheduledEvents/getScheduledEventUsers.ts | 12 +- .../scheduledEvents/getScheduledEvents.ts | 6 +- src/helpers/integrations/getIntegrations.ts | 4 +- .../batchEditApplicationCommandPermissions.ts | 4 +- .../commands/createApplicationCommand.ts | 2 +- .../commands/deleteApplicationCommand.ts | 2 +- .../commands/deleteInteractionResponse.ts | 2 +- .../editApplicationCommandPermissions.ts | 4 +- .../commands/editInteractionResponse.ts | 38 ++-- .../commands/getApplicationCommand.ts | 2 +- .../getApplicationCommandPermission.ts | 2 +- .../getApplicationCommandPermissions.ts | 4 +- .../commands/getApplicationCommands.ts | 4 +- .../commands/upsertApplicationCommand.ts | 4 +- .../commands/upsertApplicationCommands.ts | 6 +- .../followups/deleteFollowupMessage.ts | 2 +- .../followups/editFollowupMessage.ts | 33 ++-- .../followups/getFollowupMessage.ts | 2 +- .../getOriginalInteractionResponse.ts | 2 +- .../interactions/sendInteractionResponse.ts | 96 +++++----- src/helpers/interactions/verifySignature.ts | 2 +- src/helpers/invites/createInvite.ts | 2 +- src/helpers/invites/getChannelInvites.ts | 4 +- src/helpers/invites/getInvites.ts | 4 +- src/helpers/members/avatarUrl.ts | 16 +- src/helpers/members/banMember.ts | 8 +- src/helpers/members/editBotNickname.ts | 2 +- src/helpers/members/editMember.ts | 2 +- src/helpers/members/fetchMembers.ts | 2 +- src/helpers/members/getDmChannel.ts | 2 +- src/helpers/members/getMember.ts | 2 +- src/helpers/members/getMembers.ts | 4 +- src/helpers/members/pruneMembers.ts | 2 +- src/helpers/members/searchMembers.ts | 6 +- src/helpers/messages/addReaction.ts | 2 +- src/helpers/messages/addReactions.ts | 2 +- src/helpers/messages/deleteMessage.ts | 4 +- src/helpers/messages/editMessage.ts | 80 ++++---- src/helpers/messages/getMessage.ts | 2 +- src/helpers/messages/getMessages.ts | 4 +- src/helpers/messages/getReactions.ts | 4 +- src/helpers/messages/publishMessage.ts | 2 +- src/helpers/messages/removeAllReactions.ts | 2 +- src/helpers/messages/removeReaction.ts | 14 +- src/helpers/messages/removeReactionEmoji.ts | 2 +- src/helpers/messages/sendMessage.ts | 103 +++++----- src/helpers/misc/editBotStatus.ts | 30 +-- src/helpers/roles/addRole.ts | 2 +- src/helpers/roles/removeRole.ts | 2 +- .../templates/createGuildFromTemplate.ts | 2 +- src/helpers/templates/deleteGuildTemplate.ts | 2 +- src/helpers/templates/editGuildTemplate.ts | 2 +- src/helpers/templates/getGuildTemplates.ts | 2 +- src/helpers/templates/syncGuildTemplate.ts | 2 +- src/helpers/voice/connectToVoiceChannel.ts | 2 +- src/helpers/webhooks/createWebhook.ts | 2 +- src/helpers/webhooks/deleteWebhookMessage.ts | 2 +- src/helpers/webhooks/editWebhookMessage.ts | 38 ++-- src/helpers/webhooks/editWebhookWithToken.ts | 4 +- src/helpers/webhooks/getWebhookMessage.ts | 2 +- src/helpers/webhooks/sendWebhook.ts | 12 +- src/rest/README.md | 23 +-- src/rest/createRequestBody.ts | 2 +- src/rest/processGlobalQueue.ts | 11 +- src/rest/processQueue.ts | 32 ++-- src/rest/runMethod.ts | 12 +- src/transformers/applicationCommand.ts | 2 +- src/transformers/applicationCommandOption.ts | 2 +- .../applicationCommandPermission.ts | 2 +- src/transformers/auditlogEntry.ts | 178 +++++++++--------- src/transformers/channel.ts | 9 +- src/transformers/component.ts | 16 +- src/transformers/embed.ts | 54 +++--- src/transformers/guild.ts | 41 ++-- src/transformers/integration.ts | 14 +- src/transformers/interaction.ts | 52 ++--- src/transformers/invite.ts | 2 +- src/transformers/member.ts | 2 +- src/transformers/message.ts | 36 ++-- src/transformers/role.ts | 5 +- src/transformers/scheduledEvent.ts | 2 +- src/transformers/stageInstance.ts | 2 +- src/transformers/threadMember.ts | 2 +- src/transformers/voiceState.ts | 13 +- src/transformers/webhook.ts | 14 +- src/transformers/welcomeScreen.ts | 2 +- src/types/auditLog/auditLogChange.ts | 166 ++++++++-------- src/types/discordeno/errors.ts | 3 +- .../applicationCommandInteractionData.ts | 2 +- ...applicationCommandInteractionDataOption.ts | 2 +- .../commands/applicationCommandOptionTypes.ts | 2 +- src/types/messages/editMessage.ts | 10 +- src/types/util.ts | 123 +++++------- src/util/utils.ts | 2 +- src/ws/README.md | 60 +++--- src/ws/handleOnMessage.ts | 8 +- src/ws/heartbeat.ts | 4 +- src/ws/identify.ts | 4 +- src/ws/resharder.ts | 2 +- src/ws/resume.ts | 5 +- src/ws/sendShardMessage.ts | 2 +- src/ws/spawnShards.ts | 2 +- src/ws/tellWorkerToIdentify.ts | 2 +- template/README.md | 3 +- template/beginner/README.md | 3 +- template/bigbot/README.md | 64 +++---- tests/README.md | 24 +-- tests/channels/createChannel.ts | 18 +- tests/channels/stageInstances.ts | 12 +- tests/channels/threads.ts | 2 +- tests/deps.ts | 2 +- tests/emoji/emojiUrl.ts | 7 +- tests/guilds/urls.ts | 6 +- tests/helpers/channels/categoryChannels.ts | 2 +- tests/helpers/channels/createChannel.ts | 4 +- .../channels/deleteChannelOverwrite.ts | 4 +- tests/helpers/channels/editChannel.ts | 2 +- tests/helpers/guilds/createGuild.ts | 2 +- tests/helpers/guilds/editGuild.ts | 2 +- tests/helpers/guilds/getBan.ts | 2 +- tests/helpers/guilds/getGuild.ts | 2 +- tests/helpers/guilds/getVanityUrl.ts | 2 +- .../scheduledEvents/createScheduledEvent.ts | 26 ++- .../scheduledEvents/editScheduledEvent.ts | 5 +- tests/helpers/members/ban.ts | 5 - tests/helpers/messages/editMessage.ts | 4 +- tests/helpers/messages/getMessages.ts | 6 +- tests/helpers/messages/reactions.ts | 2 +- tests/helpers/misc/user.ts | 1 - .../slash/createApplicationCommand.ts | 4 +- tests/invite/getInvite.ts | 2 +- tests/members/avatarlUrl.ts | 20 +- tests/members/ban.ts | 24 +-- tests/members/getDmChannel.ts | 2 +- tests/members/getMember.ts | 4 +- tests/messages/reactions.ts | 4 +- tests/misc/editBotStatus.ts | 14 +- tests/misc/getUser.ts | 2 +- tests/misc/typing.ts | 8 +- tests/mod.ts | 6 +- tests/role/addRole.ts | 2 +- tests/role/editRole.ts | 2 +- tests/role/removeRole.ts | 2 +- .../createExternalEventWithEndtime.ts | 4 +- .../createExternalEventWithoutEndtime.ts | 4 +- .../createStageEventWithEndtime.ts | 4 +- .../createStageEventWithoutEndtime.ts | 4 +- .../createVoiceEventWithEndtime.ts | 4 +- .../createVoiceEventWithoutEndtime.ts | 4 +- tests/scheduledEvents/deleteEvent.ts | 2 +- tests/scheduledEvents/editEvent.ts | 2 +- tests/util/hash.ts | 2 +- tests/util/utils.ts | 2 +- tests/utils.ts | 2 +- 259 files changed, 1731 insertions(+), 1795 deletions(-) create mode 100644 .github/workflows/format.yml delete mode 100644 .github/workflows/prettier.yml create mode 100644 deno.json diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index f5c501831..e09123cf0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,12 +2,10 @@ - Read the [style guide](#style-guide). - Ask for help on the [official Discord server](https://discord.gg/ddeno) -- If you are going to work on an issue, mention so in the issue comments before - you start working on the issue. -- If you are going to work on a new feature, create an issue and discuss with - other contributors before you start working on the feature. -- Abide by and heed to - [Discord Developer Terms of Service](https://discord.com/developers/docs/legal) +- If you are going to work on an issue, mention so in the issue comments before you start working on the issue. +- If you are going to work on a new feature, create an issue and discuss with other contributors before you start + working on the feature. +- Abide by and heed to [Discord Developer Terms of Service](https://discord.com/developers/docs/legal) ## Submitting a Pull Request @@ -22,15 +20,14 @@ - File names shall use camel case. - Comply with [these guidelines for inclusive code](https://chromium.googlesource.com/chromium/src/+/master/styleguide/inclusive_code.md). -- An exported function must not have more than 4 individual parameters, the rest - arguments should be incorporated inside an object as a single parameter. -- Export all interfaces, types, and enums that are used for or inside an - exported entity. -- Every exported entity must be accompanied by a Typedoc (JSDoc without explicit - types) comment block. Ideally, we prefer single line comment block. +- An exported function must not have more than 4 individual parameters, the rest arguments should be incorporated inside + an object as a single parameter. +- Export all interfaces, types, and enums that are used for or inside an exported entity. +- Every exported entity must be accompanied by a Typedoc (JSDoc without explicit types) comment block. Ideally, we + prefer single line comment block. - Top-level functions should not use arrow syntax. -- Minimize dependencies (do not add a dependency unless it is absolutely - necessary and has been discussed on the Discord Server). +- Minimize dependencies (do not add a dependency unless it is absolutely necessary and has been discussed on the Discord + Server). - Do not make circular imports. - Utilize functional API wherever possible and avoid usage of ES6 classes. - Please follow the @@ -45,8 +42,7 @@ ## Types Guide - Must use camel case (same property name as in the docs just in camel case). -- Each field or property must be accompanied with a reasonable JSDoc comment - right above its type definition. +- Each field or property must be accompanied with a reasonable JSDoc comment right above its type definition. - Must be placed inside of the types module (in `src/types` directory). Example: diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd360fd1a..e8e7afc09 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -15,8 +15,7 @@ assignees: "" 3. Scroll down to '....' 4. See error -**Expected behavior** A clear and concise description of what you expected to -happen. +**Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index c707e157b..13412bb5c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -6,14 +6,12 @@ labels: feat assignees: "" --- -**Is your feature request related to a problem? Please describe.** A clear and -concise description of what the problem is. Ex. I'm always frustrated when [...] +**Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem +is. Ex. I'm always frustrated when [...] -**Describe the solution you'd like** A clear and concise description of what you -want to happen. +**Describe the solution you'd like** A clear and concise description of what you want to happen. -**Describe alternatives you've considered** A clear and concise description of -any alternative solutions or features you've considered. +**Describe alternatives you've considered** A clear and concise description of any alternative solutions or features +you've considered. -**Additional context** Add any other context or screenshots about the feature -request here. +**Additional context** Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 000000000..d0c803223 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,18 @@ +name: Check Formatting + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + deno: ["v1.x"] + steps: + - uses: actions/checkout@v2 + - uses: denoland/setup-deno@main + with: + deno-version: ${{ matrix.deno }} + - name: Check Formatting + run: deno fmt --check diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml deleted file mode 100644 index 463ba5f35..000000000 --- a/.github/workflows/prettier.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Prettier - -on: - push: - branches: - - main - -jobs: - prettier: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - # Make sure the actual branch is checked out when running on pull requests - ref: ${{ github.head_ref }} - # This is important to fetch the changes to the previous commit - fetch-depth: 0 - - - name: Prettify code - uses: creyD/prettier_action@v3.3 - with: - commit_message: "change: prettier code" - # This part is also where you can pass other options, for example: - prettier_options: --write **/* - only_changed: True - env: - GITHUB_TOKEN: ${{ github.token }} diff --git a/.vscode/settings.json b/.vscode/settings.json index 62f83064b..613a250b0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "deno.enable": true, "deno.lint": false, "deno.unstable": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "denoland.vscode-deno", "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.organizeImports": true, diff --git a/README.md b/README.md index f524cdcaa..50588fdb7 100644 --- a/README.md +++ b/README.md @@ -16,54 +16,80 @@ TODO: add coverage back when it is stable ## Features -- **Secure & stable**: Discordeno is actively maintained to ensure great - performance and convenience. -- **Simple, Efficient, & Lightweight**: Discordeno is simplistic, easy-to-use - and versatile while being efficient and lightweight. No caching by default. -- [**Functional API**](https://en.wikipedia.org/wiki/Functional_programming): - The functional API ensures overall concise yet performant code while removing - the difficulties of extending built-in classes and inheritance. +- **Secure & stable**: Discordeno is actively maintained to ensure great performance and convenience. +- **Simple, Efficient, & Lightweight**: Discordeno is simplistic, easy-to-use and versatile while being efficient and + lightweight. No caching by default. +- [**Functional API**](https://en.wikipedia.org/wiki/Functional_programming): The functional API ensures overall concise + yet performant code while removing the difficulties of extending built-in classes and inheritance. - **Cross Runtime**: Supports both Deno and Node.js runtimes. -- **Standalone REST, Gateway, Custom Cache & more**: Discordeno provides the ability to have almost every part of a bot as a standalone piece. -- **Plugins:** Designed to let you plugin and override any part of the code. Never deal with the headaches of maintaining your fork just to get something customized for your needs. You can use plugins for almost anything, for example we have a few official plugins. +- **Standalone REST, Gateway, Custom Cache & more**: Discordeno provides the ability to have almost every part of a bot + as a standalone piece. +- **Plugins:** Designed to let you plugin and override any part of the code. Never deal with the headaches of + maintaining your fork just to get something customized for your needs. You can use plugins for almost anything, for + example we have a few official plugins. - Cache plugin that enables caching everything. - Sweeper plugin that enables sweepers to clean the cache every once in a while. - - Permission plugin checks internally all missing permissions before forwarding a request to the Discord API so that the client does not get globally banned by Discord. -- **Flexibility:** If your bot does not need certain properties from objects then you can simply remove them. For example, if your bot does not need `Channel.topic` you should not have to store it. This can save you GBs of memory. Doing this for any property on any object is as simple as a few lines of code. + - Permission plugin checks internally all missing permissions before forwarding a request to the Discord API so that + the client does not get globally banned by Discord. +- **Flexibility:** If your bot does not need certain properties from objects then you can simply remove them. For + example, if your bot does not need `Channel.topic` you should not have to store it. This can save you GBs of memory. + Doing this for any property on any object is as simple as a few lines of code. ### REST - ✅ Freedom from Invalid Request 1 Hour Downtimes - - ✅ Discordeno will protect your bot from going down for an hour and will instead decrease the maximum downtime to 10 minutes. + - ✅ Discordeno will protect your bot from going down for an hour and will instead decrease the maximum downtime to 10 + minutes. - ✅ Freedom from global rate limit errors - - ✅ As your bot grows, you want to handle global rate limits better. Shards don't communicate fast enough to truly handle it properly so this allows 1 rest handler across the entire bot. + - ✅ As your bot grows, you want to handle global rate limits better. Shards don't communicate fast enough to truly + handle it properly so this allows 1 rest handler across the entire bot. - ✅ In fact, you can host multiple instances of your bot and all connect to the same rest server. - ✅ REST does not rest! - - ✅ Separate rest means if your bot for whatever reason crashes, your requests that are queued will still keep going and will not be lost. - - ✅ Seamless updates! When you want to update and reboot the bot, you could potentially lose tons of messages or responses that are in queue. Using this you could restart your bot without ever worrying about losing any responses. + - ✅ Separate rest means if your bot for whatever reason crashes, your requests that are queued will still keep going + and will not be lost. + - ✅ Seamless updates! When you want to update and reboot the bot, you could potentially lose tons of messages or + responses that are in queue. Using this you could restart your bot without ever worrying about losing any responses. - ✅ Single source of contact to Discord API - - ✅ This will allow you to make requests to discord from anywhere including a bot dashboard. You no longer need to have to communicate to your bot processes just to make a request or anything. Free up your bot process for processing bot events. + - ✅ This will allow you to make requests to discord from anywhere including a bot dashboard. You no longer need to + have to communicate to your bot processes just to make a request or anything. Free up your bot process for + processing bot events. - ✅ Scalability! Scalability! Scalability! ### Gateway - ✅ **Zero Downtime Updates:** - - ✅ Your bot can be updated in a matter of seconds. With normal sharding, you have to restart which also has to process identifying all your shards with a 1/~5s rate limit. With WS handling moved to a proxy process, this allows you to instantly get the bot code restarted without any concerns of delays. If you have a bot on 200,000 servers normally this would mean a 20 minute delay to restart your bot if you made a small change and restarted. + - ✅ Your bot can be updated in a matter of seconds. With normal sharding, you have to restart which also has to + process identifying all your shards with a 1/~5s rate limit. With WS handling moved to a proxy process, this allows + you to instantly get the bot code restarted without any concerns of delays. If you have a bot on 200,000 servers + normally this would mean a 20 minute delay to restart your bot if you made a small change and restarted. - ✅ **Zero Downtime Resharding:** - - ✅ Discord stops letting your bot get added to new servers at certain points in time. For example, suppose you had 150,000 servers running 150 shards. The maximum amount of servers your shards could hold is 150 \* 2500 = 375,000. If your bot reaches this, it can no longer join new servers until it re-shards. + - ✅ Discord stops letting your bot get added to new servers at certain points in time. For example, suppose you had + 150,000 servers running 150 shards. The maximum amount of servers your shards could hold is 150 \* 2500 = 375,000. + If your bot reaches this, it can no longer join new servers until it re-shards. - ✅ DD proxy provides 2 types of re-sharding. Automated and manual. You can also have both. - - ✅ Automated: This system will automatically begin a Zero-downtime resharding process behind the scenes when you reach 80% of your maximum servers allowed by your shards. For example, since 375,000 was the max, at 300,000 we would begin re-sharding behind the scenes with ZERO DOWNTIME. + - ✅ Automated: This system will automatically begin a Zero-downtime resharding process behind the scenes when you + reach 80% of your maximum servers allowed by your shards. For example, since 375,000 was the max, at 300,000 we + would begin re-sharding behind the scenes with ZERO DOWNTIME. - ✅ 80% of maximum servers reached (The % of 80% is customizable.) - ✅ Identify limits have room to allow re-sharding. (Also customizable) - ✅ Manual: You can also trigger this manually should you choose. - ✅ **Horizontal Scaling:** - - ✅ The proxy system allows you to scale the bot horizontally. When you reach a huge size, you can either keep spending more money to keep beefing up your server or you can buy several cheaper servers and scale horizontally. The proxy means you can have WS handling on a completely separate system. + - ✅ The proxy system allows you to scale the bot horizontally. When you reach a huge size, you can either keep + spending more money to keep beefing up your server or you can buy several cheaper servers and scale horizontally. + The proxy means you can have WS handling on a completely separate system. - ✅ **No Loss Restarts:** - - ✅ When you restart a bot without the proxy system, normally you would lose many events. Users may be using commands or messages are sent that will not be filtered. As your bot's grow this number rises dramatically. Users may join who wont get the auto-roles or any other actions your bot should take. With the proxy system, you can keep restarting your bot and never lose any events. Events will be put into a queue while your bot is down(max size of queue is customizable), once the bot is available the queue will begin processing all events. + - ✅ When you restart a bot without the proxy system, normally you would lose many events. Users may be using commands + or messages are sent that will not be filtered. As your bot's grow this number rises dramatically. Users may join + who wont get the auto-roles or any other actions your bot should take. With the proxy system, you can keep + restarting your bot and never lose any events. Events will be put into a queue while your bot is down(max size of + queue is customizable), once the bot is available the queue will begin processing all events. - ✅ **Controllers:** - - ✅ The controller aspect gives you full control over everything inside the proxy. You can provide a function to simply override the handler. For example, if you would like a certain function to do something different, instead of having to fork and maintain your fork, you can just provide a function to override. + - ✅ The controller aspect gives you full control over everything inside the proxy. You can provide a function to + simply override the handler. For example, if you would like a certain function to do something different, instead of + having to fork and maintain your fork, you can just provide a function to override. - ✅ **Clustering With Workers:** - - ✅ Take full advantage of all your CPU cores by using workers to spread the load. Control how many shards per worker and how many workers to maximize efficiency! + - ✅ Take full advantage of all your CPU cores by using workers to spread the load. Control how many shards per worker + and how many workers to maximize efficiency! ### Custom Cache @@ -102,12 +128,10 @@ await startBot(bot); ### Templates -Note to developers: don't worry, a lot of developers start out by building a -Discord bot as their first project, and it's not easy. Discordeno is designed -and built with all of the issues in mind that many developers have encountered -when they initially started writing Discord bots using existing libraries. If -you are a beginner, you can check out these awesome official and unofficial -templates: +Note to developers: don't worry, a lot of developers start out by building a Discord bot as their first project, and +it's not easy. Discordeno is designed and built with all of the issues in mind that many developers have encountered +when they initially started writing Discord bots using existing libraries. If you are a beginner, you can check out +these awesome official and unofficial templates: - [Discordeno Template (official)](https://github.com/discordeno/template) - [Serverless Slash Commands Template (official)](https://github.com/discordeno/serverless-deno-deploy-template) @@ -120,6 +144,7 @@ templates: - [Add Your Own!](https://github.com/discordeno/discordeno/pulls) ### Plugins + - [Cache Plugin](plugins/cache) - [Fileloader Plugin](plugins/fileloader) - [Helpers Plugin](plugins/helpers) diff --git a/deno.json b/deno.json new file mode 100644 index 000000000..093a7a48e --- /dev/null +++ b/deno.json @@ -0,0 +1,10 @@ +{ + "fmt": { + "files": { + "exclude": ["benchmarks/", "site/node_modules/", "site/build", "site/.docusaurus", "site/.cache-loader"] + }, + "options": { + "lineWidth": 120 + } + } +} diff --git a/plugins/cache/README.md b/plugins/cache/README.md index 994e34f77..b7b9d7112 100644 --- a/plugins/cache/README.md +++ b/plugins/cache/README.md @@ -1,9 +1,8 @@ # cache-plugin -This is an official plugin maintained by Discordeno. This plugin provides -automatic caching. Remember Discordeno does not cache by default. This plugin is -NOT recommended for big bot developers but this is useful for smaller bots who -just want simple functionality. +This is an official plugin maintained by Discordeno. This plugin provides automatic caching. Remember Discordeno does +not cache by default. This plugin is NOT recommended for big bot developers but this is useful for smaller bots who just +want simple functionality. ## Usage diff --git a/plugins/cache/mod.ts b/plugins/cache/mod.ts index 001920d2b..a371ca2b4 100644 --- a/plugins/cache/mod.ts +++ b/plugins/cache/mod.ts @@ -1,14 +1,6 @@ -import { - Bot, - Collection, - GuildEmojisUpdate, - SnakeCasedPropertiesDeep, -} from "./deps.ts"; +import { Bot, Collection, GuildEmojisUpdate, SnakeCasedPropertiesDeep } from "./deps.ts"; import { setupCacheRemovals } from "./src/setupCacheRemovals.ts"; -import { - addCacheCollections, - BotWithCache, -} from "./src/addCacheCollections.ts"; +import { addCacheCollections, BotWithCache } from "./src/addCacheCollections.ts"; import { setupCacheEdits } from "./src/setupCacheEdits.ts"; // PLUGINS MUST TAKE A BOT ARGUMENT WHICH WILL BE MODIFIED @@ -20,8 +12,7 @@ export function enableCachePlugin(rawBot: B): BotWithCache< const bot = addCacheCollections(rawBot); // Get the unmodified transformer. - const { guild, user, member, channel, message, presence, role } = - bot.transformers; + const { guild, user, member, channel, message, presence, role } = bot.transformers; // Override the transformer bot.transformers.guild = function (_, payload) { // Run the unmodified transformer diff --git a/plugins/cache/src/setupCacheEdits.ts b/plugins/cache/src/setupCacheEdits.ts index 0a1b50d35..a78486208 100644 --- a/plugins/cache/src/setupCacheEdits.ts +++ b/plugins/cache/src/setupCacheEdits.ts @@ -41,7 +41,7 @@ export function setupCacheEdits(bot: BotWithCache) { bot.handlers.MESSAGE_REACTION_ADD = function (_, data, shardId) { const payload = data.d as SnakeCasedPropertiesDeep; - const messageId = bot.transformers.snowflake(payload.message_id) + const messageId = bot.transformers.snowflake(payload.message_id); const message = bot.messages.get(messageId); const emoji = bot.transformers.emoji(bot, payload.emoji); @@ -71,12 +71,12 @@ export function setupCacheEdits(bot: BotWithCache) { } MESSAGE_REACTION_ADD(bot, data, shardId); - } + }; bot.handlers.MESSAGE_REACTION_REMOVE = function (_, data, shardId) { const payload = data.d as SnakeCasedPropertiesDeep; - const messageId = bot.transformers.snowflake(payload.message_id) + const messageId = bot.transformers.snowflake(payload.message_id); const message = bot.messages.get(messageId); const emoji = bot.transformers.emoji(bot, payload.emoji); @@ -102,7 +102,7 @@ export function setupCacheEdits(bot: BotWithCache) { } MESSAGE_REACTION_REMOVE(bot, data, shardId); - } + }; bot.handlers.MESSAGE_REACTION_REMOVE_ALL = function (_, data, shardId) { const payload = data.d as SnakeCasedPropertiesDeep; @@ -116,5 +116,5 @@ export function setupCacheEdits(bot: BotWithCache) { } MESSAGE_REACTION_REMOVE_ALL(bot, data, shardId); - } + }; } diff --git a/plugins/cache/src/setupCacheRemovals.ts b/plugins/cache/src/setupCacheRemovals.ts index 001ce5129..f49ba6ca8 100644 --- a/plugins/cache/src/setupCacheRemovals.ts +++ b/plugins/cache/src/setupCacheRemovals.ts @@ -1,5 +1,5 @@ import { -Bot, + Bot, Channel, Collection, GuildBanAddRemove, @@ -85,18 +85,14 @@ export function setupCacheRemovals(bot: BotWithCache) { bot.events.messageDelete(bot, { id, channelId: bot.transformers.snowflake(payload.channel_id), - guildId: payload.guild_id - ? bot.transformers.snowflake(payload.guild_id) - : undefined, + guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, }, message); bot.messages.delete(id); }; bot.handlers.MESSAGE_DELETE_BULK = function (_, data, shardId) { const payload = data.d as SnakeCasedPropertiesDeep; - payload.ids.forEach((id) => - bot.messages.delete(bot.transformers.snowflake(id)) - ); + payload.ids.forEach((id) => bot.messages.delete(bot.transformers.snowflake(id))); MESSAGE_DELETE_BULK(bot, data, shardId); }; diff --git a/plugins/fileloader/README.md b/plugins/fileloader/README.md index e863ee6a2..46d037d59 100644 --- a/plugins/fileloader/README.md +++ b/plugins/fileloader/README.md @@ -19,7 +19,7 @@ const bot = enableFileLoaderPlugin( console.log("Bot Ready"); }, }, - }) + }), ); bot.fastFileLoader([ diff --git a/plugins/fileloader/mod.ts b/plugins/fileloader/mod.ts index 4286658a3..eef8ad476 100644 --- a/plugins/fileloader/mod.ts +++ b/plugins/fileloader/mod.ts @@ -1,12 +1,12 @@ -import { Bot } from './deps.ts'; +import { Bot } from "./deps.ts"; // iMpOrTaNt to make sure files can be reloaded properly! export let uniqueFilePathCounter = 0; export let paths: string[] = []; -/** Recursively generates an array of unique paths to import using `fileLoader()` +/** Recursively generates an array of unique paths to import using `fileLoader()` * (**Is** windows compatible) -*/ + */ export async function importDirectory(path: string) { path = path.replaceAll("\\", "/"); const files = Deno.readDirSync(Deno.realPathSync(path)); @@ -18,9 +18,11 @@ export async function importDirectory(path: string) { if (file.isFile) { if (!currentPath.endsWith(".ts")) continue; paths.push( - `import "${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf("/"))}/${currentPath.substring( - currentPath.indexOf("src/") - )}#${uniqueFilePathCounter}";` + `import "${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf("/"))}/${ + currentPath.substring( + currentPath.indexOf("src/"), + ) + }#${uniqueFilePathCounter}";`, ); continue; } @@ -50,13 +52,13 @@ export async function fastFileLoader( */ between?: (path: string, uniqueFilePathCounter: number, paths: string[]) => void, /** A function that runs before **actually** importing all the files. */ - before?: (uniqueFilePathCounter: number, paths: string[]) => void + before?: (uniqueFilePathCounter: number, paths: string[]) => void, ) { await Promise.all( [...paths].map((path) => { if (between) between(path, uniqueFilePathCounter, paths); - importDirectory(path) - }) + importDirectory(path); + }), ); if (before) before(uniqueFilePathCounter, paths); @@ -66,12 +68,12 @@ export async function fastFileLoader( /** Extend the Bot with the Plugin's added functions */ export interface BotWithFileLoader extends Bot { - /** Recursively generates an array of unique paths to import using `fileLoader()` + /** Recursively generates an array of unique paths to import using `fileLoader()` * (**Is** windows compatible) - */ - importDirectory: (path: string) => void, + */ + importDirectory: (path: string) => void; /** Writes, then imports all everything in fileloader.ts */ - fileLoader: () => void, + fileLoader: () => void; /** This function will import the specified directories */ fastFileLoader: ( /** An array of directories to import recursively. */ @@ -81,8 +83,8 @@ export interface BotWithFileLoader extends Bot { */ between?: (path: string, uniqueFilePathCounter: number, paths: string[]) => void, /** A function that runs before **actually** importing all the files. */ - before?: (uniqueFilePathCounter: number, paths: string[]) => void - ) => void, + before?: (uniqueFilePathCounter: number, paths: string[]) => void, + ) => void; } /** Pass in a (compatible) bot instance, and get sweet file loader goodness. @@ -96,4 +98,4 @@ export function enableFileLoaderPlugin(rawBot: Bot): BotWithFileLoader { bot.fastFileLoader = fastFileLoader; return bot; -} \ No newline at end of file +} diff --git a/plugins/helpers/README.md b/plugins/helpers/README.md index e8c34b8ba..31b9125b4 100644 --- a/plugins/helpers/README.md +++ b/plugins/helpers/README.md @@ -1 +1 @@ -# helpers-plugin \ No newline at end of file +# helpers-plugin diff --git a/plugins/helpers/mod.ts b/plugins/helpers/mod.ts index c5ddf4741..e492c31ce 100644 --- a/plugins/helpers/mod.ts +++ b/plugins/helpers/mod.ts @@ -14,13 +14,7 @@ import { cloneChannel } from "./src/channels.ts"; import { sendAutocompleteChoices } from "./src/sendAutoCompleteChoices.ts"; import { sendDirectMessage } from "./src/sendDirectMessage.ts"; import { suppressEmbeds } from "./src/suppressEmbeds.ts"; -import { - archiveThread, - editThread, - lockThread, - unarchiveThread, - unlockThread, -} from "./src/threads.ts"; +import { archiveThread, editThread, lockThread, unarchiveThread, unlockThread } from "./src/threads.ts"; import { disconnectMember } from "./src/disconnectMember.ts"; import { getMembersPaginated } from "./src/getMembersPaginated.ts"; import { moveMember } from "./src/moveMember.ts"; @@ -29,11 +23,11 @@ export interface BotWithHelpersPlugin extends Bot { helpers: FinalHelpers & { sendDirectMessage: ( userId: bigint, - content: string | CreateMessage + content: string | CreateMessage, ) => Promise; suppressEmbeds: ( channelId: bigint, - messageId: bigint + messageId: bigint, ) => Promise; archiveThread: (threadId: bigint) => Promise; unarchiveThread: (threadId: bigint) => Promise; @@ -42,29 +36,29 @@ export interface BotWithHelpersPlugin extends Bot { editThread: ( threadId: bigint, options: ModifyThread, - reason?: string + reason?: string, ) => Promise; cloneChannel: ( channel: DiscordenoChannel, - reason?: string + reason?: string, ) => Promise; sendAutocompleteChoices: ( interactionId: bigint, interactionToken: string, - choices: ApplicationCommandOptionChoice[] + choices: ApplicationCommandOptionChoice[], ) => Promise; disconnectMember: ( guildId: bigint, - memberId: bigint + memberId: bigint, ) => Promise; getMembersPaginated: ( guildId: bigint, - options: ListGuildMembers & { memberCount: number } + options: ListGuildMembers & { memberCount: number }, ) => Promise>; moveMember: ( guildId: bigint, memberId: bigint, - channelId: bigint + channelId: bigint, ) => Promise; }; } @@ -74,38 +68,33 @@ export function enableHelpersPlugin(rawBot: Bot): BotWithHelpersPlugin { bot.helpers.sendDirectMessage = ( userId: bigint, - content: string | CreateMessage + content: string | CreateMessage, ) => sendDirectMessage(bot, userId, content); - bot.helpers.suppressEmbeds = (channelId: bigint, messageId: bigint) => - suppressEmbeds(bot, channelId, messageId); - bot.helpers.archiveThread = (threadId: bigint) => - archiveThread(bot, threadId); - bot.helpers.unarchiveThread = (threadId: bigint) => - unarchiveThread(bot, threadId); + bot.helpers.suppressEmbeds = (channelId: bigint, messageId: bigint) => suppressEmbeds(bot, channelId, messageId); + bot.helpers.archiveThread = (threadId: bigint) => archiveThread(bot, threadId); + bot.helpers.unarchiveThread = (threadId: bigint) => unarchiveThread(bot, threadId); bot.helpers.lockThread = (threadId: bigint) => lockThread(bot, threadId); bot.helpers.unlockThread = (threadId: bigint) => unlockThread(bot, threadId); bot.helpers.editThread = ( threadId: bigint, options: ModifyThread, - reason?: string + reason?: string, ) => editThread(bot, threadId, options, reason); - bot.helpers.cloneChannel = (channel: DiscordenoChannel, reason?: string) => - cloneChannel(bot, channel, reason); + bot.helpers.cloneChannel = (channel: DiscordenoChannel, reason?: string) => cloneChannel(bot, channel, reason); bot.helpers.sendAutocompleteChoices = ( interactionId: bigint, interactionToken: string, - choices: ApplicationCommandOptionChoice[] + choices: ApplicationCommandOptionChoice[], ) => sendAutocompleteChoices(bot, interactionId, interactionToken, choices); - bot.helpers.disconnectMember = (guildId: bigint, memberId: bigint) => - disconnectMember(bot, guildId, memberId); + bot.helpers.disconnectMember = (guildId: bigint, memberId: bigint) => disconnectMember(bot, guildId, memberId); bot.helpers.getMembersPaginated = ( guildId: bigint, - options: ListGuildMembers & { memberCount: number } + options: ListGuildMembers & { memberCount: number }, ) => getMembersPaginated(bot, guildId, options); bot.helpers.moveMember = ( guildId: bigint, memberId: bigint, - channelId: bigint + channelId: bigint, ) => moveMember(bot, guildId, memberId, channelId); return bot as BotWithHelpersPlugin; @@ -120,4 +109,4 @@ export * from "./src/sendAutoCompleteChoices.ts"; export * from "./src/sendDirectMessage.ts"; export * from "./src/suppressEmbeds.ts"; export * from "./src/threads.ts"; -export default enableHelpersPlugin; \ No newline at end of file +export default enableHelpersPlugin; diff --git a/plugins/helpers/src/channels.ts b/plugins/helpers/src/channels.ts index 47f1f93b4..5d55ea1fc 100644 --- a/plugins/helpers/src/channels.ts +++ b/plugins/helpers/src/channels.ts @@ -1,9 +1,4 @@ -import { - Bot, - CreateGuildChannel, - DiscordenoChannel, - separateOverwrites, -} from "../deps.ts"; +import { Bot, CreateGuildChannel, DiscordenoChannel, separateOverwrites } from "../deps.ts"; /** Create a copy of a channel */ export async function cloneChannel( diff --git a/plugins/helpers/src/getMembersPaginated.ts b/plugins/helpers/src/getMembersPaginated.ts index 769470fd1..7e7260c18 100644 --- a/plugins/helpers/src/getMembersPaginated.ts +++ b/plugins/helpers/src/getMembersPaginated.ts @@ -1,10 +1,4 @@ -import { - Bot, - Collection, - DiscordenoMember, - GuildMemberWithUser, - ListGuildMembers, -} from "../deps.ts"; +import { Bot, Collection, DiscordenoMember, GuildMemberWithUser, ListGuildMembers } from "../deps.ts"; /** * Highly recommended to **NOT** use this function to get members instead use fetchMembers(). @@ -14,7 +8,7 @@ import { export async function getMembersPaginated( bot: Bot, guildId: bigint, - options: ListGuildMembers & { memberCount: number } + options: ListGuildMembers & { memberCount: number }, ) { const members = new Collection(); @@ -28,18 +22,20 @@ export async function getMembersPaginated( if (options?.limit && options.limit > 1000) { console.log( - `Paginating get members from REST. #${loops} / ${Math.ceil( - (options?.limit ?? 1) / 1000 - )}` + `Paginating get members from REST. #${loops} / ${ + Math.ceil( + (options?.limit ?? 1) / 1000, + ) + }`, ); } const result = await bot.rest.runMethod( bot.rest, "get", - `${bot.constants.endpoints.GUILD_MEMBERS(guildId)}?limit=${ - membersLeft > 1000 ? 1000 : membersLeft - }${options?.after ? `&after=${options.after}` : ""}` + `${bot.constants.endpoints.GUILD_MEMBERS(guildId)}?limit=${membersLeft > 1000 ? 1000 : membersLeft}${ + options?.after ? `&after=${options.after}` : "" + }`, ); const discordenoMembers = result.map((member) => @@ -47,7 +43,7 @@ export async function getMembersPaginated( bot, member, guildId, - bot.transformers.snowflake(member.user.id) + bot.transformers.snowflake(member.user.id), ) ); diff --git a/plugins/helpers/src/moveMember.ts b/plugins/helpers/src/moveMember.ts index 9ac51d32a..493b28524 100644 --- a/plugins/helpers/src/moveMember.ts +++ b/plugins/helpers/src/moveMember.ts @@ -7,7 +7,7 @@ export function moveMember( bot: Bot, guildId: bigint, memberId: bigint, - channelId: bigint + channelId: bigint, ) { return bot.helpers.editMember(guildId, memberId, { channelId }); } diff --git a/plugins/helpers/src/sendAutoCompleteChoices.ts b/plugins/helpers/src/sendAutoCompleteChoices.ts index 5baf2ee6d..3d4461e1d 100644 --- a/plugins/helpers/src/sendAutoCompleteChoices.ts +++ b/plugins/helpers/src/sendAutoCompleteChoices.ts @@ -1,14 +1,10 @@ -import { - ApplicationCommandOptionChoice, - Bot, - InteractionResponseTypes, -} from "../deps.ts"; +import { ApplicationCommandOptionChoice, Bot, InteractionResponseTypes } from "../deps.ts"; export async function sendAutocompleteChoices( bot: Bot, interactionId: bigint, interactionToken: string, - choices: ApplicationCommandOptionChoice[] + choices: ApplicationCommandOptionChoice[], ): Promise { await bot.helpers.sendInteractionResponse(interactionId, interactionToken, { type: InteractionResponseTypes.ApplicationCommandAutocompleteResult, diff --git a/plugins/helpers/src/sendDirectMessage.ts b/plugins/helpers/src/sendDirectMessage.ts index 90221800d..529d3ee5a 100644 --- a/plugins/helpers/src/sendDirectMessage.ts +++ b/plugins/helpers/src/sendDirectMessage.ts @@ -10,7 +10,7 @@ export async function sendDirectMessage( content: string | CreateMessage, ) { if (typeof content === "string") content = { content }; - + // GET CHANNEL ID FROM CACHE OR CREATE THE CHANNEL FOR THIS USER const cachedChannelId = dmChannelIds.get(userId); // IF ID IS CACHED SEND MESSAGE DIRECTLY diff --git a/plugins/helpers/src/threads.ts b/plugins/helpers/src/threads.ts index 39b95bace..1655966ac 100644 --- a/plugins/helpers/src/threads.ts +++ b/plugins/helpers/src/threads.ts @@ -35,4 +35,4 @@ export async function editThread(bot: Bot, threadId: bigint, options: ModifyThre channel: result, guildId: result.guild_id ? bot.transformers.snowflake(result.guild_id) : undefined, }); -} \ No newline at end of file +} diff --git a/plugins/permissions/README.md b/plugins/permissions/README.md index 040eb09f4..25bcacc15 100644 --- a/plugins/permissions/README.md +++ b/plugins/permissions/README.md @@ -1,6 +1,9 @@ # permissions-plugin -This is an official plugin maintained by Discordeno. This plugin provides automatic permission checking and useful permission checking utility functions. Highly recommended to install this plugin for all users as you can use the utility functions. Enabling the permission plugin should not be done for big bot developers as it requires the cache plugin which will not work in a performance optimized fashion. This is designed mainly for the small beginner devs. +This is an official plugin maintained by Discordeno. This plugin provides automatic permission checking and useful +permission checking utility functions. Highly recommended to install this plugin for all users as you can use the +utility functions. Enabling the permission plugin should not be done for big bot developers as it requires the cache +plugin which will not work in a performance optimized fashion. This is designed mainly for the small beginner devs. ## Requirements @@ -22,4 +25,3 @@ enablePermissionPlugin(bot); // Start your bot await startBot(bot); ``` - diff --git a/plugins/permissions/src/channels/mod.ts b/plugins/permissions/src/channels/mod.ts index f02df1e21..992c3fec2 100644 --- a/plugins/permissions/src/channels/mod.ts +++ b/plugins/permissions/src/channels/mod.ts @@ -10,13 +10,13 @@ import getChannelWebhooks from "./getChannelWebhooks.ts"; import swapChannels from "./swapChannels.ts"; export default function setupChannelPermChecks(bot: BotWithCache) { - setupThreadPermChecks(bot); - setupStagePermChecks(bot); - deleteChannel(bot); - deleteChannelOverwrite(bot); - editChannel(bot); - editChannelOverwrite(bot); - followChannel(bot); - getChannelWebhooks(bot); - swapChannels(bot); -} \ No newline at end of file + setupThreadPermChecks(bot); + setupStagePermChecks(bot); + deleteChannel(bot); + deleteChannelOverwrite(bot); + editChannel(bot); + editChannelOverwrite(bot); + followChannel(bot); + getChannelWebhooks(bot); + swapChannels(bot); +} diff --git a/plugins/permissions/src/channels/stage.ts b/plugins/permissions/src/channels/stage.ts index db6b75b9b..9d8f2bba6 100644 --- a/plugins/permissions/src/channels/stage.ts +++ b/plugins/permissions/src/channels/stage.ts @@ -53,4 +53,4 @@ export default function setupStagePermChecks(bot: BotWithCache) { createStageInstance(bot); deleteStageInstance(bot); updateStageInstance(bot); -} \ No newline at end of file +} diff --git a/plugins/permissions/src/channels/threads/getArchivedThreads.ts b/plugins/permissions/src/channels/threads/getArchivedThreads.ts index 481e93dea..92e9db3e0 100644 --- a/plugins/permissions/src/channels/threads/getArchivedThreads.ts +++ b/plugins/permissions/src/channels/threads/getArchivedThreads.ts @@ -11,9 +11,7 @@ export default function getArchivedThreads(bot: BotWithCache) { await requireBotChannelPermissions( bot, channel, - options?.type === "private" - ? ["READ_MESSAGE_HISTORY", "MANAGE_THREADS"] - : ["READ_MESSAGE_HISTORY"], + options?.type === "private" ? ["READ_MESSAGE_HISTORY", "MANAGE_THREADS"] : ["READ_MESSAGE_HISTORY"], ); } diff --git a/plugins/permissions/src/channels/threads/mod.ts b/plugins/permissions/src/channels/threads/mod.ts index 1bf3e027f..8c338398a 100644 --- a/plugins/permissions/src/channels/threads/mod.ts +++ b/plugins/permissions/src/channels/threads/mod.ts @@ -7,10 +7,10 @@ import leaveThread from "./leaveThread.ts"; import removeThreadMember from "./removeThreadMember.ts"; export default function setupThreadPermChecks(bot: BotWithCache) { - addToThread(bot); - getArchivedThreads(bot); - getThreadMembers(bot); - joinThread(bot); - leaveThread(bot); - removeThreadMember(bot); -} \ No newline at end of file + addToThread(bot); + getArchivedThreads(bot); + getThreadMembers(bot); + joinThread(bot); + leaveThread(bot); + removeThreadMember(bot); +} diff --git a/plugins/permissions/src/components.ts b/plugins/permissions/src/components.ts index 81d58aa2c..a5c211a63 100644 --- a/plugins/permissions/src/components.ts +++ b/plugins/permissions/src/components.ts @@ -1,9 +1,4 @@ -import { - Bot, - ButtonStyles, - MessageComponents, - MessageComponentTypes, -} from "../deps.ts"; +import { Bot, ButtonStyles, MessageComponents, MessageComponentTypes } from "../deps.ts"; export function validateComponents(bot: Bot, components: MessageComponents) { if (!components?.length) return; @@ -20,9 +15,7 @@ export function validateComponents(bot: Bot, components: MessageComponents) { throw new Error("Too many components."); } else if ( component.components?.length > 1 && - component.components.some((subcomponent) => - subcomponent.type === MessageComponentTypes.SelectMenu - ) + component.components.some((subcomponent) => subcomponent.type === MessageComponentTypes.SelectMenu) ) { throw new Error("Select component must be alone."); } diff --git a/plugins/permissions/src/connectToVoiceChannels.ts b/plugins/permissions/src/connectToVoiceChannels.ts index 24deb6f23..7f9fbe016 100644 --- a/plugins/permissions/src/connectToVoiceChannels.ts +++ b/plugins/permissions/src/connectToVoiceChannels.ts @@ -7,17 +7,18 @@ export default function connectToVoiceChannel(bot: BotWithCache) { bot.helpers.connectToVoiceChannel = async function ( guildId, channelId, - options + options, ) { const channel = await bot.channels.get(channelId); if (!channel) throw new Error("CHANNEL_NOT_FOUND"); if ( [ChannelTypes.GuildStageVoice, ChannelTypes.GuildVoice].includes( - channel.type + channel.type, ) - ) + ) { throw new Error("INVALID_CHANNEL_TYPE"); + } const guild = channel?.guildId && bot.guilds.get(channel.guildId); if (!guild) throw new Error("GUILD_NOT_FOUND"); @@ -33,8 +34,9 @@ export default function connectToVoiceChannel(bot: BotWithCache) { channel.userLimit && guild.voiceStates.filter((vs) => vs.channelId === channelId).size >= channel.userLimit - ) + ) { permsNeeded.push("MANAGE_CHANNELS"); + } await requireBotChannelPermissions(bot, channel, permsNeeded); diff --git a/plugins/permissions/src/editMember.ts b/plugins/permissions/src/editMember.ts index 362ba0ce0..c54b8d8fc 100644 --- a/plugins/permissions/src/editMember.ts +++ b/plugins/permissions/src/editMember.ts @@ -1,8 +1,5 @@ import { BotWithCache, PermissionStrings } from "../deps.ts"; -import { - requireBotChannelPermissions, - requireBotGuildPermissions, -} from "./permissions.ts"; +import { requireBotChannelPermissions, requireBotGuildPermissions } from "./permissions.ts"; export default function editMember(bot: BotWithCache) { const editMemberOld = bot.helpers.editMember; diff --git a/plugins/permissions/src/emojis.ts b/plugins/permissions/src/emojis.ts index 853543577..e34f4880f 100644 --- a/plugins/permissions/src/emojis.ts +++ b/plugins/permissions/src/emojis.ts @@ -34,5 +34,5 @@ export function editEmoji(bot: BotWithCache) { export default function setupEmojiPermChecks(bot: BotWithCache) { createEmoji(bot); deleteEmoji(bot); - editEmoji(bot) + editEmoji(bot); } diff --git a/plugins/permissions/src/guilds/editGuild.ts b/plugins/permissions/src/guilds/editGuild.ts index bf1cb3f7a..da4cc419e 100644 --- a/plugins/permissions/src/guilds/editGuild.ts +++ b/plugins/permissions/src/guilds/editGuild.ts @@ -5,7 +5,7 @@ export default function editGuild(bot: BotWithCache) { const editGuildOld = bot.helpers.editGuild; bot.helpers.editGuild = function (guildId, options, shardId) { - requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]) + requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); return editGuildOld(guildId, options, shardId); }; diff --git a/plugins/permissions/src/guilds/events.ts b/plugins/permissions/src/guilds/events.ts index af1938c11..f4a39cc63 100644 --- a/plugins/permissions/src/guilds/events.ts +++ b/plugins/permissions/src/guilds/events.ts @@ -1,8 +1,5 @@ import { BotWithCache, ScheduledEventEntityType } from "../../deps.ts"; -import { - requireBotChannelPermissions, - requireBotGuildPermissions, -} from "../permissions.ts"; +import { requireBotChannelPermissions, requireBotGuildPermissions } from "../permissions.ts"; export function createScheduledEvent(bot: BotWithCache) { const createScheduledEventOld = bot.helpers.createScheduledEvent; diff --git a/plugins/permissions/src/messages/create.ts b/plugins/permissions/src/messages/create.ts index dfb2aefda..70b2021fa 100644 --- a/plugins/permissions/src/messages/create.ts +++ b/plugins/permissions/src/messages/create.ts @@ -1,9 +1,4 @@ -import { - AllowedMentionsTypes, - BotWithCache, - ChannelTypes, - PermissionStrings, -} from "../../deps.ts"; +import { AllowedMentionsTypes, BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts"; import { validateComponents } from "../components.ts"; import { requireBotChannelPermissions } from "../permissions.ts"; diff --git a/plugins/permissions/src/permissions.ts b/plugins/permissions/src/permissions.ts index f5a165f5b..840fcf609 100644 --- a/plugins/permissions/src/permissions.ts +++ b/plugins/permissions/src/permissions.ts @@ -17,12 +17,8 @@ export function calculateBasePermissions( guildOrId: bigint | DiscordenoGuild, memberOrId: bigint | DiscordenoMember, ) { - const guild = typeof guildOrId === "bigint" - ? bot.guilds.get(guildOrId) - : guildOrId; - const member = typeof memberOrId === "bigint" - ? bot.members.get(memberOrId) - : memberOrId; + const guild = typeof guildOrId === "bigint" ? bot.guilds.get(guildOrId) : guildOrId; + const member = typeof memberOrId === "bigint" ? bot.members.get(memberOrId) : memberOrId; if (!guild || !member) return 8n; @@ -49,16 +45,12 @@ export function calculateChannelOverwrites( channelOrId: bigint | DiscordenoChannel, memberOrId: bigint | DiscordenoMember, ) { - const channel = typeof channelOrId === "bigint" - ? bot.channels.get(channelOrId) - : channelOrId; + const channel = typeof channelOrId === "bigint" ? bot.channels.get(channelOrId) : channelOrId; // This is a DM channel so return ADMINISTRATOR permission if (!channel?.guildId) return 8n; - const member = typeof memberOrId === "bigint" - ? bot.members.get(memberOrId) - : memberOrId; + const member = typeof memberOrId === "bigint" ? bot.members.get(memberOrId) : memberOrId; if (!channel || !member) return 8n; @@ -192,9 +184,7 @@ export function missingPermissions( ) { if (permissionBits & 8n) return []; - return permissions.filter((permission) => - !(permissionBits & BigInt(BitwisePermissionFlags[permission])) - ); + return permissions.filter((permission) => !(permissionBits & BigInt(BitwisePermissionFlags[permission]))); } /** Get the missing Guild permissions this member has */ @@ -343,15 +333,12 @@ export function highestRole( guildOrId: bigint | DiscordenoGuild, memberOrId: bigint | DiscordenoMember, ) { - const guild = typeof guildOrId === "bigint" - ? bot.guilds.get(guildOrId) - : guildOrId; + const guild = typeof guildOrId === "bigint" ? bot.guilds.get(guildOrId) : guildOrId; if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); // Get the roles from the member - const memberRoles = - (typeof memberOrId === "bigint" ? bot.members.get(memberOrId) : memberOrId) - ?.roles; + const memberRoles = (typeof memberOrId === "bigint" ? bot.members.get(memberOrId) : memberOrId) + ?.roles; // This member has no roles so the highest one is the @everyone role if (!memberRoles) return guild.roles.get(guild.id)!; @@ -424,13 +411,12 @@ export function channelOverwriteHasPermission( guildId: bigint, id: bigint, overwrites: bigint[], - permissions: PermissionStrings[] + permissions: PermissionStrings[], ) { - const overwrite = - overwrites.find((perm) => { - const [_, bitID] = separateOverwrites(perm); - return id === bitID; - }) || + const overwrite = overwrites.find((perm) => { + const [_, bitID] = separateOverwrites(perm); + return id === bitID; + }) || overwrites.find((perm) => { const [_, bitID] = separateOverwrites(perm); return bitID === guildId; diff --git a/site/babel.config.js b/site/babel.config.js index e00595dae..bfd75dbdf 100644 --- a/site/babel.config.js +++ b/site/babel.config.js @@ -1,3 +1,3 @@ module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], + presets: [require.resolve("@docusaurus/core/lib/babel/preset")], }; diff --git a/site/docs/big-bot-guide/_category_.json b/site/docs/big-bot-guide/_category_.json index 2713ece3f..3ff52b832 100644 --- a/site/docs/big-bot-guide/_category_.json +++ b/site/docs/big-bot-guide/_category_.json @@ -1,4 +1,4 @@ { - "label": "Big Bot Guide", - "position": 2 -} \ No newline at end of file + "label": "Big Bot Guide", + "position": 2 +} diff --git a/site/docs/big-bot-guide/cache.md b/site/docs/big-bot-guide/cache.md index 9abda1612..99c8f8aca 100644 --- a/site/docs/big-bot-guide/cache.md +++ b/site/docs/big-bot-guide/cache.md @@ -5,28 +5,42 @@ sidebar_label: Step 3 - Cache # Step 3: Standalone Cache Process -The next part of this is going to be about making a standalone cache process. By now, you should have both a REST and a Gateway process ready. Before, we start handling events we should build a Cache handler. +The next part of this is going to be about making a standalone cache process. By now, you should have both a REST and a +Gateway process ready. Before, we start handling events we should build a Cache handler. ## Why Use Standalone Cache Process? -A standalone cache process allows you to retain cached data even after bot restarts. For example, if you are caching member roles to track when a role was added or removed, you may want to cache the members. The question then comes to play, when deciding where to keep your cache. Another reason to use this is, whether or not you are using a standalone gateway process. +A standalone cache process allows you to retain cached data even after bot restarts. For example, if you are caching +member roles to track when a role was added or removed, you may want to cache the members. The question then comes to +play, when deciding where to keep your cache. Another reason to use this is, whether or not you are using a standalone +gateway process. - Start rest process - Start event handler process(bot) - Start gateway process. - - Guild create events arrive providing all the data needed to cache in the bot process. + - Guild create events arrive providing all the data needed to cache in the bot process. - Restart event handler process(maybe for an update/reboot) - - You lost all guilds/channels/permissions etc and can not get them again without restarting gateway. This defeats the entire point of the standalone gateway. + - You lost all guilds/channels/permissions etc and can not get them again without restarting gateway. This defeats the + entire point of the standalone gateway. -If your cache is tied to the bot processes which is not tied to the gateway you lose all this info. The next thought is to just keep the Cache entirely in the gateway process however, I do not like this personally however, should you desire this you can do this as well. The reason I prefer not to do this is when your bot needs to make requests to your cache, you do not want it occupying the thread for processing other gateway events arriving from discord. A separate cache process makes it so it uses an entirely separate thread and will not slow down anything else. +If your cache is tied to the bot processes which is not tied to the gateway you lose all this info. The next thought is +to just keep the Cache entirely in the gateway process however, I do not like this personally however, should you desire +this you can do this as well. The reason I prefer not to do this is when your bot needs to make requests to your cache, +you do not want it occupying the thread for processing other gateway events arriving from discord. A separate cache +process makes it so it uses an entirely separate thread and will not slow down anything else. ## Understand Cache Types -When I use the term cache process, this is interchangeable with any similar term such as "custom cache", "redis cache", "pgsql cache", etc... The fact is you can keep this "cache" anywhere. For this guide, we will implement a very simple cache using pgsql. Feel free to modify this any way you like as advanced as you like. The point is Discordeno cache is flexible enough to let you use anything for your Cache storage. +When I use the term cache process, this is interchangeable with any similar term such as "custom cache", "redis cache", +"pgsql cache", etc... The fact is you can keep this "cache" anywhere. For this guide, we will implement a very simple +cache using pgsql. Feel free to modify this any way you like as advanced as you like. The point is Discordeno cache is +flexible enough to let you use anything for your Cache storage. ## Setting Up The Cache -This step is for you to create the base schema for your cache. For example, if you want to implement a pgsql or redis cache perhaps you want to prepare the tables/schema. For this guide, we are just going to do a quick little hack to get a custom cache working. +This step is for you to create the base schema for your cache. For example, if you want to implement a pgsql or redis +cache perhaps you want to prepare the tables/schema. For this guide, we are just going to do a quick little hack to get +a custom cache working. Create a file in a path like `src/bot/cache/schema.sql` @@ -55,14 +69,16 @@ Cache Tables: Once you are finished continue forward, for the purpose of keeping this guide short we wont cover each table. -> You should also run this file to prepare your pgsql and have your pgsql database running by now. Or whatever, cache service you use. +> You should also run this file to prepare your pgsql and have your pgsql database running by now. Or whatever, cache +> service you use. ### Cache Handler -Now we will initiate our cache service. This may be different for you based on your choice of cache type. Since we are using PGSQL for our cache layer, we will now instantiate it. +Now we will initiate our cache service. This may be different for you based on your choice of cache type. Since we are +using PGSQL for our cache layer, we will now instantiate it. ```ts -import { postgres } from '../../../deps.ts' +import { postgres } from "../../../deps.ts"; // YOU CUSTOM PGSQL INFO GOES HERE const DATABASE_USERNAME = ""; @@ -85,16 +101,17 @@ export const psql = postgres({ types: { bigint: postgres.BigInt, }, -}) +}); ``` -To use the PGSQL driver we are using in this guide you can insert this into your `deps.ts`. +To use the PGSQL driver we are using in this guide you can insert this into your `deps.ts`. ```ts // @deno-types="https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/types/index.d.ts" export { default as postgres } from "https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/deno/lib/index.js"; ``` -> Note: Remember you can use any driver you like. For deno users we prefer to use this library for PGSQL because it is more stable and more performant. +> Note: Remember you can use any driver you like. For deno users we prefer to use this library for PGSQL because it is +> more stable and more performant. -Now that the cache layer is ready, we can proceed to begin creating our bot. \ No newline at end of file +Now that the cache layer is ready, we can proceed to begin creating our bot. diff --git a/site/docs/big-bot-guide/events.md b/site/docs/big-bot-guide/events.md index 7572745a6..1610e492c 100644 --- a/site/docs/big-bot-guide/events.md +++ b/site/docs/big-bot-guide/events.md @@ -5,13 +5,19 @@ sidebar_label: Step 4 - Event Handler # Step 4: Creating Standalone Event Handler -Now we are about to start working on the bot code itself. The last 3 steps should be completed by the time you reach this. The event handler process will be listening for events from any number of gateway instances and be ready to handle them. +Now we are about to start working on the bot code itself. The last 3 steps should be completed by the time you reach +this. The event handler process will be listening for events from any number of gateway instances and be ready to handle +them. -In this guide, we may use the term `Bot` or the term `event handler`, remember that these refer to the same thing. This is your main bot code. +In this guide, we may use the term `Bot` or the term `event handler`, remember that these refer to the same thing. This +is your main bot code. ## Why Use Standalone Event Handler Process? -The standalone event handler is the portion of your bot code that you will be changing the most. The three previous steps created processes that are intended to never be turned off. This process is designed to let you restart whenever you wish and be incredibly quick to restart. Since we don't have the delay to start up shards anymore, your code becomes reloaded instantly. +The standalone event handler is the portion of your bot code that you will be changing the most. The three previous +steps created processes that are intended to never be turned off. This process is designed to let you restart whenever +you wish and be incredibly quick to restart. Since we don't have the delay to start up shards anymore, your code becomes +reloaded instantly. ## Creating Event Handlers @@ -19,7 +25,7 @@ Create a file path like `src/bot/mod.ts`. ```ts import { DISCORD_TOKEN } from "../../configs.ts"; -import { createBot, Collection } from "../../deps.ts"; +import { Collection, createBot } from "../../deps.ts"; import { psql } from "./cache/mod.ts"; export const bot = createBot({ @@ -28,13 +34,13 @@ export const bot = createBot({ // applicationId: 270010330782892032, intents: ["Guilds", "GuildMessages"], events: { - messageCreate: function(bot, message) { + messageCreate: function (bot, message) { console.log("message arrived"); }, }, cache: { isAsync: true, - customTableCreator: function(table) { + customTableCreator: function (table) { const tables = { users: "users", channels: "channels", @@ -51,9 +57,11 @@ export const bot = createBot({ return { /** Get a single item from the table */ async get(key) { - return await psql`SELECT * FROM ${psql( - tables[table] - )} WHERE "id" = ${psql.types.bigint(key)}`; + return await psql`SELECT * FROM ${ + psql( + tables[table], + ) + } WHERE "id" = ${psql.types.bigint(key)}`; }, /** Completely empty this table. */ async clear() { @@ -61,17 +69,21 @@ export const bot = createBot({ }, /** Delete the data related to this key from table. */ async delete(key) { - await psql`DELETE FROM ${psql( - tables[table] - )} WHERE "id" = ${psql.types.bigint(key)}`; + await psql`DELETE FROM ${ + psql( + tables[table], + ) + } WHERE "id" = ${psql.types.bigint(key)}`; return true; }, /** Check if there is data assigned to this key. */ async has(key) { return Boolean( - await psql`SELECT 1 FROM ${psql( - tables[table] - )} WHERE "id" = ${psql.types.bigint(key)}` + await psql`SELECT 1 FROM ${ + psql( + tables[table], + ) + } WHERE "id" = ${psql.types.bigint(key)}`, ); }, /** Check how many items are stored in this table. */ @@ -81,10 +93,12 @@ export const bot = createBot({ }, /** Store new data to this table. */ async set(key, data) { - await psql`INSERT INTO ${psql(tables[table])} ${psql( - data, - ...Object.keys(data) - )}`; + await psql`INSERT INTO ${psql(tables[table])} ${ + psql( + data, + ...Object.keys(data), + ) + }`; return true; }, // THESE TWO ARE USELESS FOR CUSTOM CACHE BUT NEED TO SHUT UP TS ERRORS @@ -105,15 +119,23 @@ Alright that was a lot of code. Now let's break it down little by little. **Basic Keys** - `token` if you can't figure this out stop reading and find another guide please. Thanks. -- `botId` This is going to be your bot id. The reason we require this here is because we are going to set up a standalone gateway process. With most other libs, they can fill this information using the READY event. However, since our gateway is designed not to reboot, we are not going to get the READY event whenever we restart our bot. This means we won't be able to fill this information later. Another method to get the id is to use the `token` but discord developers have mentioned that this behavior is not documented and not supposed to be relied on to remain stable. Due to these reasons, we chose to just require the bot id be passed here. +- `botId` This is going to be your bot id. The reason we require this here is because we are going to set up a + standalone gateway process. With most other libs, they can fill this information using the READY event. However, since + our gateway is designed not to reboot, we are not going to get the READY event whenever we restart our bot. This means + we won't be able to fill this information later. Another method to get the id is to use the `token` but discord + developers have mentioned that this behavior is not documented and not supposed to be relied on to remain stable. Due + to these reasons, we chose to just require the bot id be passed here. - `applicationId` is an optional choice if your bot is old and has a unique id different from it's bot id. - `intents`: Provide the intents you like using strings or a number. String form supports autocomplete and type safety. -- `events`: These are your event handler functions. When a MESSAGE_CREATE event arrives from Discord it will be processed here. We will set up the routing to run these functions later in the guide but for now you can see how to set it up. Note, you can create these functions in separate files and just import them here as you wish. +- `events`: These are your event handler functions. When a MESSAGE_CREATE event arrives from Discord it will be + processed here. We will set up the routing to run these functions later in the guide but for now you can see how to + set it up. Note, you can create these functions in separate files and just import them here as you wish. - `cache`: This is going to be the cache part. We will discuss this more below. ### Understanding Cache Option -Since we are using a standalone gateway a custom cache is essentially required as explained in step 3 of this guide. Please remember, to mark the cache as `async` +Since we are using a standalone gateway a custom cache is essentially required as explained in step 3 of this guide. +Please remember, to mark the cache as `async` ```ts cache: { @@ -121,7 +143,9 @@ cache: { } ``` -When you opt into the async cache, you must also provide a table creator function. This will not actually create any tables but it will create an object with methods to manage your "tables". Man we need a better name for this. Please send recommendations to @Skillz4Killz in discord. Thanks. Until then, please blame wolf for the terrible name. :) +When you opt into the async cache, you must also provide a table creator function. This will not actually create any +tables but it will create an object with methods to manage your "tables". Man we need a better name for this. Please +send recommendations to @Skillz4Killz in discord. Thanks. Until then, please blame wolf for the terrible name. :) Alrighty, now let's dig deeper into this function. @@ -140,7 +164,8 @@ const tables = { if (!tables[table]) throw new Error("I HACKED ITOH!"); ``` -This part of the code is only going to make sense if you are used to PGSQL. To prevent any attacks here we will forcibly control which table will be used. +This part of the code is only going to make sense if you are used to PGSQL. To prevent any attacks here we will forcibly +control which table will be used. This function must return an object with several methods on it. You can see the methods above. @@ -151,30 +176,38 @@ async get(key) { } ``` -You can insert any code you desire for your cache system here. Since we were using PGSQL, we used sql queries to make these requests. However, should you need to communicate to Redis or anything else of your choice, you can do so here. +You can insert any code you desire for your cache system here. Since we were using PGSQL, we used sql queries to make +these requests. However, should you need to communicate to Redis or anything else of your choice, you can do so here. -> Note: The .filter() and .forEach() methods are unnecessary and should not be used for your bot as they are not optimized for performance. These are made for smaller bot users who would not leave itoh alone and in order to please them itoh gave them their hearts desire! LMAO! +> Note: The .filter() and .forEach() methods are unnecessary and should not be used for your bot as they are not +> optimized for performance. These are made for smaller bot users who would not leave itoh alone and in order to please +> them itoh gave them their hearts desire! LMAO! ## Customizing Internal Code -One of the best parts about discordeno is the flexibility. In order to show this off, we will use the `user` example but you can apply this to any part of the library. +One of the best parts about discordeno is the flexibility. In order to show this off, we will use the `user` example but +you can apply this to any part of the library. ### Why Is Customizing Important? -At large scale, every single property can become expensive to store in your cache. For example, if your bot does not make use of a `channel.topic` why storing potentially millions of strings in your memory for something you never need/user. This could save you potentially GBs of memory to just remove this one property. +At large scale, every single property can become expensive to store in your cache. For example, if your bot does not +make use of a `channel.topic` why storing potentially millions of strings in your memory for something you never +need/user. This could save you potentially GBs of memory to just remove this one property. ### Customizing Process -First, let's create a file in some path like `src/bot/internals/mod.ts`. Note that we will create quite a few files below simply to keep code cleaner and simpler, in expectation that it will grow more complex later. You can merge them as you wish. +First, let's create a file in some path like `src/bot/internals/mod.ts`. Note that we will create quite a few files +below simply to keep code cleaner and simpler, in expectation that it will grow more complex later. You can merge them +as you wish. ```ts import { Bot } from "../../../deps.ts"; import { customizeBotTransformers } from "./transformers/mod.ts"; export function customizeBotInternals(bot: Bot) { - bot = customizeBotTransformers(bot); - // ADD AS MANY MORE CUSTOMIZATIONS HERE AS YOU LIKE TO HANDLERS, HELPERS, UTILS ETC... - return bot; + bot = customizeBotTransformers(bot); + // ADD AS MANY MORE CUSTOMIZATIONS HERE AS YOU LIKE TO HANDLERS, HELPERS, UTILS ETC... + return bot; } ``` @@ -182,19 +215,19 @@ We also need to add another file now at `src/bot/internals/transformers/mod.ts` ```ts import { Bot } from "../../../../deps.ts"; -import { customizeUserTransformer } from './user.ts' +import { customizeUserTransformer } from "./user.ts"; export function customizeBotTransformers(bot: Bot) { - bot = customizeUserTransformer(bot) + bot = customizeUserTransformer(bot); // ADD ANY MORE CUSTOM TRANSFORMERS HERE - return bot + return bot; } ``` One more file at `src/bot/internals/transformers/user.ts` ```ts -import { Bot, DiscordenoUser, transformUser } from '../../../../deps.ts' +import { Bot, DiscordenoUser, transformUser } from "../../../../deps.ts"; export function customizeUserTransformer(bot: Bot) { bot.transformers.user = function (bot, payload) { @@ -202,21 +235,27 @@ export function customizeUserTransformer(bot: Bot) { const { system, locale, verified, email, flags, mfaEnabled, premiumType, publicFlags, ...user } = transformUser( bot, payload, - ) + ); // RETURN ONLY USEFUL PROPS WE NEED TO USE AND CACHE IF NECESSARY - return user as DiscordenoUser - } + return user as DiscordenoUser; + }; return bot; } ``` -First we override the internal transformer for the `user` object. What's cool is the typings will be automatically provided :) Next, we use the `transformUser` function from the lib itself to make it create the internal user version. The reason I do this is so when I update the library and a new property is added or removed i can simply update and get it. Should you desire maximum control you can remove this entirely and only have what you want no matter what discord sends. Discordeno gives you the ability to stay in control. +First we override the internal transformer for the `user` object. What's cool is the typings will be automatically +provided :) Next, we use the `transformUser` function from the lib itself to make it create the internal user version. +The reason I do this is so when I update the library and a new property is added or removed i can simply update and get +it. Should you desire maximum control you can remove this entirely and only have what you want no matter what discord +sends. Discordeno gives you the ability to stay in control. -This method can be applied to any transformer, helper function, gateway event handler, util function or any part of the library. Anything and everything is possible to override. You do NOT need to fork and modify the library ever and give yourself a headache trying to maintain your fork with updates. +This method can be applied to any transformer, helper function, gateway event handler, util function or any part of the +library. Anything and everything is possible to override. You do NOT need to fork and modify the library ever and give +yourself a headache trying to maintain your fork with updates. ## Handling Incoming Gateway Events -Remember, this is a separate process we need to make sure we are listening to incoming events from our gateway instances. Since we used http in our Gateway step, we can create an http listener here as well. - +Remember, this is a separate process we need to make sure we are listening to incoming events from our gateway +instances. Since we used http in our Gateway step, we can create an http listener here as well. diff --git a/site/docs/big-bot-guide/gateway.md b/site/docs/big-bot-guide/gateway.md index 998f52c4f..a9fe2b762 100644 --- a/site/docs/big-bot-guide/gateway.md +++ b/site/docs/big-bot-guide/gateway.md @@ -5,7 +5,8 @@ sidebar_label: Step 2 - Gateway # Step 2: Creating A Standalone Gateway Process -If you are reading this, you should have your REST process completed. We are going to need it here. This process will be connecting to discord's websockets which will send you all the events. +If you are reading this, you should have your REST process completed. We are going to need it here. This process will be +connecting to discord's websockets which will send you all the events. Before, we dive into how, here is a quick summary of why you will want a standalone gateway process. @@ -13,63 +14,51 @@ Before, we dive into how, here is a quick summary of why you will want a standal - **Zero Downtime Updates**: - - Your bot can be updated in a matter of seconds. With normal sharding, you - have to restart which also has to process identifying all your shards with a - 1/~5s rate limit. With WS handling moved to a proxy process, this allows you - to instantly get the bot code restarted without any concerns of delays. If - you have a bot on 200,000 servers normally this would mean a 20 minute delay - to restart your bot if you made a small change and restarted. + - Your bot can be updated in a matter of seconds. With normal sharding, you have to restart which also has to process + identifying all your shards with a 1/~5s rate limit. With WS handling moved to a proxy process, this allows you to + instantly get the bot code restarted without any concerns of delays. If you have a bot on 200,000 servers normally + this would mean a 20 minute delay to restart your bot if you made a small change and restarted. - **Zero Downtime Resharding**: - - Discord stops letting your bot get added to new servers at certain points in - time. For example, suppose you had 150,000 servers running 150 shards. The - maximum amount of servers your shards could hold is 150 \* 2500 = 375,000. If - your bot reaches this, it can no longer join new servers until it re-shards. - - DD proxy provides 2 types of re-sharding. Automated and manual. You can also - have both. - - `Automated`: This system will automatically begin a Zero-downtime - resharding process behind the scenes when you reach 80% of your maximum - servers allowed by your shards. For example, since 375,000 was the max, at - 300,000 we would begin re-sharding behind the scenes with `ZERO DOWNTIME`. + - Discord stops letting your bot get added to new servers at certain points in time. For example, suppose you had + 150,000 servers running 150 shards. The maximum amount of servers your shards could hold is 150 \* 2500 = 375,000. + If your bot reaches this, it can no longer join new servers until it re-shards. + - DD proxy provides 2 types of re-sharding. Automated and manual. You can also have both. + - `Automated`: This system will automatically begin a Zero-downtime resharding process behind the scenes when you + reach 80% of your maximum servers allowed by your shards. For example, since 375,000 was the max, at 300,000 we + would begin re-sharding behind the scenes with `ZERO DOWNTIME`. - 80% of maximum servers reached (The % of 80% is customizable.) - Identify limits have room to allow re-sharding. (Also customizable) - `Manual`: You can also trigger this manually should you choose. - **Horizontal Scaling**: - - The proxy system allows you to scale the bot horizontally. When you reach a - huge size, you can either keep spending more money to keep beefing up your - server or you can buy several cheaper servers and scale horizontally. The - proxy means you can have WS handling on a completely separate system. + - The proxy system allows you to scale the bot horizontally. When you reach a huge size, you can either keep spending + more money to keep beefing up your server or you can buy several cheaper servers and scale horizontally. The proxy + means you can have WS handling on a completely separate system. - **No Loss Restarts**: - - When you restart a bot without the proxy system, normally you would lose - many events. Users may be using commands or messages are sent that will not - be filtered. As your bot's grow this number rises dramatically. Users may - join who wont get the auto-roles or any other actions your bot should take. - With the proxy system, you can keep restarting your bot and never lose any - events. Events will be put into a queue while your bot is down(max size of - queue is customizable), once the bot is available the queue will begin - processing all events. + - When you restart a bot without the proxy system, normally you would lose many events. Users may be using commands or + messages are sent that will not be filtered. As your bot's grow this number rises dramatically. Users may join who + wont get the auto-roles or any other actions your bot should take. With the proxy system, you can keep restarting + your bot and never lose any events. Events will be put into a queue while your bot is down(max size of queue is + customizable), once the bot is available the queue will begin processing all events. - **Controllers**: - - The controller aspect gives you full control over everything inside the - proxy. You can provide a function to simply override the handler. For - example, if you would like a certain function to do something different, - instead of having to fork and maintain your fork, you can just provide a - function to override. + - The controller aspect gives you full control over everything inside the proxy. You can provide a function to simply + override the handler. For example, if you would like a certain function to do something different, instead of having + to fork and maintain your fork, you can just provide a function to override. - **Clustering With Workers**: - - Take full advantage of all your CPU cores by using workers to spread the - load. Control how many shards per worker and how many workers to maximize - efficiency! + - Take full advantage of all your CPU cores by using workers to spread the load. Control how many shards per worker + and how many workers to maximize efficiency! ## Creating Gateway Manager -Create a file under some path like `src/gateway/mod.ts`. +Create a file under some path like `src/gateway/mod.ts`. ```ts import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from "../../configs.ts"; @@ -82,13 +71,17 @@ const rest = createRestManager({ }); ``` -Throw another rest manager here which will be responsible for calling the main REST process we created in Step 1. This will allow your gateway to communicate to the other process. Remember this is just to communicate outwards, this file should not have the http listener. +Throw another rest manager here which will be responsible for calling the main REST process we created in Step 1. This +will allow your gateway to communicate to the other process. Remember this is just to communicate outwards, this file +should not have the http listener. -> Feel free to refactor and optimize this should you wish to move `const rest...` to a separate file and reuse in both steps. +> Feel free to refactor and optimize this should you wish to move `const rest...` to a separate file and reuse in both +> steps. ### Getting Gateway Bot Data -Now we need to use this rest manager to call the api to get information about how to connect to discord's gateway for your bot. +Now we need to use this rest manager to call the api to get information about how to connect to discord's gateway for +your bot. ```ts const rest = createRestManager({ @@ -98,7 +91,7 @@ const rest = createRestManager({ }); // CALL THE REST PROCESS TO GET GATEWAY DATA -const result = await rest.runMethod(rest, 'get', endpoints.GATEWAY_BOT).then((res) => ({ +const result = await rest.runMethod(rest, "get", endpoints.GATEWAY_BOT).then((res) => ({ url: res.url, shards: res.shards, sessionStartLimit: { @@ -118,7 +111,7 @@ With this info, we can now create our gateway manager. const gateway = createGatewayManager({ secretKey: EVENT_HANDLER_SECRET_KEY, token: DISCORD_TOKEN, - intents: ['GuildMessages', 'Guilds'], + intents: ["GuildMessages", "Guilds"], shardsRecommended: result.shards, sessionStartLimitTotal: result.sessionStartLimit.total, sessionStartLimitRemaining: result.sessionStartLimit.remaining, @@ -131,7 +124,7 @@ const gateway = createGatewayManager({ await fetch(`${EVENT_HANDLER_URL}:${EVENT_HANDLER_PORT}`, { headers: { Authorization: gateway.secretKey, - method: 'POST', + method: "POST", body: JSON.stringify({ shardId, data, @@ -140,61 +133,78 @@ const gateway = createGatewayManager({ }) // BELOW IS FOR SOLVING DENO MEMORY LEAK. Node users do your thing. .then((res) => res.text()) - .catch(() => null) + .catch(() => null); }, -}) +}); ``` - **Basic Keys** -- `EVENT_HANDLER_SECRET_KEY` is from your configs that will be used to make sure requests sent to your event handler process are indeed from you. +- `EVENT_HANDLER_SECRET_KEY` is from your configs that will be used to make sure requests sent to your event handler + process are indeed from you. - `DISCORD_TOKEN` if you can't figure this out, this guide isn't for you. Please find another. - `intents` pass in a number or a string of intents. Autocomplete/type-safety is provided for strings :) -**Discord Data Keys**: These keys will be the data you got from the gateway request we made earlier. +**Discord Data Keys**: These keys will be the data you got from the gateway request we made earlier. + - `shardsRecommended` -- `sessionStartLimitTotal` +- `sessionStartLimitTotal` - `sessionStartLimitRemaining` - `sessionStartLimitResetAfter` - `maxConcurrency` **Powerful Keys** -If your bot is going to be run on one process, you can re-use the data that discord gave you to connect. +If your bot is going to be run on one process, you can re-use the data that discord gave you to connect. -- `maxShards`: is the maximum number of shards you want to use for connecting your bot. Should you think Discord is not smart enough to recommend a good amount, use this to override their choice. Highly recommend just using theirs. +- `maxShards`: is the maximum number of shards you want to use for connecting your bot. Should you think Discord is not + smart enough to recommend a good amount, use this to override their choice. Highly recommend just using theirs. - `lastShardId`: is the last shard you want to connect in this process. - - Using a combination of `lastShardId` & `firstShardId`, you can create several processes or even several servers to handle different amounts of shards should your bot get that big to require horizontal scaling. You can control how many shards each gateway manager will be responsible for. -- `reshard`: Whether or not to automatically reshard the bot when necessary with zero downtime deployment strategy. Default: true. + - Using a combination of `lastShardId` & `firstShardId`, you can create several processes or even several servers to + handle different amounts of shards should your bot get that big to require horizontal scaling. You can control how + many shards each gateway manager will be responsible for. +- `reshard`: Whether or not to automatically reshard the bot when necessary with zero downtime deployment strategy. + Default: true. - `reshardPercentage`: The % of servers to trigger a reshard. Default: 80%. -- `spawnShardDelay`: The delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 2500. YOU DON"T WANT TO HIT THE RATE LIMIT!!! This is mainly if you are changing internals a lot and need to modify this behavior. -- `useOptimalLargeBotSharding`: Whether or not the resharder should automatically switch to LARGE BOT SHARDING when you are above 100K servers. +- `spawnShardDelay`: The delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 2500. YOU DON"T WANT + TO HIT THE RATE LIMIT!!! This is mainly if you are changing internals a lot and need to modify this behavior. +- `useOptimalLargeBotSharding`: Whether or not the resharder should automatically switch to LARGE BOT SHARDING when you + are above 100K servers. - `shardsPerCluster`: The amount of shards to load per worker. Discussed in detail below. - `maxClusters`: The maximum amount of workers to use for your bot. #### Gateway Cache -There is a few things that we cache in the gateway process directly, because sending them across the network is not ideal. This is done to support custom cache functionality. +There is a few things that we cache in the gateway process directly, because sending them across the network is not +ideal. This is done to support custom cache functionality. - `guildIds`: Used for determining what type of GUILD_CREATE event is received. - `loadingGuildIds`: Used for determining if all guilds have arrived when initially connecting. -- `editedMessages`: Used to prevent spam of events across the network. MESSAGE_UPDATE are an extremely heavy event. Any embed or link that is in a message will unfurl triggerring a message update event. This is undesired behavior for 99% of bots out there. If someone sends a message with 5 urls, in there you will get a MESSAGE_CREATE and 5 MESSAGE_UPDATE events. If that user edits a single letter on it you now get 6 MESSAGE_UPDATE events, 1 for the content change and 5 more for each url being unfurled. The editedMessages cache checks if the content of the message changed or not before sending the event downstream. Override this behavior if you need different behavior. +- `editedMessages`: Used to prevent spam of events across the network. MESSAGE_UPDATE are an extremely heavy event. Any + embed or link that is in a message will unfurl triggerring a message update event. This is undesired behavior for 99% + of bots out there. If someone sends a message with 5 urls, in there you will get a MESSAGE_CREATE and 5 MESSAGE_UPDATE + events. If that user edits a single letter on it you now get 6 MESSAGE_UPDATE events, 1 for the content change and 5 + more for each url being unfurled. The editedMessages cache checks if the content of the message changed or not before + sending the event downstream. Override this behavior if you need different behavior. #### Gateway Method Overriding -One of the benefits of Discordeno is that you can override/customize anything from the library. Should you desire to change the logic in any method it is as simple as: +One of the benefits of Discordeno is that you can override/customize anything from the library. Should you desire to +change the logic in any method it is as simple as: ```ts // TYPINGS WILL BE AUTOMATICALLY PROVIDED -gateway.heartbeat = function(gateway, shardId, interval) { - // YOUR CUSTOM HANDLING CODE HERE -} +gateway.heartbeat = function (gateway, shardId, interval) { + // YOUR CUSTOM HANDLING CODE HERE +}; ``` ### Handle Discord Payloads -One of the big things we didn't cover yet is the handler for discord payloads. This is the main sauce of your gateway process here. This is going to take the events that the gateway manager processed and send it to your event handler. How you wish to communicate with your event handler is up to you. For this guide, we will use http, but you can replace that with anything you like. +One of the big things we didn't cover yet is the handler for discord payloads. This is the main sauce of your gateway +process here. This is going to take the events that the gateway manager processed and send it to your event handler. How +you wish to communicate with your event handler is up to you. For this guide, we will use http, but you can replace that +with anything you like. ```ts handleDiscordPayload: async function (_, data, shardId) { @@ -215,27 +225,34 @@ handleDiscordPayload: async function (_, data, shardId) { }, ``` -You can change this function to use a WS or any form of communication you prefer to use to send this to your event handler. +You can change this function to use a WS or any form of communication you prefer to use to send this to your event +handler. ## Spawning Shards Once you are ready and the gateway has been created as you desired, we can begin spawning the shards. ```ts -gateway.spawnShards(gateway) +gateway.spawnShards(gateway); ``` ## Workers Now, we should take a minute here to talk about workers. Workers are just Clusters in Node.js -When you have a big bot and you are processing millions of events, you need to speed up that processing. Keeping it in 1 thread is not very nice since JavaScript is single threaded. This means it can only process 1 event at a time. With workers, you can make it process several events at the same time. We mentioned the `shardsPerCluster` earlier. This option was added to allow you to choose how many shards should be managed by each worker. +When you have a big bot and you are processing millions of events, you need to speed up that processing. Keeping it in 1 +thread is not very nice since JavaScript is single threaded. This means it can only process 1 event at a time. With +workers, you can make it process several events at the same time. We mentioned the `shardsPerCluster` earlier. This +option was added to allow you to choose how many shards should be managed by each worker. When shards are spawn they are triggered by a method on gateway. + ```ts -gateway.tellClusterToIdentify = async function(gateway, workerId, shardId, bucketId) { +gateway.tellClusterToIdentify = async function (gateway, workerId, shardId, bucketId) { await gateway.identify(gateway, shardId, gateway.maxShards); -} +}; ``` -You can choose to replace the handler with any desired functionality you like. For example, should should you want to create a new worker for each new workerId that appears and have that worker trigger the identify functionaly. How you choose to handler workers is left in your care. \ No newline at end of file +You can choose to replace the handler with any desired functionality you like. For example, should should you want to +create a new worker for each new workerId that appears and have that worker trigger the identify functionaly. How you +choose to handler workers is left in your care. diff --git a/site/docs/big-bot-guide/rest.md b/site/docs/big-bot-guide/rest.md index 7fee374c2..2c60bf3c2 100644 --- a/site/docs/big-bot-guide/rest.md +++ b/site/docs/big-bot-guide/rest.md @@ -5,7 +5,8 @@ sidebar_label: Step 1 - REST # Creating A Standalone REST Process -The first thing we want to make is our standalone REST process. This process will be used by almost every other process, so it is going to be the foundation of the bot. +The first thing we want to make is our standalone REST process. This process will be used by almost every other process, +so it is going to be the foundation of the bot. Before, we dive into how, here is a quick summary of why you will want a standalone REST process. @@ -13,19 +14,18 @@ Before, we dive into how, here is a quick summary of why you will want a standal - Easily host on any serverless infrastructure. - Freedom from global rate limit errors - - As your bot grows, you want to handle global rate limits better. Shards - don't communicate fast enough to truly handle it properly so this allows 1 - rest handler across the entire bot. - - In fact, you can host multiple instances of your bot and all connect to the - same rest server. + - As your bot grows, you want to handle global rate limits better. Shards don't communicate fast enough to truly + handle it properly so this allows 1 rest handler across the entire bot. + - In fact, you can host multiple instances of your bot and all connect to the same rest server. - REST does not rest! - - Separate rest means if your bot for whatever reason crashes, your requests - that are queued will still keep going and will not be lost. - - Seamless updates! When you want to update and reboot the bot, you could - potentially lose tons of messages or responses that are in queue. Using this - you could restart your bot without ever worrying about losing any responses. + - Separate rest means if your bot for whatever reason crashes, your requests that are queued will still keep going and + will not be lost. + - Seamless updates! When you want to update and reboot the bot, you could potentially lose tons of messages or + responses that are in queue. Using this you could restart your bot without ever worrying about losing any responses. - Single source of contact to Discord API - - This will allow you to make requests to discord from anywhere including a bot dashboard. You no longer need to have to communicate to your bot processes just to make a request or anything. Free up your bot process for processing bot events. + - This will allow you to make requests to discord from anywhere including a bot dashboard. You no longer need to have + to communicate to your bot processes just to make a request or anything. Free up your bot process for processing bot + events. - Scalability! Scalability! Scalability! ## Preparations @@ -55,20 +55,24 @@ const rest = createRestManager({ - `createRestManager` is imported from your deps file which should have exported everything from discordeno. - `DISCORD_TOKEN` is the bots token itself. -- `REST_AUTHORIZATION` is a special password you want to use to authenticate that requests being sent to your port are indeed from you. -- `customUrl` the url where this rest process will be running. This can be localhost which we are using in this guide if you want all processes on same VPS or separate them to different servers for horizontal scaling. `REST_PORT` is just the port where you want the process hosted. +- `REST_AUTHORIZATION` is a special password you want to use to authenticate that requests being sent to your port are + indeed from you. +- `customUrl` the url where this rest process will be running. This can be localhost which we are using in this guide if + you want all processes on same VPS or separate them to different servers for horizontal scaling. `REST_PORT` is just + the port where you want the process hosted. Now you have an entire Rest manager ready and waiting. Only thing you need now, is to listen for requests. ## Creating HTTP Listener -Since this is not a beginner guide, I am assuming you know already how to create a HTTP listener. There are enough guides on this out there. I will only cover the rough functionality. +Since this is not a beginner guide, I am assuming you know already how to create a HTTP listener. There are enough +guides on this out there. I will only cover the rough functionality. ```ts // START LISTENING TO THE URL(localhost) const server = Deno.listen({ port: REST_PORT }); console.info( - `HTTP webserver running. Access it at: http://localhost:${REST_PORT}/` + `HTTP webserver running. Access it at: http://localhost:${REST_PORT}/`, ); // Connections to the server will be yielded up as an async iterable. @@ -91,7 +95,7 @@ async function handleRequest(conn: Deno.Conn) { return requestEvent.respondWith( new Response(JSON.stringify({ error: "Invalid authorization key." }), { status: 401, - }) + }), ); } @@ -105,10 +109,12 @@ async function handleRequest(conn: Deno.Conn) { // USE THE SAME METHOD THAT CAME IN. IF DELETE CAME IN WE SEND DELETE OUT requestEvent.request.method as any, // OVERWRITE THE CUSTOM URL WITH DISCORDS BASE URL - `${BASE_URL}/v${rest.version}${requestEvent.request.url.substring( - rest.customUrl.length - )}`, - json + `${BASE_URL}/v${rest.version}${ + requestEvent.request.url.substring( + rest.customUrl.length, + ) + }`, + json, ); // RETURN DISCORDS RESPONSE BACK TO THE PROCESS MAKING THE REQUEST @@ -116,13 +122,13 @@ async function handleRequest(conn: Deno.Conn) { requestEvent.respondWith( new Response(JSON.stringify(result), { status: 200, - }) + }), ); } else { requestEvent.respondWith( new Response(undefined, { status: 204, - }) + }), ); } } diff --git a/site/docs/big-bot-guide/step-by-step.md b/site/docs/big-bot-guide/step-by-step.md index 6e17c8fff..4b8a7812d 100644 --- a/site/docs/big-bot-guide/step-by-step.md +++ b/site/docs/big-bot-guide/step-by-step.md @@ -8,26 +8,33 @@ THIS IS A WORK IN PROGRESS GUIDE USING THE NEW v13 OF DISCORDENO. ## Understanding The Goals of This Guide -This guide is a quick-paced walkthrough meant for big bot developers. It is expected that you have a decent amount of understanding of how to code your bots. +This guide is a quick-paced walkthrough meant for big bot developers. It is expected that you have a decent amount of +understanding of how to code your bots. ## Is This Guide Meant For You? -If your goal is not to have a bot in millions of discord servers, please find another guide/library. Discordeno is heavily opinionated towards optimizing for bots at scale. If you do not know what a Map or a Set is without having to google it, you are at the wrong place. +If your goal is not to have a bot in millions of discord servers, please find another guide/library. Discordeno is +heavily opinionated towards optimizing for bots at scale. If you do not know what a Map or a Set is without having to +google it, you are at the wrong place. ## Why You Should Use Discordeno? -The best way I can describe why you should use Discordeno, is from the words of the biggest bot developers themselves. After speaking to some of the developers of the biggest JS/TS bots, you begin to see a pattern of users unhappy with the current state of JS/TS libraries. They are no longer able to help them scale easily and are starting to move away to other libraries or having to make their own libraries because they need to be able to make their bot distributed. +The best way I can describe why you should use Discordeno, is from the words of the biggest bot developers themselves. +After speaking to some of the developers of the biggest JS/TS bots, you begin to see a pattern of users unhappy with the +current state of JS/TS libraries. They are no longer able to help them scale easily and are starting to move away to +other libraries or having to make their own libraries because they need to be able to make their bot distributed. The following quotes are from developers who have bot's in atleast 1 million+ discord servers. - Flexibility like no other library. - - One of the big bot developers found that when their bot got too big, Eris was just very painful to optimize. - - "A pretty large hassle, I had to fork eris and modify it. There was a lot of interdependency on the values from caches that made it difficult to remove properties "safely" without searching the entire codebase" - - When discovering how easy it was to do the same thing in Discordeno: - - "the convenience of being able to do so puts confidence in me that the lib is versatile so it'd certainly draw me towards it" + - One of the big bot developers found that when their bot got too big, Eris was just very painful to optimize. + - "A pretty large hassle, I had to fork eris and modify it. There was a lot of interdependency on the values from + caches that made it difficult to remove properties "safely" without searching the entire codebase" + - When discovering how easy it was to do the same thing in Discordeno: + - "the convenience of being able to do so puts confidence in me that the lib is versatile so it'd certainly draw me + towards it" - Scalability: Standalone Gateway, Rest, Event Handler, Commands, Cache and much more. - - "All this sound like a dream (especially when you currently use eris)" + - "All this sound like a dream (especially when you currently use eris)" -Discordeno provides you all the tools that you need to make bot development -really easy. As the old saying goes, the best way to learn to ride a bicycle is to actually -try riding a bicycle. So let's try out Discordeno. +Discordeno provides you all the tools that you need to make bot development really easy. As the old saying goes, the +best way to learn to ride a bicycle is to actually try riding a bicycle. So let's try out Discordeno. diff --git a/site/docs/general/_category_.json b/site/docs/general/_category_.json index a34337df9..551eaa6d1 100644 --- a/site/docs/general/_category_.json +++ b/site/docs/general/_category_.json @@ -1,4 +1,4 @@ { - "label": "General", - "position": 1 -} \ No newline at end of file + "label": "General", + "position": 1 +} diff --git a/site/docs/general/frequently-asked-questions.md b/site/docs/general/frequently-asked-questions.md index b5745a35f..bfea59a73 100644 --- a/site/docs/general/frequently-asked-questions.md +++ b/site/docs/general/frequently-asked-questions.md @@ -6,57 +6,44 @@ sidebar_position: 1 ## Does Discordeno Support TypeScript? -Discordeno provides first class support for TypeScript! Since Deno provides -support for TypeScript, that also comes into Discordeno. This means you don't -need to compile TypeScript before you use it. However, this isn't really why -Discordeno is the best library for TypeScript developers. When I developed this -library, I was experimenting with a lot of different things and one of them was -automated typings. +Discordeno provides first class support for TypeScript! Since Deno provides support for TypeScript, that also comes into +Discordeno. This means you don't need to compile TypeScript before you use it. However, this isn't really why Discordeno +is the best library for TypeScript developers. When I developed this library, I was experimenting with a lot of +different things and one of them was automated typings. -Whenever I used other libraries, I was always seeing typings being inaccurate or -problematic. This is because in any Discord API library, the majority is not -used by the library itself so TypeScript doesn't warn the library developers. -This makes it extremely likely that those typings become inaccurate or out of -date because of simple mistakes like forgetting to update typings. Sometimes -libraries will add a property and forget to add that on their typings. This -makes it usable for JavaScript developers but not for TypeScript devs. For -TypeScript developers, typings are everything! Discordeno treats typings as part -of it's code! A breaking change in typings is a breaking change for the library! +Whenever I used other libraries, I was always seeing typings being inaccurate or problematic. This is because in any +Discord API library, the majority is not used by the library itself so TypeScript doesn't warn the library developers. +This makes it extremely likely that those typings become inaccurate or out of date because of simple mistakes like +forgetting to update typings. Sometimes libraries will add a property and forget to add that on their typings. This +makes it usable for JavaScript developers but not for TypeScript devs. For TypeScript developers, typings are +everything! Discordeno treats typings as part of it's code! A breaking change in typings is a breaking change for the +library! ## How Stable Is Discordeno? -One of the biggest issues with almost every library (that I have used) is -stability. None of the libraries gave much love and attention to TypeScript -developers the way it deserves. Sometimes TypeScript projects would break -because breaking changes to typings did not make a MAJOR bump so TypeScript bots -in production would break. Sometimes I was personally maintaining the typings -because no one else was for that lib. Some libs were pre 1.0 and didn't even -have a stable branch/version where I would not have to worry about breaking -changes. +One of the biggest issues with almost every library (that I have used) is stability. None of the libraries gave much +love and attention to TypeScript developers the way it deserves. Sometimes TypeScript projects would break because +breaking changes to typings did not make a MAJOR bump so TypeScript bots in production would break. Sometimes I was +personally maintaining the typings because no one else was for that lib. Some libs were pre 1.0 and didn't even have a +stable branch/version where I would not have to worry about breaking changes. -This is why I made it one of my foundational goals of this library to have the -best stability for TypeScript developers. No matter how small, a breaking change -is a breaking change when it affects the public API. I could care less if we end -up at version 500. Being afraid to bump a MAJOR because it's a small change or a -typing change is a terrible decision as a library maintainer and destroys the -experience for end users. +This is why I made it one of my foundational goals of this library to have the best stability for TypeScript developers. +No matter how small, a breaking change is a breaking change when it affects the public API. I could care less if we end +up at version 500. Being afraid to bump a MAJOR because it's a small change or a typing change is a terrible decision as +a library maintainer and destroys the experience for end users. ## Why Doesn't Discordeno Use Classes or EventEmitter? -This is a design decision for the lib itself. You can still use class if you -want on your bot. In fact, I hope someone makes a framework/templates for this -lib one day using classes so that devs have a choice on which style they prefer. -Without trying to write an entire thesis statement on the reasons why I avoided -Classes in this lib, I will just link to the best resources I believe help -explain it. +This is a design decision for the lib itself. You can still use class if you want on your bot. In fact, I hope someone +makes a framework/templates for this lib one day using classes so that devs have a choice on which style they prefer. +Without trying to write an entire thesis statement on the reasons why I avoided Classes in this lib, I will just link to +the best resources I believe help explain it. - [Really good article](https://dannyfritz.wordpress.com/2014/10/11/class-free-object-oriented-programming/) -- [Lecture by one of the developers who makes - JavaScript](https://www.youtube.com/watch?v=PSGEjv3Tqo0) +- [Lecture by one of the developers who makes JavaScript](https://www.youtube.com/watch?v=PSGEjv3Tqo0) -In regards to EventEmitter, I believe a functional event API was a much better -choice. EventEmitter at it's core is simply just functions that run when a -certain event is emitted. In Discordeno, that function is executed instead of +In regards to EventEmitter, I believe a functional event API was a much better choice. EventEmitter at it's core is +simply just functions that run when a certain event is emitted. In Discordeno, that function is executed instead of emitting some event to trigger that function. ```typescript @@ -66,18 +53,14 @@ EventEmitter.emit("guildCreate", guild); eventHandlers.guildCreate?.(guild); ``` -There isn't really any difference especially for users when they use it. One bad -thing about EventEmitter is that if misused it can easily cause memory leaks. It -is very easy to open yourself up to these memory leak issues. It has happened to -me when I started coding as well. This is why I wanted Discordeno's -implementation to help devs avoid the issues I had. It prevents anyone from -having this as a potential issue. Another issue with EventEmitter is trying to -update the code in those functions without having to deal with headaches left -and right of removing and adding listeners. You don't need to worry about -binding or not binding events. They are just pure functions +There isn't really any difference especially for users when they use it. One bad thing about EventEmitter is that if +misused it can easily cause memory leaks. It is very easy to open yourself up to these memory leak issues. It has +happened to me when I started coding as well. This is why I wanted Discordeno's implementation to help devs avoid the +issues I had. It prevents anyone from having this as a potential issue. Another issue with EventEmitter is trying to +update the code in those functions without having to deal with headaches left and right of removing and adding +listeners. You don't need to worry about binding or not binding events. They are just pure functions -In Discordeno, this is extremely simple, you just simply give it the new event -handlers. +In Discordeno, this is extremely simple, you just simply give it the new event handlers. ```typescript updateEventHandlers(newEventHandlers); @@ -85,45 +68,35 @@ updateEventHandlers(newEventHandlers); ## Why Do You Have A Class for Collection If Classes Are Bad? -The Collection class is an exception in the library where a class was allowed. -This is because Collection extends Map. The Map class is provided by JavaScript -itself and is extremely fast. You can perform millions of operations a second -with a Map. Maps are too useful to avoid and don't have downsides like -EventEmitters do. The Collection class simply adds on other functionality that -Discordeno users felt they needed. Although I am against using classes whenever +The Collection class is an exception in the library where a class was allowed. This is because Collection extends Map. +The Map class is provided by JavaScript itself and is extremely fast. You can perform millions of operations a second +with a Map. Maps are too useful to avoid and don't have downsides like EventEmitters do. The Collection class simply +adds on other functionality that Discordeno users felt they needed. Although I am against using classes whenever possible, I am also a big supporter of providing the best developer experience. ## Why Are there no options in Discordeno? -Discordeno is not a library that handles code in the exact way every person -wants it to. It is opinionated. Discordeno defaults to the Discord recommended -options or the best options for majority of developers needs. For example, there -is no option of fetching all members startup. This is a practice that Discord -does not recommend or want users doing. By default, we don't support stuff like -this. In Discordeno, we follow Discords recommended solution and it just works +Discordeno is not a library that handles code in the exact way every person wants it to. It is opinionated. Discordeno +defaults to the Discord recommended options or the best options for majority of developers needs. For example, there is +no option of fetching all members startup. This is a practice that Discord does not recommend or want users doing. By +default, we don't support stuff like this. In Discordeno, we follow Discords recommended solution and it just works internally. The End! No fuss! No Muss! Just good stuff! -Now, I understand that there are times when it's necessary to be able to -customize this and fetch them all. If you are advanced enough to need these -options, you should be able to simply do it yourself. For most users, this is -just an unnecessary option. The main module should remain minimalistic and easy -to use for 99% of users. +Now, I understand that there are times when it's necessary to be able to customize this and fetch them all. If you are +advanced enough to need these options, you should be able to simply do it yourself. For most users, this is just an +unnecessary option. The main module should remain minimalistic and easy to use for 99% of users. ## Why Do I See errors Like "MISSING_VIEW_CHANNEL" or "BOTS_HIGHEST_ROLE_TOO_LOW"? -Discordeno is the only library(that I have used), that has built in permission -handling. A lot of bots get automatically banned by Discord because they forget -to handle permissions. When bots don't check permissions and continue to send -requests to the API, this leads to bots being banned. I have tried to request -adding this feature into libraries but they were reluctant to do so because it -would require the devs to maintain the library whenever an update was made by +Discordeno is the only library(that I have used), that has built in permission handling. A lot of bots get automatically +banned by Discord because they forget to handle permissions. When bots don't check permissions and continue to send +requests to the API, this leads to bots being banned. I have tried to request adding this feature into libraries but +they were reluctant to do so because it would require the devs to maintain the library whenever an update was made by Discord. -Discordeno provides you specific keywords that you can use to send a clean -response to the end user of your choosing. I have even seen some bots have -hundreds of thousands of Missing Permission or Missing Access errors because -libraries don't handle it. IMO, this is a crucial part of any good library as -much as it is to handle rate limiting. +Discordeno provides you specific keywords that you can use to send a clean response to the end user of your choosing. I +have even seen some bots have hundreds of thousands of Missing Permission or Missing Access errors because libraries +don't handle it. IMO, this is a crucial part of any good library as much as it is to handle rate limiting. ```typescript import { Errors, Message } from "https://deno.land/x/discordeno@10.0.0/mod.ts"; diff --git a/site/docs/general/getting-started.md b/site/docs/general/getting-started.md index 345968958..eaab47683 100644 --- a/site/docs/general/getting-started.md +++ b/site/docs/general/getting-started.md @@ -4,10 +4,9 @@ sidebar_position: 2 # Getting Started -Discordeno aims for a simple, easy and stress-free interaction with the Discord -API. Always supporting the latest version to ensure stability, consistency and -the best developer experience. This guide serves as the purpose for introducing -Discordeno to developers. +Discordeno aims for a simple, easy and stress-free interaction with the Discord API. Always supporting the latest +version to ensure stability, consistency and the best developer experience. This guide serves as the purpose for +introducing Discordeno to developers. ## Requirements @@ -17,23 +16,20 @@ Discordeno to developers. Plenty of guides are available on how to create a Discord Bot Application. -1. [Creating an Application](https://discord.com/developers/applications) on the - Developer Portal, name something cool and pick a sweet icon! -2. After creating an application. Save the **Client ID.** Thats the unique - identifier for a Discord Bot. -3. Now, go and create a bot by clicking the **Bot** tab. You will see a - **Token** section and thats the Discord Bot's token. **Make sure you don't - share that token with anyone!!!** +1. [Creating an Application](https://discord.com/developers/applications) on the Developer Portal, name something cool + and pick a sweet icon! +2. After creating an application. Save the **Client ID.** Thats the unique identifier for a Discord Bot. +3. Now, go and create a bot by clicking the **Bot** tab. You will see a **Token** section and thats the Discord Bot's + token. **Make sure you don't share that token with anyone!!!** 4. Invite the bot to the server, you can use the - **[Discord Permissions Calculator](https://discordapi.com/permissions.html#0)** - for creating the invite link with custom permissions. By default, `0` means - no permissions and `8` means Administrator. + **[Discord Permissions Calculator](https://discordapi.com/permissions.html#0)** for creating the invite link with + custom permissions. By default, `0` means no permissions and `8` means Administrator. -Now you've created an Application but it will need some code in order for it to -be online. Thats when Discordeno comes in handy! +Now you've created an Application but it will need some code in order for it to be online. Thats when Discordeno comes +in handy! -> Make sure you store your tokens in a file that is NOT deployed by adding it to -> the .gitignore file. **Don't share your bot token with anybody.** +> Make sure you store your tokens in a file that is NOT deployed by adding it to the .gitignore file. **Don't share your +> bot token with anybody.** ## Installation @@ -45,8 +41,8 @@ import { startBot } from "https://deno.land/x/discordeno@10.0.0/mod.ts"; ## Example Usage -Starting with Discordeno is very simple, you can start from scratch without any -templates/frameworks: Add this snippet of code into a new TypeScript file: +Starting with Discordeno is very simple, you can start from scratch without any templates/frameworks: Add this snippet +of code into a new TypeScript file: ```ts import { startBot } from "https://deno.land/x/discordeno/mod.ts"; @@ -69,11 +65,8 @@ startBot({ ## Tutorials -Below you will find youtube playlists that display channels using Discordeno for -their tutorials. +Below you will find youtube playlists that display channels using Discordeno for their tutorials. -- [Making a Discord bot with Deno and - Discordeno](https://web-mystery.com/articles/making-discord-bot-deno-and-discordeno) -- [Running a Discord bot written using Deno in - Docker](https://web-mystery.com/articles/running-discord-bot-written-deno-docker) +- [Making a Discord bot with Deno and Discordeno](https://web-mystery.com/articles/making-discord-bot-deno-and-discordeno) +- [Running a Discord bot written using Deno in Docker](https://web-mystery.com/articles/running-discord-bot-written-deno-docker) - [Discordeno Bot Tutorials (YouTube)](https://youtu.be/rIph9-BGsuQ) diff --git a/site/docs/general/migrating.md b/site/docs/general/migrating.md index 224c0d20e..929925458 100644 --- a/site/docs/general/migrating.md +++ b/site/docs/general/migrating.md @@ -1,49 +1,44 @@ --- sidebar_position: 3 --- + # Migrating ## Migrating from Discord.js -This migration guide is not intended to discredit Discord.js authors/maintainers -or Discord.js itself. In fact, Discord.js is the most popular Node.js library, -admired and praised by a lot of JavaScript developers. +This migration guide is not intended to discredit Discord.js authors/maintainers or Discord.js itself. In fact, +Discord.js is the most popular Node.js library, admired and praised by a lot of JavaScript developers. ## Finding an Open-Source Discord Bot -For the purposes of this guide, I wanted to find a moderation bot that is -totally open source to show an example of how to convert the bot to Discordeno. -Trying to find one was not easy as most bot's were not using the latest -Discord.JS version 12. Trying to find one that was using TypeScript made it even -more difficult. My next best solution was to find a moderation bot that was -recently updated(showing it is maintained or recently built). The best one I -could find was [Zodiac Bot](https://github.com/Nukestye/Zodiac). +For the purposes of this guide, I wanted to find a moderation bot that is totally open source to show an example of how +to convert the bot to Discordeno. Trying to find one was not easy as most bot's were not using the latest Discord.JS +version 12. Trying to find one that was using TypeScript made it even more difficult. My next best solution was to find +a moderation bot that was recently updated(showing it is maintained or recently built). The best one I could find was +[Zodiac Bot](https://github.com/Nukestye/Zodiac). For the purposes of this guide, I will be using the current [latest commit](https://github.com/Nukestye/Zodiac/tree/213891a38af1b7ecbd068b661ef9062ab58cc818) ## Preparations -- First, create a Discordeno Bot using the - [Generator Template](https://github.com/discordeno/template) I will name - it Zodiac. +- First, create a Discordeno Bot using the [Generator Template](https://github.com/discordeno/template) I will name it + Zodiac. - Then `git clone https://github.com/Skillz4Killz/Zodiac.git` -Now that I had the repository cloned, I could begin. Note that although the bot -we are converting is built in JavaScript, I converted all code to TypeScript in -this Guide as Discordeno is designed to be the best lib for TypeScript +Now that I had the repository cloned, I could begin. Note that although the bot we are converting is built in +JavaScript, I converted all code to TypeScript in this Guide as Discordeno is designed to be the best lib for TypeScript developers. Time to get started! ## Converting main.js (index file) -The first thing is to convert the `main.js` file which would be the app.js or -index.js file. This is the file that is run to start your bot. In this case, the -bot developer chose `main.js`. In Deno, the initial file is named `mod.ts` so we -can go ahead and opt for the Deno pattern. Note: there is already a `mod.ts` -file created and prebuilt entirely using the Generator. +The first thing is to convert the `main.js` file which would be the app.js or index.js file. This is the file that is +run to start your bot. In this case, the bot developer chose `main.js`. In Deno, the initial file is named `mod.ts` so +we can go ahead and opt for the Deno pattern. Note: there is already a `mod.ts` file created and prebuilt entirely using +the Generator. Current Discord.JS Code: @@ -73,9 +68,7 @@ fs.readdir("./src/events/", (err, files) => { const { once } = eventFunction; try { emitter[ - once - ? "once" - : "on" + once ? "once" : "on" ](event, (...args) => eventFunction.run(...args)); } catch (error) { console.error(error.stack); @@ -175,22 +168,14 @@ startBot({ }); ``` -Something we haven't converted yet from the `main.js` files is the event -listeners. To do that, we will open up the events folder and find the -corresponding event or create it if necessary. In this case, we have the `ready` -event and there is already a `ready.ts` file. We can just use that. +Something we haven't converted yet from the `main.js` files is the event listeners. To do that, we will open up the +events folder and find the corresponding event or create it if necessary. In this case, we have the `ready` event and +there is already a `ready.ts` file. We can just use that. In our `ready.ts` file we can add the `ready` event listener. ```ts -import { - ActivityType, - botCache, - cache, - chooseRandom, - editBotsStatus, - StatusTypes, -} from "../../deps.ts"; +import { ActivityType, botCache, cache, chooseRandom, editBotsStatus, StatusTypes } from "../../deps.ts"; import { registerTasks } from "./../utils/taskHelper.ts"; botCache.eventHandlers.ready = function () { @@ -225,19 +210,15 @@ botCache.eventHandlers.ready = function () { }; ``` -To understand this code, we are setting a function to be run when the bot is -`ready`. Then the bot will edit the bots status every 5 seconds. Notice, that -Discordeno provides a nice clean util function to choose a random item from an -array. You also have beautiful enums provided that prevent you from making any -typos/mistakes. +To understand this code, we are setting a function to be run when the bot is `ready`. Then the bot will edit the bots +status every 5 seconds. Notice, that Discordeno provides a nice clean util function to choose a random item from an +array. You also have beautiful enums provided that prevent you from making any typos/mistakes. -We have now converted the entire `main.js` file, in a matter of seconds. The -Discordeno official generator took care of the majority of workload and we just -modified the `ready.ts` file. +We have now converted the entire `main.js` file, in a matter of seconds. The Discordeno official generator took care of +the majority of workload and we just modified the `ready.ts` file. -`Note:` I did remove some generally well known "bad practices" such as global -vars and such. Overall, you will see the functionality of the project will not -change as we progress through this guide. +`Note:` I did remove some generally well known "bad practices" such as global vars and such. Overall, you will see the +functionality of the project will not change as we progress through this guide. ## Converting Commands @@ -330,9 +311,8 @@ createCommand({ }); ``` -Awesome, that is a full command converted from Discord.JS to Discordeno. See how -easy it is! Let's convert one more command to see how to really take full -advantage of Discordeno template and have something amazing. +Awesome, that is a full command converted from Discord.JS to Discordeno. See how easy it is! Let's convert one more +command to see how to really take full advantage of Discordeno template and have something amazing. Discord.JS Kick Command Version @@ -455,9 +435,7 @@ createCommand({ .addField("Reason >", args.reason) .addField("Time", message.timestamp.toString()); - const reportchannel = message.guild?.channels.find((channel) => - channel.name === "report" - ); + const reportchannel = message.guild?.channels.find((channel) => channel.name === "report"); if (!reportchannel) { return message.reply("*`Report channel cannot be found!`*"); } @@ -477,20 +455,16 @@ interface KickArgs { } ``` -Let's take a minute and explain the differences here. The first thing you will -probably notice is different is the `arguments` property. Discordeno provides -the `arguments` property because it provides argument -handling/parsing/validating internally. You don't need to be splitting the -message content or going through and validating it yourself. All you do is tell -Discordeno that you want a member and a reason. It will do the magic and hard -work to get you that data before you even run the command. You just do -`args.member` and you have access to the full member object. There are a lot -more powerful aspects to Discordeno like arguments. Keep diving in and you will -find all the wonderful tools available to give you the best developer experience -possible. +Let's take a minute and explain the differences here. The first thing you will probably notice is different is the +`arguments` property. Discordeno provides the `arguments` property because it provides argument +handling/parsing/validating internally. You don't need to be splitting the message content or going through and +validating it yourself. All you do is tell Discordeno that you want a member and a reason. It will do the magic and hard +work to get you that data before you even run the command. You just do `args.member` and you have access to the full +member object. There are a lot more powerful aspects to Discordeno like arguments. Keep diving in and you will find all +the wonderful tools available to give you the best developer experience possible. ### Need More Examples/Help -If you still need more help converting other aspects of your bot please contact -me at [Discord](https://discord.com/invite/5vBgXk3UcZ). I will continue adding -more examples to this guide as more people request them. +If you still need more help converting other aspects of your bot please contact me at +[Discord](https://discord.com/invite/5vBgXk3UcZ). I will continue adding more examples to this guide as more people +request them. diff --git a/site/docs/intro.md b/site/docs/intro.md index 7f94ec876..1b5d4cef2 100644 --- a/site/docs/intro.md +++ b/site/docs/intro.md @@ -11,16 +11,13 @@ sidebar_position: 1 ## Features -- **Secure & stable**: Discordeno is secure and stable. One of the greatest - issues with almost every library is stability; types are outdated, less (or - minimal) parity with the API, core maintainers have quit or no longer actively - maintain the library, and whatnot. Discordeno, on the other hand, is actively - maintained to ensure great performance and convenience. Moreover, it - internally checks all missing permissions before forwarding a request to the - Discord API so that the client does not get globally-banned by Discord. -- **Simple, Efficient, & Lightweight**: Discordeno is simplistic, easy-to-use, - versatile while being efficient and lightweight. -- [**Functional API**](https://en.wikipedia.org/wiki/Functional_programming): - Functional API ensures an overall concise yet performant code while removing - the difficulties of extending built-in classes and inheritance. +- **Secure & stable**: Discordeno is secure and stable. One of the greatest issues with almost every library is + stability; types are outdated, less (or minimal) parity with the API, core maintainers have quit or no longer actively + maintain the library, and whatnot. Discordeno, on the other hand, is actively maintained to ensure great performance + and convenience. Moreover, it internally checks all missing permissions before forwarding a request to the Discord API + so that the client does not get globally-banned by Discord. +- **Simple, Efficient, & Lightweight**: Discordeno is simplistic, easy-to-use, versatile while being efficient and + lightweight. +- [**Functional API**](https://en.wikipedia.org/wiki/Functional_programming): Functional API ensures an overall concise + yet performant code while removing the difficulties of extending built-in classes and inheritance. [Learn more about class-free JavaScript](https://dannyfritz.wordpress.com/2014/10/11/class-free-object-oriented-programming/) diff --git a/site/sidebars.js b/site/sidebars.js index fd342f2cd..8212d1a11 100644 --- a/site/sidebars.js +++ b/site/sidebars.js @@ -14,8 +14,7 @@ /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - + tutorialSidebar: [{ type: "autogenerated", dirName: "." }], // But you can create a sidebar manually /* tutorialSidebar: [ diff --git a/site/src/components/HomepageFeatures.tsx b/site/src/components/HomepageFeatures.tsx index 370335953..cb8e09feb 100644 --- a/site/src/components/HomepageFeatures.tsx +++ b/site/src/components/HomepageFeatures.tsx @@ -85,9 +85,7 @@ export default function HomepageFeatures(): JSX.Element {
- {FeatureList.map((props, idx) => ( - - ))} + {FeatureList.map((props, idx) => )}
diff --git a/site/src/pages/index.tsx b/site/src/pages/index.tsx index 6bba93c6e..0fa82d657 100644 --- a/site/src/pages/index.tsx +++ b/site/src/pages/index.tsx @@ -1,22 +1,23 @@ -import React from 'react'; -import clsx from 'clsx'; -import Layout from '@theme/Layout'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import styles from './index.module.css'; -import HomepageFeatures from '../components/HomepageFeatures'; +import React from "react"; +import clsx from "clsx"; +import Layout from "@theme/Layout"; +import Link from "@docusaurus/Link"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import styles from "./index.module.css"; +import HomepageFeatures from "../components/HomepageFeatures"; function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return ( -
+

{siteConfig.title}

{siteConfig.tagline}

+ to="/docs/intro" + > Discordeno Tutorial
@@ -26,11 +27,12 @@ function HomepageHeader() { } export default function Home(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return ( + description="Description will go into a meta tag in " + >
diff --git a/src/bot.ts b/src/bot.ts index b4b5a30d1..e02dd6442 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -1,13 +1,13 @@ import { checkRateLimits, - processQueue, cleanupQueues, createRequestBody, + processGlobalQueue, + processQueue, processRateLimitedPaths, processRequest, processRequestHeaders, runMethod, - processGlobalQueue, simplifyUrl, } from "./rest/mod.ts"; import type { RestPayload, RestRateLimitedPath, RestRequest } from "./rest/rest.ts"; @@ -16,27 +16,27 @@ import { GetGatewayBot } from "./types/gateway/getGatewayBot.ts"; import { bigintToSnowflake, snowflakeToBigint } from "./util/bigint.ts"; import { Collection } from "./util/collection.ts"; import { - DiscordenoMember, - DiscordenoUser, - transformMember, - transformUser, - DiscordenoGuild, - transformGuild, DiscordenoChannel, - transformChannel, - transformMessage, - transformRole, - DiscordenoVoiceState, - transformVoiceState, + DiscordenoGuild, + DiscordenoMember, DiscordenoMessage, DiscordenoRole, + DiscordenoUser, + DiscordenoVoiceState, + transformChannel, + transformGuild, + transformMember, + transformMessage, + transformRole, + transformUser, + transformVoiceState, } from "./transformers/mod.ts"; import { baseEndpoints, CHANNEL_MENTION_REGEX, CONTEXT_MENU_COMMANDS_NAME_REGEX, - DISCORDENO_VERSION, DISCORD_SNOWFLAKE_REGEX, + DISCORDENO_VERSION, endpoints, SLASH_COMMANDS_NAME_REGEX, USER_AGENT, @@ -45,18 +45,18 @@ import { Errors } from "./types/discordeno/errors.ts"; import { DiscordGatewayPayload, GatewayDispatchEventNames, GatewayPayload } from "./types/gateway/gatewayPayload.ts"; import { closeWS, - handleOnMessage, - resume, - resharder, - spawnShards, - prepareBuckets, createShard, - identify, - heartbeat, - tellWorkerToIdentify, - sendShardMessage, DiscordenoShard, + handleOnMessage, + heartbeat, + identify, + prepareBuckets, processGatewayQueue, + resharder, + resume, + sendShardMessage, + spawnShards, + tellWorkerToIdentify, } from "./ws/mod.ts"; import { validateLength } from "./util/validateLength.ts"; import { delay, formatImageURL, hasProperty } from "./util/utils.ts"; @@ -125,8 +125,7 @@ export function createBot(options: CreateBotOptions): Bot { token: bot.token, intents: bot.intents, debug: bot.events.debug, - handleDiscordPayload: - bot.handleDiscordPayload ?? + handleDiscordPayload: bot.handleDiscordPayload ?? async function (_, data: DiscordGatewayPayload, shardId: number) { // TRIGGER RAW EVENT bot.events.raw(bot as Bot, data, shardId); @@ -331,7 +330,7 @@ export interface HelperUtils { } export function createGatewayManager( - options: Partial & Pick + options: Partial & Pick, ): GatewayManager { return { cache: { @@ -651,7 +650,7 @@ export interface EventHandlers { guildId: bigint; addedMembers?: DiscordenoThreadMember[]; removedMemberIds?: bigint[]; - } + }, ) => unknown; threadUpdate: (bot: Bot, thread: DiscordenoChannel) => unknown; scheduledEventCreate: (bot: Bot, event: DiscordenoScheduledEvent) => unknown; @@ -664,7 +663,7 @@ export interface EventHandlers { guildScheduledEventId: bigint; guildId: bigint; userId: bigint; - } + }, ) => unknown; /** Sent when a user has unsubscribed to a guild scheduled event. EXPERIMENTAL! */ scheduledEventUserRemove: ( @@ -673,7 +672,7 @@ export interface EventHandlers { guildScheduledEventId: bigint; guildId: bigint; userId: bigint; - } + }, ) => unknown; ready: ( bot: Bot, @@ -686,7 +685,7 @@ export interface EventHandlers { shard?: number[]; applicationId: bigint; }, - rawPayload: DiscordReady + rawPayload: DiscordReady, ) => any; interactionCreate: (bot: Bot, interaction: DiscordenoInteraction) => any; integrationCreate: (bot: Bot, integration: DiscordenoIntegration) => any; @@ -699,7 +698,7 @@ export interface EventHandlers { channelId: bigint; guildId?: bigint; code: string; - } + }, ) => any; guildMemberAdd: (bot: Bot, member: DiscordenoMember, user: DiscordenoUser) => any; guildMemberRemove: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any; @@ -708,7 +707,7 @@ export interface EventHandlers { messageDelete: ( bot: Bot, payload: { id: bigint; channelId: bigint; guildId?: bigint }, - message?: DiscordenoMessage + message?: DiscordenoMessage, ) => any; messageUpdate: (bot: Bot, message: DiscordenoMessage, oldMessage?: DiscordenoMessage) => any; reactionAdd: ( @@ -720,7 +719,7 @@ export interface EventHandlers { guildId?: bigint; member?: DiscordenoMember; emoji: DiscordenoEmoji; - } + }, ) => any; reactionRemove: ( bot: Bot, @@ -730,7 +729,7 @@ export interface EventHandlers { messageId: bigint; guildId?: bigint; emoji: DiscordenoEmoji; - } + }, ) => any; reactionRemoveEmoji: ( bot: Bot, @@ -739,7 +738,7 @@ export interface EventHandlers { messageId: bigint; guildId?: bigint; emoji: DiscordenoEmoji; - } + }, ) => any; reactionRemoveAll: ( bot: Bot, @@ -747,7 +746,7 @@ export interface EventHandlers { channelId: bigint; messageId: bigint; guildId?: bigint; - } + }, ) => any; presenceUpdate: (bot: Bot, presence: DiscordenoPresence, oldPresence?: DiscordenoPresence) => any; voiceServerUpdate: (bot: Bot, payload: { token: string; endpoint?: string; guildId: bigint }) => any; @@ -768,7 +767,7 @@ export interface EventHandlers { selfVideo: boolean; suppress: boolean; requestToSpeakTimestamp?: number; - } + }, ) => any; channelCreate: (bot: Bot, channel: DiscordenoChannel) => any; dispatchRequirements: (bot: Bot, data: GatewayPayload, shardId: number) => any; @@ -776,7 +775,7 @@ export interface EventHandlers { bot: Bot, voiceState: DiscordenoVoiceState, guild: DiscordenoGuild, - channel?: DiscordenoChannel + channel?: DiscordenoChannel, ) => any; channelDelete: (bot: Bot, channel: DiscordenoChannel) => any; channelPinsUpdate: (bot: Bot, data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => any; @@ -788,7 +787,7 @@ export interface EventHandlers { guildId: bigint; channelId: bigint; topic: string; - } + }, ) => any; stageInstanceDelete: ( bot: Bot, @@ -797,7 +796,7 @@ export interface EventHandlers { guildId: bigint; channelId: bigint; topic: string; - } + }, ) => any; stageInstanceUpdate: ( bot: Bot, @@ -806,7 +805,7 @@ export interface EventHandlers { guildId: bigint; channelId: bigint; topic: string; - } + }, ) => any; // TODO: THREADS guildEmojisUpdate: ( @@ -814,7 +813,7 @@ export interface EventHandlers { payload: { guildId: bigint; emojis: Collection; - } + }, ) => any; guildBanAdd: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any; guildBanRemove: (bot: Bot, user: DiscordenoUser, guildId: bigint) => any; @@ -836,7 +835,7 @@ export interface EventHandlers { userId: bigint; timestamp: number; member: DiscordenoMember | undefined; - } + }, ) => any; } @@ -915,7 +914,7 @@ export interface BotGatewayHandlerOptions { } export function createBotGatewayHandlers( - options: Partial + options: Partial, ): Record any> { return { // misc @@ -956,8 +955,8 @@ export function createBotGatewayHandlers( GUILD_SCHEDULED_EVENT_DELETE: options.GUILD_SCHEDULED_EVENT_DELETE ?? handlers.handleGuildScheduledEventDelete, GUILD_SCHEDULED_EVENT_UPDATE: options.GUILD_SCHEDULED_EVENT_UPDATE ?? handlers.handleGuildScheduledEventUpdate, GUILD_SCHEDULED_EVENT_USER_ADD: options.GUILD_SCHEDULED_EVENT_USER_ADD ?? handlers.handleGuildScheduledEventUserAdd, - GUILD_SCHEDULED_EVENT_USER_REMOVE: - options.GUILD_SCHEDULED_EVENT_USER_REMOVE ?? handlers.handleGuildScheduledEventUserRemove, + GUILD_SCHEDULED_EVENT_USER_REMOVE: options.GUILD_SCHEDULED_EVENT_USER_REMOVE ?? + handlers.handleGuildScheduledEventUserRemove, // interactions INTERACTION_CREATE: options.INTERACTION_CREATE ?? handlers.handleInteractionCreate, // invites @@ -988,10 +987,8 @@ export function createBotGatewayHandlers( }; } -export type RemoveFirstFromTuple = T["length"] extends 0 - ? [] - : ((...b: T) => void) extends (a: any, ...b: infer I) => void - ? I +export type RemoveFirstFromTuple = T["length"] extends 0 ? [] + : ((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : []; export type FinalHelpers = { [K in keyof Helpers]: (...args: RemoveFirstFromTuple>) => ReturnType; diff --git a/src/handlers/channels/CHANNEL_DELETE.ts b/src/handlers/channels/CHANNEL_DELETE.ts index babb58d7e..18c3b07bb 100644 --- a/src/handlers/channels/CHANNEL_DELETE.ts +++ b/src/handlers/channels/CHANNEL_DELETE.ts @@ -12,6 +12,6 @@ export async function handleChannelDelete(bot: Bot, data: DiscordGatewayPayload) bot.transformers.channel(bot, { channel: payload, guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, - }) + }), ); } diff --git a/src/handlers/guilds/GUILD_BAN_REMOVE.ts b/src/handlers/guilds/GUILD_BAN_REMOVE.ts index b2d26f5e0..fac4e1544 100644 --- a/src/handlers/guilds/GUILD_BAN_REMOVE.ts +++ b/src/handlers/guilds/GUILD_BAN_REMOVE.ts @@ -9,6 +9,6 @@ export async function handleGuildBanRemove(bot: Bot, data: DiscordGatewayPayload await bot.events.guildBanRemove( bot, bot.transformers.user(bot, payload.user), - bot.transformers.snowflake(payload.guild_id) + bot.transformers.snowflake(payload.guild_id), ); } diff --git a/src/handlers/integrations/INTEGRATION_CREATE.ts b/src/handlers/integrations/INTEGRATION_CREATE.ts index 549e15588..ef3586d56 100644 --- a/src/handlers/integrations/INTEGRATION_CREATE.ts +++ b/src/handlers/integrations/INTEGRATION_CREATE.ts @@ -6,6 +6,6 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; export function handleIntegrationCreate(bot: Bot, data: DiscordGatewayPayload) { bot.events.integrationCreate( bot, - bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep) + bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep), ); } diff --git a/src/handlers/integrations/INTEGRATION_UPDATE.ts b/src/handlers/integrations/INTEGRATION_UPDATE.ts index 2de0aea0f..965268841 100644 --- a/src/handlers/integrations/INTEGRATION_UPDATE.ts +++ b/src/handlers/integrations/INTEGRATION_UPDATE.ts @@ -6,6 +6,6 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; export function handleIntegrationUpdate(bot: Bot, data: DiscordGatewayPayload) { bot.events.integrationUpdate( bot, - bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep) + bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep), ); } diff --git a/src/handlers/members/GUILD_MEMBERS_CHUNK.ts b/src/handlers/members/GUILD_MEMBERS_CHUNK.ts index ba0e62857..7d3bad401 100644 --- a/src/handlers/members/GUILD_MEMBERS_CHUNK.ts +++ b/src/handlers/members/GUILD_MEMBERS_CHUNK.ts @@ -9,7 +9,11 @@ export async function handleGuildMembersChunk(bot: Bot, data: DiscordGatewayPayl const guildId = bot.transformers.snowflake(payload.guild_id); - if (payload.nonce && payload.chunk_index >= payload.chunk_count - 1) bot.cache.fetchAllMembersProcessingRequests.get(payload.nonce)?.(`Member fetching complete. Nonce: ${payload.nonce}`); + if (payload.nonce && payload.chunk_index >= payload.chunk_count - 1) { + bot.cache.fetchAllMembersProcessingRequests.get(payload.nonce)?.( + `Member fetching complete. Nonce: ${payload.nonce}`, + ); + } return { guildId, diff --git a/src/handlers/members/GUILD_MEMBER_UPDATE.ts b/src/handlers/members/GUILD_MEMBER_UPDATE.ts index a9377d07b..671272973 100644 --- a/src/handlers/members/GUILD_MEMBER_UPDATE.ts +++ b/src/handlers/members/GUILD_MEMBER_UPDATE.ts @@ -10,6 +10,6 @@ export async function handleGuildMemberUpdate(bot: Bot, data: DiscordGatewayPayl bot.events.guildMemberUpdate( bot, bot.transformers.member(bot, payload, bot.transformers.snowflake(payload.guild_id), user.id), - user + user, ); } diff --git a/src/handlers/misc/READY.ts b/src/handlers/misc/READY.ts index 1dc8ef24c..fd7952e2f 100644 --- a/src/handlers/misc/READY.ts +++ b/src/handlers/misc/READY.ts @@ -16,7 +16,7 @@ export function handleReady(bot: Bot, data: DiscordGatewayPayload, shardId: numb shard: payload.shard, applicationId: bot.transformers.snowflake(payload.application.id), }, - payload + payload, ); if (!bot.id) bot.id = bot.transformers.snowflake(payload.user.id); diff --git a/src/handlers/roles/GUILD_ROLE_CREATE.ts b/src/handlers/roles/GUILD_ROLE_CREATE.ts index b5d8c197d..69616913e 100644 --- a/src/handlers/roles/GUILD_ROLE_CREATE.ts +++ b/src/handlers/roles/GUILD_ROLE_CREATE.ts @@ -7,6 +7,6 @@ export async function handleGuildRoleCreate(bot: Bot, data: DiscordGatewayPayloa const payload = data.d as SnakeCasedPropertiesDeep; bot.events.roleCreate( bot, - bot.transformers.role(bot, { role: payload.role, guildId: bot.transformers.snowflake(payload.guild_id) }) + bot.transformers.role(bot, { role: payload.role, guildId: bot.transformers.snowflake(payload.guild_id) }), ); } diff --git a/src/handlers/roles/GUILD_ROLE_UPDATE.ts b/src/handlers/roles/GUILD_ROLE_UPDATE.ts index c2d0d8eda..350e9bcfc 100644 --- a/src/handlers/roles/GUILD_ROLE_UPDATE.ts +++ b/src/handlers/roles/GUILD_ROLE_UPDATE.ts @@ -8,6 +8,6 @@ export async function handleGuildRoleUpdate(bot: Bot, data: DiscordGatewayPayloa bot.events.roleUpdate( bot, - bot.transformers.role(bot, { role: payload.role, guildId: bot.transformers.snowflake(payload.guild_id) }) + bot.transformers.role(bot, { role: payload.role, guildId: bot.transformers.snowflake(payload.guild_id) }), ); } diff --git a/src/helpers/channels/createChannel.ts b/src/helpers/channels/createChannel.ts index 541b1aeda..c2fd292e9 100644 --- a/src/helpers/channels/createChannel.ts +++ b/src/helpers/channels/createChannel.ts @@ -14,24 +14,24 @@ export async function createChannel(bot: Bot, guildId: bigint, options?: CreateG bot.constants.endpoints.GUILD_CHANNELS(guildId), options ? { - name: options.name, - topic: options.topic, - bitrate: options.bitrate, - user_limit: options.userLimit, - rate_limit_per_user: options.rateLimitPerUser, - position: options.position, - parent_id: options.parentId?.toString(), - nsfw: options.nsfw, - permission_overwrites: options?.permissionOverwrites?.map((perm) => ({ - id: perm.id.toString(), - type: perm.type, - allow: perm.allow ? bot.utils.calculateBits(perm.allow) : "0", - deny: perm.deny ? bot.utils.calculateBits(perm.deny) : "0", - })), - type: options?.type || ChannelTypes.GuildText, - reason, - } - : {} + name: options.name, + topic: options.topic, + bitrate: options.bitrate, + user_limit: options.userLimit, + rate_limit_per_user: options.rateLimitPerUser, + position: options.position, + parent_id: options.parentId?.toString(), + nsfw: options.nsfw, + permission_overwrites: options?.permissionOverwrites?.map((perm) => ({ + id: perm.id.toString(), + type: perm.type, + allow: perm.allow ? bot.utils.calculateBits(perm.allow) : "0", + deny: perm.deny ? bot.utils.calculateBits(perm.deny) : "0", + })), + type: options?.type || ChannelTypes.GuildText, + reason, + } + : {}, ); return bot.transformers.channel(bot, { channel: result, guildId }); diff --git a/src/helpers/channels/deleteChannel.ts b/src/helpers/channels/deleteChannel.ts index d047582f4..da0aa943d 100644 --- a/src/helpers/channels/deleteChannel.ts +++ b/src/helpers/channels/deleteChannel.ts @@ -9,6 +9,6 @@ export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string bot.constants.endpoints.CHANNEL_BASE(channelId), { reason, - } + }, ); } diff --git a/src/helpers/channels/deleteChannelOverwrite.ts b/src/helpers/channels/deleteChannelOverwrite.ts index fa0298d85..655ef75c9 100644 --- a/src/helpers/channels/deleteChannelOverwrite.ts +++ b/src/helpers/channels/deleteChannelOverwrite.ts @@ -5,6 +5,6 @@ export async function deleteChannelOverwrite(bot: Bot, channelId: bigint, overwr await bot.rest.runMethod( bot.rest, "delete", - bot.constants.endpoints.CHANNEL_OVERWRITE(channelId, overwriteId) + bot.constants.endpoints.CHANNEL_OVERWRITE(channelId, overwriteId), ); } diff --git a/src/helpers/channels/editChannel.ts b/src/helpers/channels/editChannel.ts index 063d8ae94..8e67ec0b2 100644 --- a/src/helpers/channels/editChannel.ts +++ b/src/helpers/channels/editChannel.ts @@ -47,12 +47,12 @@ export async function editChannel(bot: Bot, channelId: bigint, options: ModifyCh invitable: options.invitable, permission_overwrites: options.permissionOverwrites ? options.permissionOverwrites?.map((overwrite) => { - return { - ...overwrite, - allow: overwrite.allow ? bot.utils.calculateBits(overwrite.allow) : "0", - deny: overwrite.deny ? bot.utils.calculateBits(overwrite.deny) : "0", - }; - }) + return { + ...overwrite, + allow: overwrite.allow ? bot.utils.calculateBits(overwrite.allow) : "0", + deny: overwrite.deny ? bot.utils.calculateBits(overwrite.deny) : "0", + }; + }) : undefined, reason, }); diff --git a/src/helpers/channels/editChannelOverwrite.ts b/src/helpers/channels/editChannelOverwrite.ts index b44bdb259..e47c9c654 100644 --- a/src/helpers/channels/editChannelOverwrite.ts +++ b/src/helpers/channels/editChannelOverwrite.ts @@ -6,7 +6,7 @@ export async function editChannelOverwrite( bot: Bot, channelId: bigint, overwriteId: bigint, - options: Omit + options: Omit, ) { await bot.rest.runMethod( bot.rest, @@ -16,6 +16,6 @@ export async function editChannelOverwrite( allow: options.allow ? bot.utils.calculateBits(options.allow) : "0", deny: options.deny ? bot.utils.calculateBits(options.deny) : "0", type: options.type, - } + }, ); } diff --git a/src/helpers/channels/followChannel.ts b/src/helpers/channels/followChannel.ts index 82948cead..8e8e44ca6 100644 --- a/src/helpers/channels/followChannel.ts +++ b/src/helpers/channels/followChannel.ts @@ -9,7 +9,7 @@ export async function followChannel(bot: Bot, sourceChannelId: bigint, targetCha bot.constants.endpoints.CHANNEL_FOLLOW(sourceChannelId), { webhook_channel_id: targetChannelId, - } + }, ); return bot.transformers.snowflake(data.webhook_id); diff --git a/src/helpers/channels/getChannelWebhooks.ts b/src/helpers/channels/getChannelWebhooks.ts index 6cec421a4..bf564cb4a 100644 --- a/src/helpers/channels/getChannelWebhooks.ts +++ b/src/helpers/channels/getChannelWebhooks.ts @@ -7,7 +7,7 @@ export async function getChannelWebhooks(bot: Bot, channelId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.CHANNEL_WEBHOOKS(channelId) + bot.constants.endpoints.CHANNEL_WEBHOOKS(channelId), ); return new Collection(result.map((webhook) => [webhook.id, webhook])); diff --git a/src/helpers/channels/getChannels.ts b/src/helpers/channels/getChannels.ts index d196083c7..dee5eba57 100644 --- a/src/helpers/channels/getChannels.ts +++ b/src/helpers/channels/getChannels.ts @@ -7,6 +7,6 @@ export async function getChannels(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_CHANNELS(guildId)); return new Collection( - result.map((res) => bot.transformers.channel(bot, { channel: res, guildId })).map((c) => [c.id, c]) + result.map((res) => bot.transformers.channel(bot, { channel: res, guildId })).map((c) => [c.id, c]), ); } diff --git a/src/helpers/channels/getStageInstance.ts b/src/helpers/channels/getStageInstance.ts index cc548ce98..48ae08ae3 100644 --- a/src/helpers/channels/getStageInstance.ts +++ b/src/helpers/channels/getStageInstance.ts @@ -6,7 +6,7 @@ export async function getStageInstance(bot: Bot, channelId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.STAGE_INSTANCE(channelId) + bot.constants.endpoints.STAGE_INSTANCE(channelId), ); return bot.transformers.stageInstance(bot, result); diff --git a/src/helpers/channels/swapChannels.ts b/src/helpers/channels/swapChannels.ts index aec44f2ea..d61d7ef43 100644 --- a/src/helpers/channels/swapChannels.ts +++ b/src/helpers/channels/swapChannels.ts @@ -18,6 +18,6 @@ export async function swapChannels(bot: Bot, guildId: bigint, channelPositions: lock_positions: channelPosition.lockPositions, parent_id: channelPosition.parentId, }; - }) + }), ); } diff --git a/src/helpers/channels/threads/getActiveThreads.ts b/src/helpers/channels/threads/getActiveThreads.ts index 9a6c07745..7c0252edc 100644 --- a/src/helpers/channels/threads/getActiveThreads.ts +++ b/src/helpers/channels/threads/getActiveThreads.ts @@ -8,7 +8,7 @@ export async function getActiveThreads(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.THREAD_ACTIVE(guildId) + bot.constants.endpoints.THREAD_ACTIVE(guildId), ); return { @@ -16,13 +16,13 @@ export async function getActiveThreads(bot: Bot, guildId: bigint) { result.threads.map((t) => { const thread = bot.transformers.channel(bot, { channel: t }); return [thread.id, thread]; - }) + }), ), members: new Collection( result.members.map((m) => { const member = bot.transformers.threadMember(bot, m); return [member.id, member]; - }) + }), ), }; } diff --git a/src/helpers/channels/threads/getArchivedThreads.ts b/src/helpers/channels/threads/getArchivedThreads.ts index d55b3a458..6558dd507 100644 --- a/src/helpers/channels/threads/getArchivedThreads.ts +++ b/src/helpers/channels/threads/getArchivedThreads.ts @@ -11,7 +11,7 @@ export async function getArchivedThreads( channelId: bigint, options?: ListPublicArchivedThreads & { type?: "public" | "private" | "privateJoinedThreads"; - } + }, ) { const result = (await bot.rest.runMethod( bot.rest, @@ -23,25 +23,25 @@ export async function getArchivedThreads( : bot.constants.endpoints.THREAD_ARCHIVED_PUBLIC(channelId), options ? { - before: options.before, - limit: options.limit, - type: options.type, - } - : {} + before: options.before, + limit: options.limit, + type: options.type, + } + : {}, )); - + return { threads: new Collection( result.threads.map((t) => { const thread = bot.transformers.channel(bot, { channel: t }); return [thread.id, thread]; - }) + }), ), members: new Collection( result.members.map((m) => { const member = bot.transformers.threadMember(bot, m); return [member.id, member]; - }) + }), ), - };; + }; } diff --git a/src/helpers/channels/threads/getThreadMember.ts b/src/helpers/channels/threads/getThreadMember.ts index ff409fb58..04be5f2c3 100644 --- a/src/helpers/channels/threads/getThreadMember.ts +++ b/src/helpers/channels/threads/getThreadMember.ts @@ -6,7 +6,7 @@ export async function getThreadMember(bot: Bot, threadId: bigint, userId: bigint const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.THREAD_USER(threadId, userId) + bot.constants.endpoints.THREAD_USER(threadId, userId), ); return { diff --git a/src/helpers/channels/threads/getThreadMembers.ts b/src/helpers/channels/threads/getThreadMembers.ts index 90eb0a19a..2b00ce0c8 100644 --- a/src/helpers/channels/threads/getThreadMembers.ts +++ b/src/helpers/channels/threads/getThreadMembers.ts @@ -6,7 +6,7 @@ export async function getThreadMembers(bot: Bot, threadId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.THREAD_MEMBERS(threadId) + bot.constants.endpoints.THREAD_MEMBERS(threadId), ); return result; diff --git a/src/helpers/channels/threads/startThreadWithMessage.ts b/src/helpers/channels/threads/startThreadWithMessage.ts index 77f09b3ba..61dbbf5b0 100644 --- a/src/helpers/channels/threads/startThreadWithMessage.ts +++ b/src/helpers/channels/threads/startThreadWithMessage.ts @@ -7,7 +7,7 @@ export async function startThreadWithMessage( bot: Bot, channelId: bigint, messageId: bigint, - options: StartThreadBase + options: StartThreadBase, ) { const result = await bot.rest.runMethod( bot.rest, @@ -16,7 +16,7 @@ export async function startThreadWithMessage( { name: options.name, auto_archive_duration: options.autoArchiveDuration, - } + }, ); return bot.transformers.channel(bot, { channel: result, guildId: bot.transformers.snowflake(result.guild_id!) }); diff --git a/src/helpers/channels/threads/startThreadWithoutMessage.ts b/src/helpers/channels/threads/startThreadWithoutMessage.ts index 94584f5ae..600bdb780 100644 --- a/src/helpers/channels/threads/startThreadWithoutMessage.ts +++ b/src/helpers/channels/threads/startThreadWithoutMessage.ts @@ -11,7 +11,7 @@ export async function startThreadWithoutMessage(bot: Bot, channelId: bigint, opt { name: options.name, auto_archive_duration: options.autoArchiveDuration, - } + }, ); return bot.transformers.channel(bot, { diff --git a/src/helpers/channels/updateStageInstance.ts b/src/helpers/channels/updateStageInstance.ts index 85cc3a76b..581e81468 100644 --- a/src/helpers/channels/updateStageInstance.ts +++ b/src/helpers/channels/updateStageInstance.ts @@ -10,7 +10,7 @@ export async function updateStageInstance(bot: Bot, channelId: bigint, data: AtL bot.constants.endpoints.STAGE_INSTANCE(channelId), { topic: data.topic, - } + }, ); return bot.transformers.stageInstance(bot, result); diff --git a/src/helpers/channels/updateVoiceState.ts b/src/helpers/channels/updateVoiceState.ts index 55fb15f3b..b11ed30af 100644 --- a/src/helpers/channels/updateVoiceState.ts +++ b/src/helpers/channels/updateVoiceState.ts @@ -42,6 +42,6 @@ export async function updateUserVoiceState(bot: Bot, guildId: bigint, options: U channel_id: options.channelId, suppress: options.suppress, user_id: options.userId, - } + }, ); } diff --git a/src/helpers/discovery/addDiscoverySubcategory.ts b/src/helpers/discovery/addDiscoverySubcategory.ts index 0107c863b..a089ed1ac 100644 --- a/src/helpers/discovery/addDiscoverySubcategory.ts +++ b/src/helpers/discovery/addDiscoverySubcategory.ts @@ -6,6 +6,6 @@ export async function addDiscoverySubcategory(bot: Bot, guildId: bigint, categor await bot.rest.runMethod( bot.rest, "post", - bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId) + bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId), ); } diff --git a/src/helpers/discovery/editDiscovery.ts b/src/helpers/discovery/editDiscovery.ts index f00027f24..10b32650b 100644 --- a/src/helpers/discovery/editDiscovery.ts +++ b/src/helpers/discovery/editDiscovery.ts @@ -12,7 +12,7 @@ export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuild primary_category_id: data.primaryCategoryId, keywords: data.keywords, emoji_discoverability_enabled: data.emojiDiscoverabilityEnabled, - } + }, ); return { diff --git a/src/helpers/discovery/getDiscovery.ts b/src/helpers/discovery/getDiscovery.ts index 3bcce91db..3bfaceaa6 100644 --- a/src/helpers/discovery/getDiscovery.ts +++ b/src/helpers/discovery/getDiscovery.ts @@ -6,7 +6,7 @@ export async function getDiscovery(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.DISCOVERY_METADATA(guildId) + bot.constants.endpoints.DISCOVERY_METADATA(guildId), ); return { diff --git a/src/helpers/discovery/getDiscoveryCategories.ts b/src/helpers/discovery/getDiscoveryCategories.ts index 09e5bb1e8..48a8bff5e 100644 --- a/src/helpers/discovery/getDiscoveryCategories.ts +++ b/src/helpers/discovery/getDiscoveryCategories.ts @@ -8,10 +8,10 @@ export async function getDiscoveryCategories(bot: Bot) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.DISCOVERY_CATEGORIES + bot.constants.endpoints.DISCOVERY_CATEGORIES, ); return new Collection>( - result.map((category) => [category.id, category]) + result.map((category) => [category.id, category]), ); } diff --git a/src/helpers/discovery/removeDiscoverySubcategory.ts b/src/helpers/discovery/removeDiscoverySubcategory.ts index f25b35d90..eba432147 100644 --- a/src/helpers/discovery/removeDiscoverySubcategory.ts +++ b/src/helpers/discovery/removeDiscoverySubcategory.ts @@ -5,6 +5,6 @@ export async function removeDiscoverySubcategory(bot: Bot, guildId: bigint, cate await bot.rest.runMethod( bot.rest, "delete", - bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId) + bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId), ); } diff --git a/src/helpers/discovery/validDiscoveryTerm.ts b/src/helpers/discovery/validDiscoveryTerm.ts index d8f0c1313..0475ccb74 100644 --- a/src/helpers/discovery/validDiscoveryTerm.ts +++ b/src/helpers/discovery/validDiscoveryTerm.ts @@ -7,7 +7,7 @@ export async function validDiscoveryTerm(bot: Bot, term: string) { bot.rest, "get", bot.constants.endpoints.DISCOVERY_VALID_TERM, - { term } + { term }, ); return result.valid; diff --git a/src/helpers/emojis/getEmoji.ts b/src/helpers/emojis/getEmoji.ts index 17287b174..f5ac5c820 100644 --- a/src/helpers/emojis/getEmoji.ts +++ b/src/helpers/emojis/getEmoji.ts @@ -9,7 +9,7 @@ export async function getEmoji(bot: Bot, guildId: bigint, emojiId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId) + bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId), ); return bot.transformers.emoji(bot, result); diff --git a/src/helpers/guilds/editGuild.ts b/src/helpers/guilds/editGuild.ts index 079c10621..24d505d35 100644 --- a/src/helpers/guilds/editGuild.ts +++ b/src/helpers/guilds/editGuild.ts @@ -20,7 +20,7 @@ export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild, bot.rest, "patch", bot.constants.endpoints.GUILDS_BASE(guildId), - options + options, ); return bot.transformers.guild(bot, { diff --git a/src/helpers/guilds/editWelcomeScreen.ts b/src/helpers/guilds/editWelcomeScreen.ts index 9d7601fc7..4281927d0 100644 --- a/src/helpers/guilds/editWelcomeScreen.ts +++ b/src/helpers/guilds/editWelcomeScreen.ts @@ -16,7 +16,7 @@ export async function editWelcomeScreen(bot: Bot, guildId: bigint, options: Modi emoji_name: welcomeScreen.emojiName, })), description: options.description, - } + }, ); return bot.transformers.welcomeScreen(bot, result); diff --git a/src/helpers/guilds/editWidget.ts b/src/helpers/guilds/editWidget.ts index 0135f2722..f0d3185a5 100644 --- a/src/helpers/guilds/editWidget.ts +++ b/src/helpers/guilds/editWidget.ts @@ -3,10 +3,15 @@ import type { Bot } from "../../bot.ts"; /** Modify a guild widget object for the guild. Requires the MANAGE_GUILD permission. */ export async function editWidget(bot: Bot, guildId: bigint, enabled: boolean, channelId?: string | null) { - const result = await bot.rest.runMethod(bot.rest, "patch", bot.constants.endpoints.GUILD_WIDGET(guildId), { - enabled, - channel_id: channelId, - }); + const result = await bot.rest.runMethod( + bot.rest, + "patch", + bot.constants.endpoints.GUILD_WIDGET(guildId), + { + enabled, + channel_id: channelId, + }, + ); return bot.transformers.widget(bot, result); } diff --git a/src/helpers/guilds/getAuditLogs.ts b/src/helpers/guilds/getAuditLogs.ts index c17c00cf7..b3707614e 100644 --- a/src/helpers/guilds/getAuditLogs.ts +++ b/src/helpers/guilds/getAuditLogs.ts @@ -12,7 +12,7 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild bot.rest, "get", bot.constants.endpoints.GUILD_AUDIT_LOGS(guildId), - options + options, ); return { @@ -39,13 +39,13 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild revoked: integration.revoked, application: integration.application ? { - id: bot.transformers.snowflake(integration.application.id), - name: integration.application.name, - icon: integration.application.icon ? bot.utils.iconHashToBigInt(integration.application.icon) : undefined, - description: integration.application.description, - summary: integration.application.summary, - bot: integration.application.bot ? bot.transformers.user(bot, integration.application.bot) : undefined, - } + id: bot.transformers.snowflake(integration.application.id), + name: integration.application.name, + icon: integration.application.icon ? bot.utils.iconHashToBigInt(integration.application.icon) : undefined, + description: integration.application.description, + summary: integration.application.summary, + bot: integration.application.bot ? bot.transformers.user(bot, integration.application.bot) : undefined, + } : undefined, })), threads: auditlog.threads.map((thread) => bot.transformers.channel(bot, { channel: thread, guildId })), diff --git a/src/helpers/guilds/getAvailableVoiceRegions.ts b/src/helpers/guilds/getAvailableVoiceRegions.ts index d1541582f..a8a21cf25 100644 --- a/src/helpers/guilds/getAvailableVoiceRegions.ts +++ b/src/helpers/guilds/getAvailableVoiceRegions.ts @@ -10,6 +10,6 @@ export async function getAvailableVoiceRegions(bot: Bot) { result.map((region) => { const voiceRegion = bot.transformers.voiceRegion(bot, region); return [voiceRegion.id, voiceRegion]; - }) + }), ); } diff --git a/src/helpers/guilds/getBans.ts b/src/helpers/guilds/getBans.ts index ef4dcbab9..22b442294 100644 --- a/src/helpers/guilds/getBans.ts +++ b/src/helpers/guilds/getBans.ts @@ -14,6 +14,6 @@ export async function getBans(bot: Bot, guildId: bigint) { reason: res.reason ?? undefined, user: bot.transformers.user(bot, res.user), }, - ]) + ]), ); } diff --git a/src/helpers/guilds/getGuild.ts b/src/helpers/guilds/getGuild.ts index d377319f2..5e9b51c7b 100644 --- a/src/helpers/guilds/getGuild.ts +++ b/src/helpers/guilds/getGuild.ts @@ -4,13 +4,13 @@ import type { Bot } from "../../bot.ts"; /** * This function fetches a guild's data. This is not the same data as a GUILD_CREATE. * So it does not cache the guild, you must do it manually. - * */ + */ export async function getGuild( bot: Bot, guildId: bigint, options: { counts?: boolean } = { counts: true, - } + }, ) { const result = await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILDS_BASE(guildId), { with_counts: options.counts, diff --git a/src/helpers/guilds/getGuildPreview.ts b/src/helpers/guilds/getGuildPreview.ts index 84a4a1cb8..f5d57e5e4 100644 --- a/src/helpers/guilds/getGuildPreview.ts +++ b/src/helpers/guilds/getGuildPreview.ts @@ -6,7 +6,7 @@ export async function getGuildPreview(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_PREVIEW(guildId) + bot.constants.endpoints.GUILD_PREVIEW(guildId), ); return { diff --git a/src/helpers/guilds/getPruneCount.ts b/src/helpers/guilds/getPruneCount.ts index 7dac554b5..3fcce2d86 100644 --- a/src/helpers/guilds/getPruneCount.ts +++ b/src/helpers/guilds/getPruneCount.ts @@ -14,10 +14,10 @@ export async function getPruneCount(bot: Bot, guildId: bigint, options?: GetGuil bot.constants.endpoints.GUILD_PRUNE(guildId), options ? { - days: options.days, - include_roles: options.includeRoles, - } - : {} + days: options.days, + include_roles: options.includeRoles, + } + : {}, ); return result.pruned as number; diff --git a/src/helpers/guilds/getVanityUrl.ts b/src/helpers/guilds/getVanityUrl.ts index 1ee1e0b86..8a43b7ed9 100644 --- a/src/helpers/guilds/getVanityUrl.ts +++ b/src/helpers/guilds/getVanityUrl.ts @@ -6,7 +6,7 @@ export async function getVanityUrl(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod>( bot.rest, "get", - bot.constants.endpoints.GUILD_VANITY_URL(guildId) + bot.constants.endpoints.GUILD_VANITY_URL(guildId), ); return { diff --git a/src/helpers/guilds/getVoiceRegions.ts b/src/helpers/guilds/getVoiceRegions.ts index 36f016665..1a55cae8d 100644 --- a/src/helpers/guilds/getVoiceRegions.ts +++ b/src/helpers/guilds/getVoiceRegions.ts @@ -7,13 +7,13 @@ export async function getVoiceRegions(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_REGIONS(guildId) + bot.constants.endpoints.GUILD_REGIONS(guildId), ); return new Collection( result.map((reg) => { const region = bot.transformers.voiceRegion(bot, reg); return [region.id, region]; - }) + }), ); } diff --git a/src/helpers/guilds/getWelcomeScreen.ts b/src/helpers/guilds/getWelcomeScreen.ts index 006096275..15f999cad 100644 --- a/src/helpers/guilds/getWelcomeScreen.ts +++ b/src/helpers/guilds/getWelcomeScreen.ts @@ -6,7 +6,7 @@ export async function getWelcomeScreen(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId) + bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId), ); return bot.transformers.welcomeScreen(bot, result); diff --git a/src/helpers/guilds/getWidget.ts b/src/helpers/guilds/getWidget.ts index c51cc0a58..7ca80927e 100644 --- a/src/helpers/guilds/getWidget.ts +++ b/src/helpers/guilds/getWidget.ts @@ -6,7 +6,7 @@ export async function getWidget(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - `${bot.constants.endpoints.GUILD_WIDGET(guildId)}.json` + `${bot.constants.endpoints.GUILD_WIDGET(guildId)}.json`, ); return { diff --git a/src/helpers/guilds/guildBannerUrl.ts b/src/helpers/guilds/guildBannerUrl.ts index 4469af30f..08f5e4b04 100644 --- a/src/helpers/guilds/guildBannerUrl.ts +++ b/src/helpers/guilds/guildBannerUrl.ts @@ -10,16 +10,16 @@ export function guildBannerURL( banner?: string | bigint; size?: ImageSize; format?: ImageFormat; - } + }, ) { return options.banner ? bot.utils.formatImageURL( - bot.constants.endpoints.GUILD_BANNER( - id, - typeof options.banner === "string" ? options.banner : bot.utils.iconBigintToHash(options.banner) - ), - options.size || 128, - options.format - ) + bot.constants.endpoints.GUILD_BANNER( + id, + typeof options.banner === "string" ? options.banner : bot.utils.iconBigintToHash(options.banner), + ), + options.size || 128, + options.format, + ) : undefined; } diff --git a/src/helpers/guilds/guildIconUrl.ts b/src/helpers/guilds/guildIconUrl.ts index fcd4d89c5..f69196f4c 100644 --- a/src/helpers/guilds/guildIconUrl.ts +++ b/src/helpers/guilds/guildIconUrl.ts @@ -10,16 +10,16 @@ export function guildIconURL( options?: { size?: ImageSize; format?: ImageFormat; - } + }, ) { return icon ? bot.utils.formatImageURL( - bot.constants.endpoints.GUILD_ICON( - id, - typeof icon === "string" ? icon : bot.utils.iconBigintToHash(icon) - ), - options?.size || 128, - options?.format - ) + bot.constants.endpoints.GUILD_ICON( + id, + typeof icon === "string" ? icon : bot.utils.iconBigintToHash(icon), + ), + options?.size || 128, + options?.format, + ) : undefined; } diff --git a/src/helpers/guilds/guildSplashUrl.ts b/src/helpers/guilds/guildSplashUrl.ts index defaa4930..1bb87886a 100644 --- a/src/helpers/guilds/guildSplashUrl.ts +++ b/src/helpers/guilds/guildSplashUrl.ts @@ -10,16 +10,16 @@ export function guildSplashURL( options?: { size?: ImageSize; format?: ImageFormat; - } + }, ) { return splash ? bot.utils.formatImageURL( - bot.constants.endpoints.GUILD_SPLASH( - id, - typeof splash === "string" ? splash : bot.utils.iconBigintToHash(splash) - ), - options?.size || 128, - options?.format - ) + bot.constants.endpoints.GUILD_SPLASH( + id, + typeof splash === "string" ? splash : bot.utils.iconBigintToHash(splash), + ), + options?.size || 128, + options?.format, + ) : undefined; } diff --git a/src/helpers/guilds/scheduledEvents/createScheduledEvent.ts b/src/helpers/guilds/scheduledEvents/createScheduledEvent.ts index 098bb2b68..a24e23626 100644 --- a/src/helpers/guilds/scheduledEvents/createScheduledEvent.ts +++ b/src/helpers/guilds/scheduledEvents/createScheduledEvent.ts @@ -8,15 +8,19 @@ import { /** Create a guild scheduled event in the guild. A guild can have a maximum of 100 events with `SCHEDULED` or `ACTIVE` status at any time. */ export async function createScheduledEvent(bot: Bot, guildId: bigint, options: CreateScheduledEvent) { - if (!bot.utils.validateLength(options.name, { min: 1, max: 100 })) + if (!bot.utils.validateLength(options.name, { min: 1, max: 100 })) { throw new Error("Name must be between 1-100 characters."); - if (options.description && !bot.utils.validateLength(options.description, { max: 1000 })) + } + if (options.description && !bot.utils.validateLength(options.description, { max: 1000 })) { throw new Error("Description must be below 1000 characters."); + } if (options.location) { - if (!bot.utils.validateLength(options.location, { max: 100 })) + if (!bot.utils.validateLength(options.location, { max: 100 })) { throw new Error("Location must be below 100 characters."); - if (options.entityType === ScheduledEventEntityType.Voice) + } + if (options.entityType === ScheduledEventEntityType.Voice) { throw new Error("Location can not be provided for a Voice event."); + } } if (options.entityType === ScheduledEventEntityType.External) { if (!options.scheduledEndTime) throw new Error("A scheduled end time is required when making an External event."); @@ -40,7 +44,7 @@ export async function createScheduledEvent(bot: Bot, guildId: bigint, options: C privacy_level: options.privacyLevel || ScheduledEventPrivacyLevel.GuildOnly, entity_type: options.entityType, reason: options.reason, - } + }, ); return bot.transformers.scheduledEvent(bot, event); diff --git a/src/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts b/src/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts index b440e4351..748499ffc 100644 --- a/src/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts +++ b/src/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts @@ -5,6 +5,6 @@ export async function deleteScheduledEvent(bot: Bot, guildId: bigint, eventId: b await bot.rest.runMethod( bot.rest, "delete", - bot.constants.endpoints.GUILD_SCHEDULED_EVENT(guildId, eventId) + bot.constants.endpoints.GUILD_SCHEDULED_EVENT(guildId, eventId), ); } diff --git a/src/helpers/guilds/scheduledEvents/editScheduledEvent.ts b/src/helpers/guilds/scheduledEvents/editScheduledEvent.ts index 9d66fb9fc..8be0390c2 100644 --- a/src/helpers/guilds/scheduledEvents/editScheduledEvent.ts +++ b/src/helpers/guilds/scheduledEvents/editScheduledEvent.ts @@ -6,14 +6,17 @@ export async function editScheduledEvent( bot: Bot, guildId: bigint, eventId: bigint, - options: Partial + options: Partial, ) { - if (options.name && !bot.utils.validateLength(options.name, { min: 1, max: 100 })) + if (options.name && !bot.utils.validateLength(options.name, { min: 1, max: 100 })) { throw new Error("Name must be between 1-100 characters."); - if (options.description && !bot.utils.validateLength(options.description, { max: 1000 })) + } + if (options.description && !bot.utils.validateLength(options.description, { max: 1000 })) { throw new Error("Description must be below 1000 characters."); - if (options.location && !bot.utils.validateLength(options.location, { max: 100 })) + } + if (options.location && !bot.utils.validateLength(options.location, { max: 100 })) { throw new Error("Location must be below 100 characters."); + } if (options.scheduledStartTime && options.scheduledEndTime && options.scheduledStartTime > options.scheduledEndTime) { throw new Error("Cannot schedule event to end before starting."); } @@ -33,7 +36,7 @@ export async function editScheduledEvent( entity_type: options.entityType, status: options.status, reason: options.reason, - } + }, ); return bot.transformers.scheduledEvent(bot, event); diff --git a/src/helpers/guilds/scheduledEvents/getScheduledEvent.ts b/src/helpers/guilds/scheduledEvents/getScheduledEvent.ts index 706af90fb..e6bbd89d4 100644 --- a/src/helpers/guilds/scheduledEvents/getScheduledEvent.ts +++ b/src/helpers/guilds/scheduledEvents/getScheduledEvent.ts @@ -2,12 +2,17 @@ import { Bot } from "../../../bot.ts"; import { ScheduledEvent } from "../../../types/guilds/scheduledEvents.ts"; /** Get a guild scheduled event. */ -export async function getScheduledEvent(bot: Bot, guildId: bigint, eventId: bigint, options?: { withUserCount?: boolean }) { +export async function getScheduledEvent( + bot: Bot, + guildId: bigint, + eventId: bigint, + options?: { withUserCount?: boolean }, +) { const event = await bot.rest.runMethod( bot.rest, "get", bot.constants.endpoints.GUILD_SCHEDULED_EVENT(guildId, eventId), - { with_user_count: options?.withUserCount || false} + { with_user_count: options?.withUserCount || false }, ); return bot.transformers.scheduledEvent(bot, event); diff --git a/src/helpers/guilds/scheduledEvents/getScheduledEventUsers.ts b/src/helpers/guilds/scheduledEvents/getScheduledEventUsers.ts index bd63b3eea..bb8ae9e13 100644 --- a/src/helpers/guilds/scheduledEvents/getScheduledEventUsers.ts +++ b/src/helpers/guilds/scheduledEvents/getScheduledEventUsers.ts @@ -9,19 +9,19 @@ export async function getScheduledEventUsers( bot: Bot, guildId: bigint, eventId: bigint, - options?: GetScheduledEventUsers & { withMember?: false } + options?: GetScheduledEventUsers & { withMember?: false }, ): Promise>; export async function getScheduledEventUsers( bot: Bot, guildId: bigint, eventId: bigint, - options?: GetScheduledEventUsers & { withMember: true } + options?: GetScheduledEventUsers & { withMember: true }, ): Promise>; export async function getScheduledEventUsers( bot: Bot, guildId: bigint, eventId: bigint, - options?: GetScheduledEventUsers + options?: GetScheduledEventUsers, ): Promise< Collection | Collection > { @@ -34,7 +34,7 @@ export async function getScheduledEventUsers( { limit: options?.limit, with_members: options?.withMember, - } + }, ); if (!options?.withMember) { @@ -42,7 +42,7 @@ export async function getScheduledEventUsers( result.map((res) => { const user = bot.transformers.user(bot, res.user); return [user.id, user]; - }) + }), ); } @@ -52,6 +52,6 @@ export async function getScheduledEventUsers( const member = bot.transformers.member(bot, res.member!, guildId, user.id); return [user.id, { member, user }]; - }) + }), ); } diff --git a/src/helpers/guilds/scheduledEvents/getScheduledEvents.ts b/src/helpers/guilds/scheduledEvents/getScheduledEvents.ts index 0a1a916c7..0cc5ab440 100644 --- a/src/helpers/guilds/scheduledEvents/getScheduledEvents.ts +++ b/src/helpers/guilds/scheduledEvents/getScheduledEvents.ts @@ -10,14 +10,14 @@ export async function getScheduledEvents(bot: Bot, guildId: bigint, options?: Ge "get", bot.constants.endpoints.GUILD_SCHEDULED_EVENTS(guildId), { - with_user_count: options?.withUserCount, - } + with_user_count: options?.withUserCount, + }, ); return new Collection( events.map((e) => { const event = bot.transformers.scheduledEvent(bot, e); return [event.id, event]; - }) + }), ); } diff --git a/src/helpers/integrations/getIntegrations.ts b/src/helpers/integrations/getIntegrations.ts index 4736d3d0e..ac685f85e 100644 --- a/src/helpers/integrations/getIntegrations.ts +++ b/src/helpers/integrations/getIntegrations.ts @@ -7,7 +7,7 @@ export async function getIntegrations(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_INTEGRATIONS(guildId) + bot.constants.endpoints.GUILD_INTEGRATIONS(guildId), ); return new Collection( @@ -31,6 +31,6 @@ export async function getIntegrations(bot: Bot, guildId: bigint) { application: res.application, }); return [integration.id, integration]; - }) + }), ); } diff --git a/src/helpers/interactions/commands/batchEditApplicationCommandPermissions.ts b/src/helpers/interactions/commands/batchEditApplicationCommandPermissions.ts index 11d3dd5ea..ed61e0544 100644 --- a/src/helpers/interactions/commands/batchEditApplicationCommandPermissions.ts +++ b/src/helpers/interactions/commands/batchEditApplicationCommandPermissions.ts @@ -6,13 +6,13 @@ import { GuildApplicationCommandPermissions } from "../../../types/interactions/ export async function batchEditApplicationCommandPermissions( bot: Bot, guildId: bigint, - options: { id: string; permissions: ApplicationCommandPermissions[] }[] + options: { id: string; permissions: ApplicationCommandPermissions[] }[], ) { const result = await bot.rest.runMethod( bot.rest, "put", bot.constants.endpoints.COMMANDS_PERMISSIONS(bot.applicationId, guildId), - options + options, ); return result.map((res) => bot.transformers.applicationCommandPermission(bot, res)); diff --git a/src/helpers/interactions/commands/createApplicationCommand.ts b/src/helpers/interactions/commands/createApplicationCommand.ts index fea31422c..552d5dedf 100644 --- a/src/helpers/interactions/commands/createApplicationCommand.ts +++ b/src/helpers/interactions/commands/createApplicationCommand.ts @@ -26,7 +26,7 @@ export async function createApplicationCommand(bot: Bot, options: CreateApplicat description: options.description, type: options.type, options: options.options ? makeOptionsForCommand(options.options) : undefined, - } + }, ); return bot.transformers.applicationCommand(bot, result); diff --git a/src/helpers/interactions/commands/deleteApplicationCommand.ts b/src/helpers/interactions/commands/deleteApplicationCommand.ts index 073727b2d..874083535 100644 --- a/src/helpers/interactions/commands/deleteApplicationCommand.ts +++ b/src/helpers/interactions/commands/deleteApplicationCommand.ts @@ -7,6 +7,6 @@ export async function deleteApplicationCommand(bot: Bot, id: bigint, guildId?: b "delete", guildId ? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, id) - : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, id) + : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, id), ); } diff --git a/src/helpers/interactions/commands/deleteInteractionResponse.ts b/src/helpers/interactions/commands/deleteInteractionResponse.ts index 353cdd58a..e6de957e9 100644 --- a/src/helpers/interactions/commands/deleteInteractionResponse.ts +++ b/src/helpers/interactions/commands/deleteInteractionResponse.ts @@ -7,6 +7,6 @@ export async function deleteInteractionResponse(bot: Bot, token: string, message "delete", messageId ? bot.constants.endpoints.INTERACTION_ID_TOKEN_MESSAGE_ID(bot.applicationId, token, messageId) - : bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token) + : bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token), ); } diff --git a/src/helpers/interactions/commands/editApplicationCommandPermissions.ts b/src/helpers/interactions/commands/editApplicationCommandPermissions.ts index 52104b03c..1fc915185 100644 --- a/src/helpers/interactions/commands/editApplicationCommandPermissions.ts +++ b/src/helpers/interactions/commands/editApplicationCommandPermissions.ts @@ -7,7 +7,7 @@ export async function editApplicationCommandPermissions( bot: Bot, guildId: bigint, commandId: bigint, - options: ApplicationCommandPermissions[] + options: ApplicationCommandPermissions[], ) { const result = await bot.rest.runMethod( bot.rest, @@ -15,7 +15,7 @@ export async function editApplicationCommandPermissions( bot.constants.endpoints.COMMANDS_PERMISSION(bot.applicationId, guildId, commandId), { permissions: options, - } + }, ); return bot.transformers.applicationCommandPermission(bot, result); diff --git a/src/helpers/interactions/commands/editInteractionResponse.ts b/src/helpers/interactions/commands/editInteractionResponse.ts index 80b2109e3..b397d77ed 100644 --- a/src/helpers/interactions/commands/editInteractionResponse.ts +++ b/src/helpers/interactions/commands/editInteractionResponse.ts @@ -17,11 +17,11 @@ export async function editInteractionResponse(bot: Bot, token: string, options: file: options.file, allowed_mentions: options.allowedMentions ? { - parse: options.allowedMentions.parse, - roles: options.allowedMentions.roles?.map((id) => id.toString()), - users: options.allowedMentions.users?.map((id) => id.toString()), - replied_user: options.allowedMentions.repliedUser, - } + parse: options.allowedMentions.parse, + roles: options.allowedMentions.roles?.map((id) => id.toString()), + users: options.allowedMentions.users?.map((id) => id.toString()), + replied_user: options.allowedMentions.repliedUser, + } : undefined, attachments: options.attachments?.map((attachment) => ({ id: attachment.id.toString(), @@ -49,7 +49,7 @@ export async function editInteractionResponse(bot: Bot, token: string, options: }; } - if (subcomponent.type === MessageComponentTypes.SelectMenu) + if (subcomponent.type === MessageComponentTypes.SelectMenu) { return { type: subcomponent.type, custom_id: subcomponent.customId, @@ -62,35 +62,35 @@ export async function editInteractionResponse(bot: Bot, token: string, options: description: option.description, emoji: option.emoji ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } + id: option.emoji.id?.toString(), + name: option.emoji.name, + animated: option.emoji.animated, + } : undefined, default: option.default, })), }; + } return { type: subcomponent.type, custom_id: subcomponent.customId, label: subcomponent.label, style: subcomponent.style, - emoji: - "emoji" in subcomponent && subcomponent.emoji - ? { - id: subcomponent.emoji.id?.toString(), - name: subcomponent.emoji.name, - animated: subcomponent.emoji.animated, - } - : undefined, + emoji: "emoji" in subcomponent && subcomponent.emoji + ? { + id: subcomponent.emoji.id?.toString(), + name: subcomponent.emoji.name, + animated: subcomponent.emoji.animated, + } + : undefined, url: "url" in subcomponent ? subcomponent.url : undefined, disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, }; }), })), message_id: options.messageId?.toString(), - } + }, ); // If the original message was edited, this will not return a message diff --git a/src/helpers/interactions/commands/getApplicationCommand.ts b/src/helpers/interactions/commands/getApplicationCommand.ts index 6622a02cb..5c27470c9 100644 --- a/src/helpers/interactions/commands/getApplicationCommand.ts +++ b/src/helpers/interactions/commands/getApplicationCommand.ts @@ -8,7 +8,7 @@ export async function getApplicationCommand(bot: Bot, commandId: bigint, guildId "get", guildId ? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, commandId) - : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, commandId) + : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, commandId), ); return bot.transformers.applicationCommand(bot, result); diff --git a/src/helpers/interactions/commands/getApplicationCommandPermission.ts b/src/helpers/interactions/commands/getApplicationCommandPermission.ts index 86e2ed419..31f4eff2e 100644 --- a/src/helpers/interactions/commands/getApplicationCommandPermission.ts +++ b/src/helpers/interactions/commands/getApplicationCommandPermission.ts @@ -6,7 +6,7 @@ export async function getApplicationCommandPermission(bot: Bot, guildId: bigint, const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.COMMANDS_PERMISSION(bot.applicationId, guildId, commandId) + bot.constants.endpoints.COMMANDS_PERMISSION(bot.applicationId, guildId, commandId), ); return bot.transformers.applicationCommandPermission(bot, result); diff --git a/src/helpers/interactions/commands/getApplicationCommandPermissions.ts b/src/helpers/interactions/commands/getApplicationCommandPermissions.ts index adac57736..515da9d17 100644 --- a/src/helpers/interactions/commands/getApplicationCommandPermissions.ts +++ b/src/helpers/interactions/commands/getApplicationCommandPermissions.ts @@ -7,13 +7,13 @@ export async function getApplicationCommandPermissions(bot: Bot, guildId: bigint const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.COMMANDS_PERMISSIONS(bot.applicationId, guildId) + bot.constants.endpoints.COMMANDS_PERMISSIONS(bot.applicationId, guildId), ); return new Collection( result.map((res) => { const perms = bot.transformers.applicationCommandPermission(bot, res); return [perms.id, perms]; - }) + }), ); } diff --git a/src/helpers/interactions/commands/getApplicationCommands.ts b/src/helpers/interactions/commands/getApplicationCommands.ts index 4af891a24..29c242463 100644 --- a/src/helpers/interactions/commands/getApplicationCommands.ts +++ b/src/helpers/interactions/commands/getApplicationCommands.ts @@ -9,13 +9,13 @@ export async function getApplicationCommands(bot: Bot, guildId?: bigint) { "get", guildId ? bot.constants.endpoints.COMMANDS_GUILD(bot.applicationId, guildId) - : bot.constants.endpoints.COMMANDS(bot.applicationId) + : bot.constants.endpoints.COMMANDS(bot.applicationId), ); return new Collection( result.map((res) => { const command = bot.transformers.applicationCommand(bot, res); return [command.id, command]; - }) + }), ); } diff --git a/src/helpers/interactions/commands/upsertApplicationCommand.ts b/src/helpers/interactions/commands/upsertApplicationCommand.ts index 0d00b715b..411ac228c 100644 --- a/src/helpers/interactions/commands/upsertApplicationCommand.ts +++ b/src/helpers/interactions/commands/upsertApplicationCommand.ts @@ -10,7 +10,7 @@ export async function upsertApplicationCommand( bot: Bot, commandId: bigint, options: EditGlobalApplicationCommand, - guildId?: bigint + guildId?: bigint, ) { const result = await bot.rest.runMethod( bot.rest, @@ -23,7 +23,7 @@ export async function upsertApplicationCommand( description: options.description, type: options.type, options: options.options ? makeOptionsForCommand(options.options) : undefined, - } + }, ); return bot.transformers.applicationCommand(bot, result); diff --git a/src/helpers/interactions/commands/upsertApplicationCommands.ts b/src/helpers/interactions/commands/upsertApplicationCommands.ts index b47f668e3..3c454e3f6 100644 --- a/src/helpers/interactions/commands/upsertApplicationCommands.ts +++ b/src/helpers/interactions/commands/upsertApplicationCommands.ts @@ -14,7 +14,7 @@ import { makeOptionsForCommand } from "./createApplicationCommand.ts"; export async function upsertApplicationCommands( bot: Bot, options: MakeRequired[], - guildId?: bigint + guildId?: bigint, ) { const result = await bot.rest.runMethod( bot.rest, @@ -28,13 +28,13 @@ export async function upsertApplicationCommands( type: option.type, options: option.options ? makeOptionsForCommand(option.options) : undefined, default_permission: option.defaultPermission, - })) + })), ); return new Collection( result.map((res) => { const command = bot.transformers.applicationCommand(bot, res); return [command.id, command]; - }) + }), ); } diff --git a/src/helpers/interactions/followups/deleteFollowupMessage.ts b/src/helpers/interactions/followups/deleteFollowupMessage.ts index c35af735d..918c1135e 100644 --- a/src/helpers/interactions/followups/deleteFollowupMessage.ts +++ b/src/helpers/interactions/followups/deleteFollowupMessage.ts @@ -5,6 +5,6 @@ export async function deleteFollowupMessage(bot: Bot, interactionToken: string, await bot.rest.runMethod( bot.rest, "delete", - bot.constants.endpoints.WEBHOOK_MESSAGE(bot.applicationId, interactionToken, messageId) + bot.constants.endpoints.WEBHOOK_MESSAGE(bot.applicationId, interactionToken, messageId), ); } diff --git a/src/helpers/interactions/followups/editFollowupMessage.ts b/src/helpers/interactions/followups/editFollowupMessage.ts index 0ec094846..6b649940b 100644 --- a/src/helpers/interactions/followups/editFollowupMessage.ts +++ b/src/helpers/interactions/followups/editFollowupMessage.ts @@ -9,7 +9,7 @@ export async function editFollowupMessage( bot: Bot, interactionToken: string, messageId: bigint, - options: EditWebhookMessage + options: EditWebhookMessage, ) { const result = await bot.rest.runMethod( bot.rest, @@ -21,11 +21,11 @@ export async function editFollowupMessage( file: options.file, allowed_mentions: options.allowedMentions ? { - parse: options.allowedMentions.parse, - roles: options.allowedMentions.roles?.map((id) => id.toString()), - users: options.allowedMentions.users?.map((id) => id.toString()), - replied_user: options.allowedMentions.repliedUser, - } + parse: options.allowedMentions.parse, + roles: options.allowedMentions.roles?.map((id) => id.toString()), + users: options.allowedMentions.users?.map((id) => id.toString()), + replied_user: options.allowedMentions.repliedUser, + } : undefined, attachments: options.attachments?.map((attachment) => ({ id: attachment.id.toString(), @@ -53,7 +53,7 @@ export async function editFollowupMessage( }; } - if (subcomponent.type === MessageComponentTypes.SelectMenu) + if (subcomponent.type === MessageComponentTypes.SelectMenu) { return { type: subcomponent.type, custom_id: subcomponent.customId, @@ -66,14 +66,15 @@ export async function editFollowupMessage( description: option.description, emoji: option.emoji ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } + id: option.emoji.id?.toString(), + name: option.emoji.name, + animated: option.emoji.animated, + } : undefined, default: option.default, })), }; + } return { type: subcomponent.type, @@ -82,10 +83,10 @@ export async function editFollowupMessage( style: subcomponent.style, emoji: subcomponent.emoji ? { - id: subcomponent.emoji.id?.toString(), - name: subcomponent.emoji.name, - animated: subcomponent.emoji.animated, - } + id: subcomponent.emoji.id?.toString(), + name: subcomponent.emoji.name, + animated: subcomponent.emoji.animated, + } : undefined, url: subcomponent.url, disabled: subcomponent.disabled, @@ -93,7 +94,7 @@ export async function editFollowupMessage( }), })), message_id: messageId?.toString(), - } + }, ); return bot.transformers.message(bot, result); diff --git a/src/helpers/interactions/followups/getFollowupMessage.ts b/src/helpers/interactions/followups/getFollowupMessage.ts index d32977d10..9c97d8516 100644 --- a/src/helpers/interactions/followups/getFollowupMessage.ts +++ b/src/helpers/interactions/followups/getFollowupMessage.ts @@ -6,7 +6,7 @@ export async function getFollowupMessage(bot: Bot, interactionToken: string, mes const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.WEBHOOK_MESSAGE(bot.applicationId, interactionToken, messageId) + bot.constants.endpoints.WEBHOOK_MESSAGE(bot.applicationId, interactionToken, messageId), ); return bot.transformers.message(bot, result); diff --git a/src/helpers/interactions/getOriginalInteractionResponse.ts b/src/helpers/interactions/getOriginalInteractionResponse.ts index 021875659..a54141c2e 100644 --- a/src/helpers/interactions/getOriginalInteractionResponse.ts +++ b/src/helpers/interactions/getOriginalInteractionResponse.ts @@ -7,7 +7,7 @@ export async function getOriginalInteractionResponse(bot: Bot, token: string) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token) + bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token), ); return bot.transformers.message(bot, result); diff --git a/src/helpers/interactions/sendInteractionResponse.ts b/src/helpers/interactions/sendInteractionResponse.ts index c81848bec..0a2dcecbe 100644 --- a/src/helpers/interactions/sendInteractionResponse.ts +++ b/src/helpers/interactions/sendInteractionResponse.ts @@ -13,7 +13,7 @@ export async function sendInteractionResponse( bot: Bot, id: bigint, token: string, - options: DiscordenoInteractionResponse + options: DiscordenoInteractionResponse, ) { // If the user wants this as a private message mark it ephemeral if (options.private) { @@ -38,43 +38,43 @@ export async function sendInteractionResponse( color: embed.color, footer: embed.footer ? { - text: embed.footer.text, - icon_url: embed.footer.iconUrl, - proxy_icon_url: embed.footer.proxyIconUrl, - } + text: embed.footer.text, + icon_url: embed.footer.iconUrl, + proxy_icon_url: embed.footer.proxyIconUrl, + } : undefined, image: embed.image ? { - url: embed.image.url, - proxy_url: embed.image.proxyUrl, - height: embed.image.height, - width: embed.image.width, - } + url: embed.image.url, + proxy_url: embed.image.proxyUrl, + height: embed.image.height, + width: embed.image.width, + } : undefined, thumbnail: embed.thumbnail ? { - url: embed.thumbnail.url, - proxy_url: embed.thumbnail.proxyUrl, - height: embed.thumbnail.height, - width: embed.thumbnail.width, - } + url: embed.thumbnail.url, + proxy_url: embed.thumbnail.proxyUrl, + height: embed.thumbnail.height, + width: embed.thumbnail.width, + } : undefined, video: embed.video ? { - url: embed.video.url, - proxy_url: embed.video.proxyUrl, - height: embed.video.height, - width: embed.video.width, - } + url: embed.video.url, + proxy_url: embed.video.proxyUrl, + height: embed.video.height, + width: embed.video.width, + } : undefined, provider: embed.provider, author: embed.author ? { - name: embed.author.name, - url: embed.author.url, - icon_url: embed.author.iconUrl, - proxy_icon_url: embed.author.proxyIconUrl, - } + name: embed.author.name, + url: embed.author.url, + icon_url: embed.author.iconUrl, + proxy_icon_url: embed.author.proxyIconUrl, + } : undefined, fields: embed.fields, })), @@ -102,7 +102,7 @@ export async function sendInteractionResponse( }; } - if (subcomponent.type === MessageComponentTypes.SelectMenu) + if (subcomponent.type === MessageComponentTypes.SelectMenu) { return { type: subcomponent.type, custom_id: subcomponent.customId, @@ -115,28 +115,28 @@ export async function sendInteractionResponse( description: option.description, emoji: option.emoji ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } + id: option.emoji.id?.toString(), + name: option.emoji.name, + animated: option.emoji.animated, + } : undefined, default: option.default, })), }; + } return { type: subcomponent.type, custom_id: subcomponent.customId, label: subcomponent.label, style: subcomponent.style, - emoji: - "emoji" in subcomponent && subcomponent.emoji - ? { - id: subcomponent.emoji.id?.toString(), - name: subcomponent.emoji.name, - animated: subcomponent.emoji.animated, - } - : undefined, + emoji: "emoji" in subcomponent && subcomponent.emoji + ? { + id: subcomponent.emoji.id?.toString(), + name: subcomponent.emoji.name, + animated: subcomponent.emoji.animated, + } + : undefined, url: "url" in subcomponent ? subcomponent.url : undefined, disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, }; @@ -148,14 +148,24 @@ export async function sendInteractionResponse( // A reply has never been send if (bot.cache.unrepliedInteractions.delete(id)) { - return await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.INTERACTION_ID_TOKEN(id, token), { - type: options.type, - data, - }); + return await bot.rest.runMethod( + bot.rest, + "post", + bot.constants.endpoints.INTERACTION_ID_TOKEN(id, token), + { + type: options.type, + data, + }, + ); } // If its already been executed, we need to send a followup response - const result = await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.WEBHOOK(bot.applicationId, token), data); + const result = await bot.rest.runMethod( + bot.rest, + "post", + bot.constants.endpoints.WEBHOOK(bot.applicationId, token), + data, + ); return bot.transformers.message(bot, result); } diff --git a/src/helpers/interactions/verifySignature.ts b/src/helpers/interactions/verifySignature.ts index f062d6be0..51e3e88e4 100644 --- a/src/helpers/interactions/verifySignature.ts +++ b/src/helpers/interactions/verifySignature.ts @@ -7,7 +7,7 @@ export function verifySignature({ publicKey, signature, timestamp, body }: Verif const isValid = verify( hexToUint8Array(publicKey), hexToUint8Array(signature), - new TextEncoder().encode(timestamp + body) + new TextEncoder().encode(timestamp + body), ); return { isValid, body }; diff --git a/src/helpers/invites/createInvite.ts b/src/helpers/invites/createInvite.ts index 1a59b7bc5..1cf4a91be 100644 --- a/src/helpers/invites/createInvite.ts +++ b/src/helpers/invites/createInvite.ts @@ -16,7 +16,7 @@ export async function createInvite(bot: Bot, channelId: bigint, options: CreateC target_type: options.targetType, target_user_id: options.targetUserId, target_application_id: options.targetUserId, - } + }, ); return { diff --git a/src/helpers/invites/getChannelInvites.ts b/src/helpers/invites/getChannelInvites.ts index 4341416ec..fc620be05 100644 --- a/src/helpers/invites/getChannelInvites.ts +++ b/src/helpers/invites/getChannelInvites.ts @@ -7,7 +7,7 @@ export async function getChannelInvites(bot: Bot, channelId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.CHANNEL_INVITES(channelId) + bot.constants.endpoints.CHANNEL_INVITES(channelId), ); return new Collection( @@ -20,6 +20,6 @@ export async function getChannelInvites(bot: Bot, channelId: bigint) { temporary: invite.temporary, createdAt: Date.parse(invite.created_at), }, - ]) + ]), ); } diff --git a/src/helpers/invites/getInvites.ts b/src/helpers/invites/getInvites.ts index a828fcde9..055f96031 100644 --- a/src/helpers/invites/getInvites.ts +++ b/src/helpers/invites/getInvites.ts @@ -8,7 +8,7 @@ export async function getInvites(bot: Bot, guildId: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_INVITES(guildId) + bot.constants.endpoints.GUILD_INVITES(guildId), ); return new Collection( @@ -21,6 +21,6 @@ export async function getInvites(bot: Bot, guildId: bigint) { temporary: invite.temporary, createdAt: Date.parse(invite.created_at), }, - ]) + ]), ); } diff --git a/src/helpers/members/avatarUrl.ts b/src/helpers/members/avatarUrl.ts index 4bbd15d87..3dd7518b8 100644 --- a/src/helpers/members/avatarUrl.ts +++ b/src/helpers/members/avatarUrl.ts @@ -11,16 +11,16 @@ export function avatarURL( avatar: bigint | undefined; size?: ImageSize; format?: ImageFormat; - } + }, ) { return options?.avatar ? bot.utils.formatImageURL( - bot.constants.endpoints.USER_AVATAR( - userId, - typeof options?.avatar === "string" ? options.avatar : bot.utils.iconBigintToHash(options?.avatar) - ), - options?.size || 128, - options?.format - ) + bot.constants.endpoints.USER_AVATAR( + userId, + typeof options?.avatar === "string" ? options.avatar : bot.utils.iconBigintToHash(options?.avatar), + ), + options?.size || 128, + options?.format, + ) : bot.constants.endpoints.USER_DEFAULT_AVATAR(Number(discriminator) % 5); } diff --git a/src/helpers/members/banMember.ts b/src/helpers/members/banMember.ts index e0e7cad44..ebb63a09e 100644 --- a/src/helpers/members/banMember.ts +++ b/src/helpers/members/banMember.ts @@ -9,9 +9,9 @@ export async function banMember(bot: Bot, guildId: bigint, id: bigint, options?: bot.constants.endpoints.GUILD_BAN(guildId, id), options ? { - delete_message_days: options.deleteMessageDays, - reason: options.reason, - } - : {} + delete_message_days: options.deleteMessageDays, + reason: options.reason, + } + : {}, ); } diff --git a/src/helpers/members/editBotNickname.ts b/src/helpers/members/editBotNickname.ts index 5b5d918a5..16e2db266 100644 --- a/src/helpers/members/editBotNickname.ts +++ b/src/helpers/members/editBotNickname.ts @@ -6,7 +6,7 @@ export async function editBotNickname(bot: Bot, guildId: bigint, options: { nick bot.rest, "patch", bot.constants.endpoints.USER_NICK(guildId), - options + options, ); return response.nick; diff --git a/src/helpers/members/editMember.ts b/src/helpers/members/editMember.ts index 0e8402136..d7be0c2a9 100644 --- a/src/helpers/members/editMember.ts +++ b/src/helpers/members/editMember.ts @@ -15,7 +15,7 @@ export async function editMember(bot: Bot, guildId: bigint, memberId: bigint, op deaf: options.deaf, channel_id: options.channelId, communication_disabled_until: options.communicationDisabledUntil, - } + }, ); return bot.transformers.member(bot, result, guildId, memberId); diff --git a/src/helpers/members/fetchMembers.ts b/src/helpers/members/fetchMembers.ts index f941bdcdd..fd0055d69 100644 --- a/src/helpers/members/fetchMembers.ts +++ b/src/helpers/members/fetchMembers.ts @@ -14,7 +14,7 @@ export function fetchMembers( bot: Bot, guildId: bigint, shardId: number, - options?: Omit + options?: Omit, ) { // You can request 1 member without the intent // Check if intents is not 0 as proxy ws won't set intents in other instances diff --git a/src/helpers/members/getDmChannel.ts b/src/helpers/members/getDmChannel.ts index 8411c8ea2..373121074 100644 --- a/src/helpers/members/getDmChannel.ts +++ b/src/helpers/members/getDmChannel.ts @@ -8,6 +8,6 @@ export async function getDmChannel(bot: Bot, userId: bigint) { const dmChannelData = await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.USER_DM, { recipient_id: userId.toString(), }); - + return bot.transformers.channel(bot, { channel: dmChannelData }); } diff --git a/src/helpers/members/getMember.ts b/src/helpers/members/getMember.ts index 1b38cab8d..de3f7f893 100644 --- a/src/helpers/members/getMember.ts +++ b/src/helpers/members/getMember.ts @@ -9,7 +9,7 @@ export async function getMember(bot: Bot, guildId: bigint, id: bigint) { const data = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_MEMBER(guildId, id) + bot.constants.endpoints.GUILD_MEMBER(guildId, id), ); return bot.transformers.member(bot, data, guildId, id); diff --git a/src/helpers/members/getMembers.ts b/src/helpers/members/getMembers.ts index a4c14ea90..035e5dfb3 100644 --- a/src/helpers/members/getMembers.ts +++ b/src/helpers/members/getMembers.ts @@ -17,13 +17,13 @@ export async function getMembers(bot: Bot, guildId: bigint, options: ListGuildMe { limit: options?.limit ?? options.memberCount, after: options?.after, - } + }, ); return new Collection( result.map((res) => { const member = bot.transformers.member(bot, res, guildId, bot.transformers.snowflake(res.user.id)); return [member.id, member]; - }) + }), ); } diff --git a/src/helpers/members/pruneMembers.ts b/src/helpers/members/pruneMembers.ts index a25342c77..e10fcf036 100644 --- a/src/helpers/members/pruneMembers.ts +++ b/src/helpers/members/pruneMembers.ts @@ -18,7 +18,7 @@ export async function pruneMembers(bot: Bot, guildId: bigint, options: BeginGuil days: options.days, compute_prune_count: options.computePruneCount, include_roles: options.includeRoles, - } + }, ); return result.pruned; diff --git a/src/helpers/members/searchMembers.ts b/src/helpers/members/searchMembers.ts index 913f902a3..e65eadf00 100644 --- a/src/helpers/members/searchMembers.ts +++ b/src/helpers/members/searchMembers.ts @@ -10,7 +10,7 @@ export async function searchMembers( bot: Bot, guildId: bigint, query: string, - options?: Omit + options?: Omit, ) { if (options?.limit) { if (options.limit < 1) throw new Error(bot.constants.Errors.MEMBER_SEARCH_LIMIT_TOO_LOW); @@ -26,13 +26,13 @@ export async function searchMembers( { ...options, query, - } + }, ); return new Collection( result.map((member) => { const m = bot.transformers.member(bot, member, guildId, bot.transformers.snowflake(member.user.id)); return [m.id, m]; - }) + }), ); } diff --git a/src/helpers/messages/addReaction.ts b/src/helpers/messages/addReaction.ts index 855f00e70..b67de8462 100644 --- a/src/helpers/messages/addReaction.ts +++ b/src/helpers/messages/addReaction.ts @@ -12,6 +12,6 @@ export async function addReaction(bot: Bot, channelId: bigint, messageId: bigint bot.rest, "put", bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, encodeURIComponent(reaction)), - {} + {}, ); } diff --git a/src/helpers/messages/addReactions.ts b/src/helpers/messages/addReactions.ts index 789b5f953..faffb1d11 100644 --- a/src/helpers/messages/addReactions.ts +++ b/src/helpers/messages/addReactions.ts @@ -6,7 +6,7 @@ export async function addReactions( channelId: bigint, messageId: bigint, reactions: string[], - ordered = false + ordered = false, ) { if (!ordered) { await Promise.all(reactions.map((reaction) => bot.helpers.addReaction(channelId, messageId, reaction))); diff --git a/src/helpers/messages/deleteMessage.ts b/src/helpers/messages/deleteMessage.ts index 875e404ea..4810ded3c 100644 --- a/src/helpers/messages/deleteMessage.ts +++ b/src/helpers/messages/deleteMessage.ts @@ -6,7 +6,7 @@ export async function deleteMessage( channelId: bigint, messageId: bigint, reason?: string, - delayMilliseconds = 0 + delayMilliseconds = 0, ) { if (delayMilliseconds) await bot.utils.delay(delayMilliseconds); @@ -14,6 +14,6 @@ export async function deleteMessage( bot.rest, "delete", bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId), - { reason } + { reason }, ); } diff --git a/src/helpers/messages/editMessage.ts b/src/helpers/messages/editMessage.ts index 7737438ae..5420dd369 100644 --- a/src/helpers/messages/editMessage.ts +++ b/src/helpers/messages/editMessage.ts @@ -5,7 +5,7 @@ import { MessageComponentTypes } from "../../types/messages/components/messageCo /** Edit the message. */ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint, content: EditMessage) { - const result = await bot.rest.runMethod( + const result = await bot.rest.runMethod( bot.rest, "patch", bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId), @@ -20,43 +20,43 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint color: embed.color, footer: embed.footer ? { - text: embed.footer.text, - icon_url: embed.footer.iconUrl, - proxy_icon_url: embed.footer.proxyIconUrl, - } + text: embed.footer.text, + icon_url: embed.footer.iconUrl, + proxy_icon_url: embed.footer.proxyIconUrl, + } : undefined, image: embed.image ? { - url: embed.image.url, - proxy_url: embed.image.proxyUrl, - height: embed.image.height, - width: embed.image.width, - } + url: embed.image.url, + proxy_url: embed.image.proxyUrl, + height: embed.image.height, + width: embed.image.width, + } : undefined, thumbnail: embed.thumbnail ? { - url: embed.thumbnail.url, - proxy_url: embed.thumbnail.proxyUrl, - height: embed.thumbnail.height, - width: embed.thumbnail.width, - } + url: embed.thumbnail.url, + proxy_url: embed.thumbnail.proxyUrl, + height: embed.thumbnail.height, + width: embed.thumbnail.width, + } : undefined, video: embed.video ? { - url: embed.video.url, - proxy_url: embed.video.proxyUrl, - height: embed.video.height, - width: embed.video.width, - } + url: embed.video.url, + proxy_url: embed.video.proxyUrl, + height: embed.video.height, + width: embed.video.width, + } : undefined, provider: embed.provider, author: embed.author ? { - name: embed.author.name, - url: embed.author.url, - icon_url: embed.author.iconUrl, - proxy_icon_url: embed.author.proxyIconUrl, - } + name: embed.author.name, + url: embed.author.url, + icon_url: embed.author.iconUrl, + proxy_icon_url: embed.author.proxyIconUrl, + } : undefined, fields: embed.fields, })), @@ -91,8 +91,8 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint max_length: subcomponent.maxLength, }; } - - if (subcomponent.type === MessageComponentTypes.SelectMenu) + + if (subcomponent.type === MessageComponentTypes.SelectMenu) { return { type: subcomponent.type, custom_id: subcomponent.customId, @@ -105,34 +105,34 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint description: option.description, emoji: option.emoji ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } + id: option.emoji.id?.toString(), + name: option.emoji.name, + animated: option.emoji.animated, + } : undefined, default: option.default, })), }; + } return { type: subcomponent.type, custom_id: subcomponent.customId, label: subcomponent.label, style: subcomponent.style, - emoji: - "emoji" in subcomponent && subcomponent.emoji - ? { - id: subcomponent.emoji.id?.toString(), - name: subcomponent.emoji.name, - animated: subcomponent.emoji.animated, - } - : undefined, + emoji: "emoji" in subcomponent && subcomponent.emoji + ? { + id: subcomponent.emoji.id?.toString(), + name: subcomponent.emoji.name, + animated: subcomponent.emoji.animated, + } + : undefined, url: "url" in subcomponent ? subcomponent.url : undefined, disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, }; }), })), - } + }, ); return bot.transformers.message(bot, result); diff --git a/src/helpers/messages/getMessage.ts b/src/helpers/messages/getMessage.ts index 71aea5601..4a2c20a88 100644 --- a/src/helpers/messages/getMessage.ts +++ b/src/helpers/messages/getMessage.ts @@ -6,7 +6,7 @@ export async function getMessage(bot: Bot, channelId: bigint, id: bigint) { const result = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.CHANNEL_MESSAGE(channelId, id) + bot.constants.endpoints.CHANNEL_MESSAGE(channelId, id), ); return bot.transformers.message(bot, result); diff --git a/src/helpers/messages/getMessages.ts b/src/helpers/messages/getMessages.ts index 0392d5701..c9c406604 100644 --- a/src/helpers/messages/getMessages.ts +++ b/src/helpers/messages/getMessages.ts @@ -11,7 +11,7 @@ import type { Bot } from "../../bot.ts"; export async function getMessages( bot: Bot, channelId: bigint, - options?: GetMessagesAfter | GetMessagesBefore | GetMessagesAround | GetMessagesLimit + options?: GetMessagesAfter | GetMessagesBefore | GetMessagesAround | GetMessagesLimit, ) { if (options?.limit && (options.limit < 0 || options.limit > 100)) { throw new Error(bot.constants.Errors.INVALID_GET_MESSAGES_LIMIT); @@ -27,7 +27,7 @@ export async function getMessages( bot.rest, "get", bot.constants.endpoints.CHANNEL_MESSAGES(channelId), - options + options, ); return await Promise.all(result.map((res) => bot.transformers.message(bot, res))); diff --git a/src/helpers/messages/getReactions.ts b/src/helpers/messages/getReactions.ts index b5fcfddc2..84a5f9964 100644 --- a/src/helpers/messages/getReactions.ts +++ b/src/helpers/messages/getReactions.ts @@ -9,7 +9,7 @@ export async function getReactions( channelId: bigint, messageId: bigint, reaction: string, - options?: GetReactions + options?: GetReactions, ) { if (reaction.startsWith("<:")) { reaction = reaction.substring(2, reaction.length - 1); @@ -21,7 +21,7 @@ export async function getReactions( bot.rest, "get", bot.constants.endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, encodeURIComponent(reaction)), - options + options, ); return new Collection(users.map((user) => [user.id, user])); diff --git a/src/helpers/messages/publishMessage.ts b/src/helpers/messages/publishMessage.ts index e893610ed..a7e374188 100644 --- a/src/helpers/messages/publishMessage.ts +++ b/src/helpers/messages/publishMessage.ts @@ -7,7 +7,7 @@ export async function publishMessage(bot: Bot, channelId: bigint, messageId: big const data = await bot.rest.runMethod( bot.rest, "post", - bot.constants.endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId) + bot.constants.endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId), ); return bot.transformers.message(bot, data); diff --git a/src/helpers/messages/removeAllReactions.ts b/src/helpers/messages/removeAllReactions.ts index 3a58c4729..11c6ae5f1 100644 --- a/src/helpers/messages/removeAllReactions.ts +++ b/src/helpers/messages/removeAllReactions.ts @@ -5,6 +5,6 @@ export async function removeAllReactions(bot: Bot, channelId: bigint, messageId: await bot.rest.runMethod( bot.rest, "delete", - bot.constants.endpoints.CHANNEL_MESSAGE_REACTIONS(channelId, messageId) + bot.constants.endpoints.CHANNEL_MESSAGE_REACTIONS(channelId, messageId), ); } diff --git a/src/helpers/messages/removeReaction.ts b/src/helpers/messages/removeReaction.ts index 4dbe2b362..caa1f6b4c 100644 --- a/src/helpers/messages/removeReaction.ts +++ b/src/helpers/messages/removeReaction.ts @@ -6,7 +6,7 @@ export async function removeReaction( channelId: bigint, messageId: bigint, reaction: string, - options?: { userId?: bigint } + options?: { userId?: bigint }, ) { if (reaction.startsWith("<:")) { reaction = reaction.substring(2, reaction.length - 1); @@ -19,11 +19,11 @@ export async function removeReaction( "delete", options?.userId ? bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_USER( - channelId, - messageId, - encodeURIComponent(reaction), - options.userId - ) - : bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, encodeURIComponent(reaction)) + channelId, + messageId, + encodeURIComponent(reaction), + options.userId, + ) + : bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, encodeURIComponent(reaction)), ); } diff --git a/src/helpers/messages/removeReactionEmoji.ts b/src/helpers/messages/removeReactionEmoji.ts index 590876429..3176978fc 100644 --- a/src/helpers/messages/removeReactionEmoji.ts +++ b/src/helpers/messages/removeReactionEmoji.ts @@ -11,6 +11,6 @@ export async function removeReactionEmoji(bot: Bot, channelId: bigint, messageId await bot.rest.runMethod( bot.rest, "delete", - bot.constants.endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, reaction) + bot.constants.endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, reaction), ); } diff --git a/src/helpers/messages/sendMessage.ts b/src/helpers/messages/sendMessage.ts index b58479f24..d612ca710 100644 --- a/src/helpers/messages/sendMessage.ts +++ b/src/helpers/messages/sendMessage.ts @@ -22,53 +22,53 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe color: embed.color, footer: embed.footer ? { - text: embed.footer.text, - icon_url: embed.footer.iconUrl, - proxy_icon_url: embed.footer.proxyIconUrl, - } + text: embed.footer.text, + icon_url: embed.footer.iconUrl, + proxy_icon_url: embed.footer.proxyIconUrl, + } : undefined, image: embed.image ? { - url: embed.image.url, - proxy_url: embed.image.proxyUrl, - height: embed.image.height, - width: embed.image.width, - } + url: embed.image.url, + proxy_url: embed.image.proxyUrl, + height: embed.image.height, + width: embed.image.width, + } : undefined, thumbnail: embed.thumbnail ? { - url: embed.thumbnail.url, - proxy_url: embed.thumbnail.proxyUrl, - height: embed.thumbnail.height, - width: embed.thumbnail.width, - } + url: embed.thumbnail.url, + proxy_url: embed.thumbnail.proxyUrl, + height: embed.thumbnail.height, + width: embed.thumbnail.width, + } : undefined, video: embed.video ? { - url: embed.video.url, - proxy_url: embed.video.proxyUrl, - height: embed.video.height, - width: embed.video.width, - } + url: embed.video.url, + proxy_url: embed.video.proxyUrl, + height: embed.video.height, + width: embed.video.width, + } : undefined, provider: embed.provider, author: embed.author ? { - name: embed.author.name, - url: embed.author.url, - icon_url: embed.author.iconUrl, - proxy_icon_url: embed.author.proxyIconUrl, - } + name: embed.author.name, + url: embed.author.url, + icon_url: embed.author.iconUrl, + proxy_icon_url: embed.author.proxyIconUrl, + } : undefined, fields: embed.fields, })), allowed_mentions: content.allowedMentions ? { - parse: content.allowedMentions?.parse, - roles: content.allowedMentions?.roles?.map((id) => id.toString()), - users: content.allowedMentions?.users?.map((id) => id.toString()), - replied_user: content.allowedMentions?.repliedUser, - } + parse: content.allowedMentions?.parse, + roles: content.allowedMentions?.roles?.map((id) => id.toString()), + users: content.allowedMentions?.users?.map((id) => id.toString()), + replied_user: content.allowedMentions?.repliedUser, + } : undefined, file: content.file, components: content.components?.map((component) => ({ @@ -85,8 +85,8 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe max_length: subcomponent.maxLength, }; } - - if (subcomponent.type === MessageComponentTypes.SelectMenu) + + if (subcomponent.type === MessageComponentTypes.SelectMenu) { return { type: subcomponent.type, custom_id: subcomponent.customId, @@ -99,28 +99,28 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe description: option.description, emoji: option.emoji ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } + id: option.emoji.id?.toString(), + name: option.emoji.name, + animated: option.emoji.animated, + } : undefined, default: option.default, })), }; + } return { type: subcomponent.type, custom_id: subcomponent.customId, label: subcomponent.label, style: subcomponent.style, - emoji: - "emoji" in subcomponent && subcomponent.emoji - ? { - id: subcomponent.emoji.id?.toString(), - name: subcomponent.emoji.name, - animated: subcomponent.emoji.animated, - } - : undefined, + emoji: "emoji" in subcomponent && subcomponent.emoji + ? { + id: subcomponent.emoji.id?.toString(), + name: subcomponent.emoji.name, + animated: subcomponent.emoji.animated, + } + : undefined, url: "url" in subcomponent ? subcomponent.url : undefined, disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, }; @@ -128,17 +128,16 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe })), ...(content.messageReference?.messageId ? { - message_reference: { - message_id: content.messageReference.messageId.toString(), - channel_id: content.messageReference.channelId?.toString(), - guild_id: content.messageReference.guildId?.toString(), - fail_if_not_exists: content.messageReference.failIfNotExists === true, - }, - } + message_reference: { + message_id: content.messageReference.messageId.toString(), + channel_id: content.messageReference.channelId?.toString(), + guild_id: content.messageReference.guildId?.toString(), + fail_if_not_exists: content.messageReference.failIfNotExists === true, + }, + } : {}), - } + }, ); return bot.transformers.message(bot, result); } - diff --git a/src/helpers/misc/editBotStatus.ts b/src/helpers/misc/editBotStatus.ts index b2c38fb12..715dd9003 100644 --- a/src/helpers/misc/editBotStatus.ts +++ b/src/helpers/misc/editBotStatus.ts @@ -18,33 +18,33 @@ export function editBotStatus(bot: Bot, data: Omit( bot.rest, "delete", - `${bot.constants.endpoints.GUILD_TEMPLATES(guildId)}/${templateCode}` + `${bot.constants.endpoints.GUILD_TEMPLATES(guildId)}/${templateCode}`, ); } diff --git a/src/helpers/templates/editGuildTemplate.ts b/src/helpers/templates/editGuildTemplate.ts index a5b73fc56..d51983520 100644 --- a/src/helpers/templates/editGuildTemplate.ts +++ b/src/helpers/templates/editGuildTemplate.ts @@ -22,6 +22,6 @@ export async function editGuildTemplate(bot: Bot, guildId: bigint, templateCode: { name: data.name, description: data.description, - } + }, ); } diff --git a/src/helpers/templates/getGuildTemplates.ts b/src/helpers/templates/getGuildTemplates.ts index 226d84ffc..845528f0f 100644 --- a/src/helpers/templates/getGuildTemplates.ts +++ b/src/helpers/templates/getGuildTemplates.ts @@ -10,7 +10,7 @@ export async function getGuildTemplates(bot: Bot, guildId: bigint) { const templates = await bot.rest.runMethod( bot.rest, "get", - bot.constants.endpoints.GUILD_TEMPLATES(guildId) + bot.constants.endpoints.GUILD_TEMPLATES(guildId), ); return new Collection(templates.map((template) => [template.code, template])); diff --git a/src/helpers/templates/syncGuildTemplate.ts b/src/helpers/templates/syncGuildTemplate.ts index 70943c006..8a74d999e 100644 --- a/src/helpers/templates/syncGuildTemplate.ts +++ b/src/helpers/templates/syncGuildTemplate.ts @@ -9,6 +9,6 @@ export async function syncGuildTemplate(bot: Bot, guildId: bigint, templateCode: return await bot.rest.runMethod