Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upgrade discord.js v13 -> v14 #928

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

SlayerOrnstein
Copy link
Member

@SlayerOrnstein SlayerOrnstein commented Feb 6, 2025

Summary:


Resolves issue:
resolves #925


Screenshots:

Summary by CodeRabbit

  • Chore

    • Upgraded the Discord dependency to the latest version, enabling new performance and compatibility enhancements.
  • Refactor

    • Standardized event handling, command options, and embed formatting to streamline interactions and improve overall reliability.
    • Updated imports and usage of types throughout the codebase for better clarity and maintainability.
    • Transitioned from direct property assignments to setter methods in embed classes for improved encapsulation and maintainability.
  • Bug Fixes

    • Resolved minor logging inconsistencies and updated a joke response for clearer content.

This update refines the bot’s infrastructure and ensures a smoother, more consistent user experience.

Copy link

coderabbitai bot commented Feb 6, 2025

Walkthrough

This update upgrades the discord.js dependency from ^13.17.1 to ^14.17.3. The changes revise import statements across the codebase to use specific modules, update event constants from uppercase to camel case, and replace deprecated classes (such as MessageEmbed) with their modern equivalents (EmbedBuilder). In addition, command option types and permission flags have been standardized using enums like ApplicationCommandOptionType and PermissionsBitField. Numerous event handler files, interaction commands, and utility functions have been refactored accordingly without altering the core control flow.

Changes

File(s) Change Summary
package.json Updated discord.js version from ^13.17.1 to ^14.17.3.
src/bot.js, src/embeds/BaseEmbed.js Revised imports and usage of Discord classes; replaced MessageEmbed with EmbedBuilder; updated event naming conventions.
src/eventHandlers/* Updated import statements to use specific modules (Events, ChannelType, PermissionsBitField); changed event constants from uppercase (e.g., CLIENT_READY) to camel case (ClientReady); improved type-checks using enums.
src/interactions/channels/* Modified command option types and permission flags; transitioned from MessageEmbed to EmbedBuilder in Rooms.js and Templates.js.
src/interactions/{core,custom,fun}/* Adjusted command handling: updated embed structures, replaced ephemeral property with flags, and standardized option types (e.g., in About.js, Ping.js, CustomCommands.js, 8ball.js, Corgi.js, Joke.js).
src/interactions/tracking/Tracking.js Overhauled command definitions with updated permission flags, new builders (ActionRowBuilder, ButtonBuilder, etc.), and updated interaction collector configurations.
src/interactions/warframe/* Updated all command option types and embed components using ApplicationCommandOptionType and EmbedBuilder; refined component creation and interaction handling.
src/models/Interaction.js, src/notifications/Broadcaster.js Updated method signatures to use explicit Discord types; replaced MessageEmbed with EmbedBuilder in notifications.
src/utilities/* Modernized collectors and utility functions to use new builders and updated type annotations (e.g., EmbedBuilder instead of MessageEmbed).

Sequence Diagram(s)

sequenceDiagram
    participant D as Discord API
    participant B as Bot
    participant EH as Event Handler
    participant DB as Database/Logger

    D->>B: Emit Event (e.g., GuildCreate)
    B->>EH: Route event to proper handler
    EH->>DB: Process event, update logging/database
    DB-->>EH: Acknowledge update
    EH-->>B: Complete event processing
Loading
sequenceDiagram
    participant U as User
    participant D as Discord API
    participant IH as Interaction Handler
    participant R as Response

    U->>D: Send command interaction
    D->>IH: Forward interaction to Bot
    IH->>IH: Process command using updated option types and builders
    IH->>R: Generate response with EmbedBuilder
    R-->>U: Deliver the response
Loading

Poem

Oh, how my code now hops so light,
Imports refined, constants shining bright.
I nibble on updates with a joyful cheer,
New builders and types make bugs disappear.
Carrots and code, a bunny’s delight! 🥕🐰

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (13)
src/eventHandlers/UpdateGuildStatistics.js (1)

22-22: Update permission flags to use PermissionsBitField.

The permission flags should be updated to use the new PermissionsBitField flags from discord.js v14.

Apply this diff to update the permission flags:

-        if (channel.permissionsFor(this.bot.client.user).has(['MANAGE_CHANNELS', 'MANAGE_ROLES'])) {
+        if (channel.permissionsFor(this.bot.client.user).has([PermissionsBitField.Flags.ManageChannels, PermissionsBitField.Flags.ManageRoles])) {

Don't forget to add the import at the top:

-import { Events } from 'discord.js';
+import { Events, PermissionsBitField } from 'discord.js';
src/eventHandlers/AddGuildToDatabase.js (1)

29-29: Fix missing closing bracket in debug log.

The debug logging statement is missing a closing bracket.

-    this.logger.debug(`Joined guild ${guild} (${guild.id}`);
+    this.logger.debug(`Joined guild ${guild} (${guild.id})`);
src/eventHandlers/DeleteChannel.js (1)

14-14: Update event constant to camelCase.

For consistency with other files and discord.js v14, the event constant should be updated to camelCase.

-    super(bot, 'handlers.deleteChannel', Events.CHANNEL_DELETE);
+    super(bot, 'handlers.deleteChannel', Events.ChannelDelete);
src/eventHandlers/LogMemberBan.js (1)

33-33: Update channel type check to use ChannelType enum.

The channel type check should use the new ChannelType enum from discord.js v14 instead of the string literal.

-    if (logChannel && logChannel.type === 'GUILD_TEXT') {
+    if (logChannel && logChannel.type === ChannelType.GuildText) {

Don't forget to add the import:

-import { Events } from 'discord.js';
+import { ChannelType, Events } from 'discord.js';
src/eventHandlers/LogMemberRemove.js (1)

33-33: Update channel type check to use ChannelType enum.

The channel type check should use the new ChannelType enum from discord.js v14 instead of the string literal.

-    if (logChannel && logChannel.type === 'GUILD_TEXT') {
+    if (logChannel && logChannel.type === ChannelType.GuildText) {

Don't forget to add the import:

-import { Events } from 'discord.js';
+import { ChannelType, Events } from 'discord.js';
src/eventHandlers/LogMemberUnban.js (1)

34-34: Update channel type check to use ChannelType enum.

The channel type check should use the new ChannelType enum from discord.js v14 instead of the string literal.

-    if (logChannel && logChannel.type === 'GUILD_TEXT') {
+    if (logChannel && logChannel.type === ChannelType.GuildText) {

Don't forget to add the import:

-import { Events } from 'discord.js';
+import { ChannelType, Events } from 'discord.js';
src/eventHandlers/NotifyOwnerJoin.js (1)

36-40: Critical: Update deprecated guild.owner usage.

The guild.owner property is deprecated in discord.js v14. Use guild.fetchOwner() instead.

Apply this diff to fix the breaking change:

-        guild.owner.send(
+        const owner = await guild.fetchOwner();
+        owner.send(
           `${this.client.user.username} has been added ` +
             `to ${guild.name} and is ready\n Type ` +
             `\`${prefix}help\` for help`
         );
-        guild.owner.send(
+        const owner = await guild.fetchOwner();
+        owner.send(
           `Your guild **${guild.name}** is over the bot-to-user ratio.\nGenesis will now leave.\nIf you want to keep using ${this.client.user.username} please invite more people or kick some bots.`
         );

Also applies to: 42-44

src/eventHandlers/BulkMessageDeleteHandle.js (1)

35-35: Update channel type check for discord.js v14.

The channel type check should be updated to use the new channel types in v14.

Apply this diff:

-    if (channel?.type === 'text') {
+    if (channel?.type === 0) { // GUILD_TEXT
src/eventHandlers/MessageDeleteHandle.js (1)

30-30: Update channel type check for discord.js v14.

The channel type check should use the new ChannelType enum from discord.js v14 instead of the string literal 'GUILD_TEXT'.

Import ChannelType and update the check:

+import { Events, ChannelType } from 'discord.js';

-    if (logChannel && logChannel.type === 'GUILD_TEXT') {
+    if (logChannel && logChannel.type === ChannelType.GuildText) {
src/utilities/Webhook.js (1)

35-35: Fix undefined this reference and deprecated method usage.

There are two issues in the code:

  1. this.settings is undefined as this is not a class method
  2. webhooks.array() is deprecated in discord.js v14

Apply these fixes:

-      await this.settings.deleteWebhooksForChannel(ctx.channel.id);
+      await ctx.settings.deleteWebhooksForChannel(ctx.channel.id);

-      if (webhooks.array().length > 0) {
-        [target] = webhooks.array();
+      const webhookArray = Array.from(webhooks.values());
+      if (webhookArray.length > 0) {
+        [target] = webhookArray;

Also applies to: 54-55

src/interactions/channels/Templates.js (1)

59-59: Update channel type check to use new ChannelType enum.

The channel type check uses the old string literal 'GUILD_VOICE'. In discord.js v14, channel types are defined in the ChannelType enum.

+import { ChannelType } from 'discord.js';

-    if (channel && channel.type !== 'GUILD_VOICE') {
+    if (channel && channel.type !== ChannelType.GuildVoice) {
src/interactions/channels/Rooms.js (1)

143-143: Use ChannelType enum for channel types.

Replace string literals with the new ChannelType enum from discord.js v14 for better type safety:

-      type: 'GUILD_CATEGORY',
+      type: ChannelType.GuildCategory,

-      type: 'GUILD_TEXT',
+      type: ChannelType.GuildText,

-    type: 'GUILD_VOICE',
+    type: ChannelType.GuildVoice,

Add the import:

-import { ApplicationCommandOptionType, PermissionsBitField, EmbedBuilder } from 'discord.js';
+import { ApplicationCommandOptionType, PermissionsBitField, EmbedBuilder, ChannelType } from 'discord.js';

Also applies to: 150-150, 160-160

src/utilities/CommonFunctions.js (1)

882-882: Use ChannelType enum for channel type comparison.

Replace the string literal with the new ChannelType enum from discord.js v14 for better type safety:

-      Array.from(message.guild.channels.cache.filter((channel) => channel.type === 'GUILD_TEXT'))
+      Array.from(message.guild.channels.cache.filter((channel) => channel.type === ChannelType.GuildText))

Add the import:

-import { Collection, EmbedBuilder } from 'discord.js';
+import { Collection, EmbedBuilder, ChannelType } from 'discord.js';
🧹 Nitpick comments (7)
src/interactions/warframe/Builds.js (1)

440-458: Resolve potential scoping issues with declarations in switch-based logic.
Static analysis flags the declaration of navComponents and other variables as potentially accessible in unintended switch clauses. Consider wrapping them in a local block or declaring them within their specific case if necessary.

Possible approach:

 switch (something) {
   case 'example': {
+    const navComponents = new ActionRowBuilder({
+      // ...
+    });
+    // ...
   }
   // ...
 }
🧰 Tools
🪛 Biome (1.9.4)

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/eventHandlers/AddChannelToDatabase.js (1)

16-16: Update JSDoc to use correct type reference.

The JSDoc parameter type should be updated to reflect the new discord.js v14 type.

-   * @param {Discord.channel} channel channel to add to the database
+   * @param {import('discord.js').Channel} channel channel to add to the database
src/eventHandlers/LogMemberRemove.js (1)

21-21: Fix typo in JSDoc comment.

There's a typo in the JSDoc comment.

-   * @param {Discord.Message} message member that was remvoed, left, or kicked
+   * @param {Discord.Message} message member that was removed, left, or kicked
src/interactions/core/Ping.js (1)

54-55: Consider removing empty footer icon.

The footer icon is set to a zero-width space character ('\u200B'). Since it's not displaying an actual icon, consider removing the icon_url property entirely.

 footer: {
-  icon_url: '\u200B',
   text: `Uptime: ${timeDeltaToString(interaction.client.uptime)}`,
 },
src/interactions/warframe/WhereIs.js (2)

23-24: Update JSDoc to reflect new types.

The JSDoc comment still references the old Discord namespace. Update it to use the new types from discord.js v14.

- * @type {Discord.ApplicationCommandData}
+ * @type {import('discord.js').ApplicationCommandData}

32-32: Update JSDoc parameter type.

Update the interaction parameter type to use the new discord.js v14 type.

- * @param {Discord.CommandInteraction} interaction interaction to handle
+ * @param {import('discord.js').CommandInteraction} interaction interaction to handle
src/notifications/Broadcaster.js (1)

1-1: Optimize imports for better maintainability.

Since we're only using the type for JSDoc, we can use an import type statement instead.

-import Discord from 'discord.js'; // eslint-disable-line no-unused-vars
+import type { Client, EmbedBuilder } from 'discord.js';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8977327 and 569608f.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (44)
  • package.json (1 hunks)
  • src/bot.js (4 hunks)
  • src/embeds/BaseEmbed.js (2 hunks)
  • src/eventHandlers/AddChannelToDatabase.js (2 hunks)
  • src/eventHandlers/AddGuildToDatabase.js (2 hunks)
  • src/eventHandlers/AssignDefaultRoles.js (2 hunks)
  • src/eventHandlers/BulkMessageDeleteHandle.js (2 hunks)
  • src/eventHandlers/DeleteChannel.js (2 hunks)
  • src/eventHandlers/DeleteGuild.js (2 hunks)
  • src/eventHandlers/DynamicVoiceHandler.js (2 hunks)
  • src/eventHandlers/InteractionHandler.js (7 hunks)
  • src/eventHandlers/JoinNotify.js (1 hunks)
  • src/eventHandlers/LeaveNotify.js (1 hunks)
  • src/eventHandlers/LogMemberBan.js (2 hunks)
  • src/eventHandlers/LogMemberRemove.js (2 hunks)
  • src/eventHandlers/LogMemberUnban.js (2 hunks)
  • src/eventHandlers/MessageDeleteHandle.js (1 hunks)
  • src/eventHandlers/NotifyOwnerJoin.js (2 hunks)
  • src/eventHandlers/NotifyVulgarName.js (1 hunks)
  • src/eventHandlers/Ready.js (2 hunks)
  • src/eventHandlers/UpdateGuildStatistics.js (1 hunks)
  • src/eventHandlers/WelcomeHandler.js (1 hunks)
  • src/interactions/channels/Rooms.js (9 hunks)
  • src/interactions/channels/Templates.js (1 hunks)
  • src/interactions/core/About.js (2 hunks)
  • src/interactions/core/Ping.js (3 hunks)
  • src/interactions/custom/CustomCommands.js (1 hunks)
  • src/interactions/fun/8ball.js (2 hunks)
  • src/interactions/fun/Corgi.js (1 hunks)
  • src/interactions/fun/Joke.js (1 hunks)
  • src/interactions/tracking/Tracking.js (11 hunks)
  • src/interactions/warframe/Builds.js (7 hunks)
  • src/interactions/warframe/Calculator.js (2 hunks)
  • src/interactions/warframe/LFG.js (5 hunks)
  • src/interactions/warframe/Lookup.js (3 hunks)
  • src/interactions/warframe/PriceCheck.js (2 hunks)
  • src/interactions/warframe/WhatsIn.js (2 hunks)
  • src/interactions/warframe/WhereIs.js (3 hunks)
  • src/interactions/warframe/Worldstate.js (9 hunks)
  • src/models/Interaction.js (1 hunks)
  • src/notifications/Broadcaster.js (1 hunks)
  • src/utilities/Collectors.js (8 hunks)
  • src/utilities/CommonFunctions.js (8 hunks)
  • src/utilities/Webhook.js (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/interactions/fun/Joke.js
🧰 Additional context used
🪛 Biome (1.9.4)
src/interactions/warframe/Builds.js

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🔇 Additional comments (61)
src/eventHandlers/UpdateGuildStatistics.js (2)

1-1: LGTM! Import statement updated correctly.

The change to import only the Events module directly follows best practices and aligns with discord.js v14 patterns.


8-8: LGTM! Event constant updated correctly.

The event constant has been properly updated to use the new camel case format (Events.GuildMemberUpdate) as required by discord.js v14.

Let's verify that we're using the correct event constant name:

✅ Verification successful

🌐 Web query:

What are the available event constants in discord.js v14?

💡 Result:

Discord.js v14 uses an `Events` enum to provide event constants, replacing string-based event names from previous versions. Here are key event categories and their corresponding constants:

## Core Client Events
- `ClientReady`: Emitted when client connects
- `InteractionCreate`: Triggered for slash commands/components
- `MessageCreate`: Replaces `message` event (fires on new messages)

## Guild Events
- `GuildCreate`/`GuildDelete`: Server join/leave
- `GuildMemberAdd`/`GuildMemberRemove`: Member joins/leaves
- `GuildMemberUpdate`: Member changes (roles/nickname)
- `GuildUpdate`: Server configuration changes

## Scheduled Event Handling
- `GuildScheduledEventCreate`/`Delete`/`Update`
- `GuildScheduledEventUserAdd`/`Remove`

## Voice Channel Events
- `VoiceStateUpdate`: Voice connection changes
- `VoiceServerUpdate`: Voice server updates

## Message Lifecycle
- `MessageDelete`/`BulkDelete`
- `MessageUpdate`: Message edits

## Thread Management
- `ThreadCreate`/`Delete`/`Update`
- `ThreadMembersUpdate`: Participants change
- `ThreadMemberUpdate`: Individual member changes

## Reaction Handling
- `MessageReactionAdd`/`Remove`
- `MessageReactionRemoveAll`/`RemoveEmoji`

**Key changes in v14:**
1. Use enum access instead of strings:  
   ```javascript
   const { Events } = require('discord.js');
   client.on(Events.MessageCreate, message => { ... });
   ```
2. Event name standardization:
   - All events use PascalCase (e.g., `messageCreate` → `MessageCreate`)
   - Deprecated events removed in favor of Gateway v9 equivalents[9]

For a complete list, reference the official [`Events` enum](https://discord.js.org/docs/packages/discord.js/14.14.1/Events:Enum)[8] which contains 140+ documented events. Common patterns include Create/Delete/Update suffixes for resource lifecycle events and UserAdd/UserRemove for participation tracking[4][7].

Citations:

- 1: https://discordjs.guide/creating-your-bot/event-handling
- 2: https://www.youtube.com/watch?v=XqPQnSSAg68
- 3: https://discord.js.org/docs/packages/discord.js/14.14.1/Message:Class
- 4: https://github.com/itsdrvgo/discord.js-v14-events-cheatsheet
- 5: https://www.youtube.com/watch?v=Mug61R0cxRw
- 6: https://www.youtube.com/watch?v=JEEcbVjLyr0
- 7: https://gist.github.com/Iliannnn/f4985563833e2538b1b96a8cb89d72bb
- 8: https://discord.js.org/docs/packages/discord.js/14.14.1/Events:Enum
- 9: https://discordjs.guide/additional-info/changes-in-v14
- 10: https://discord.js.org/docs/packages/discord.js/14.17.3

LGTM! Event constant verified

The updated event constant (Events.GuildMemberUpdate) aligns perfectly with the discord.js v14 naming conventions as confirmed by the web query. No further changes are necessary.

src/interactions/warframe/Builds.js (4)

141-141: Good use of updated enumerations for command option types.
Switching to ApplicationCommandOptionType.Subcommand, .String, and .Boolean ensures compatibility with discord.js v14. Nicely done.

Also applies to: 146-146, 151-151, 159-159, 163-163, 170-170, 175-175, 182-182, 190-190, 195-195, 202-202, 209-209, 214-214


421-426: Clean transition to builders for select menus.
Using ActionRowBuilder and StringSelectMenuBuilder is correct for discord.js v14; no issues found.


517-517: Correct usage of the new interactionType property.
Replacing legacy constants with InteractionType.MessageComponent is consistent with discord.js v14.

Also applies to: 526-526


559-559: Proper migration to new ButtonBuilder and ButtonStyle.
These lines correctly align with the v14 approach.

Also applies to: 561-561, 563-563

src/interactions/tracking/Tracking.js (7)

42-42: Seamless migration from v13 constants to v14 standard enumerations.
Updating defaultMemberPermissions and type fields to PermissionsBitField.Flags.ManageGuild and ApplicationCommandOptionType.* ensures the commands remain aligned with the new API.

Also applies to: 46-47, 50-51, 54-55, 60-61, 64-65, 68-69, 72-73, 76-77, 80-81, 84-85


207-218: Ternary-based creation of ActionRowBuilder & ButtonBuilder is correctly applied.
Switching from old MessageButton usage to ButtonBuilder with ButtonStyle.Secondary is correct for v14.


226-256: Dynamic creation of ActionRowBuilder & StringSelectMenuBuilder.
Using these builders instead of legacy message components avoids deprecation issues and is fully v14-compliant. Nicely done.


267-296: Unified button row creation with the new builder patterns.
Good job employing ButtonBuilder and ButtonStyle.* for each action. The approach is straightforward and clear.


305-306: Adoption of explicit interaction and component types.
Replacing old usage with interactionType: interaction.MESSAGE_COMPONENT and componentType: ComponentType.StringSelect is correct for v14.


360-361: Button collector changes align with v14.
Using interactionType: interaction.MESSAGE_COMPONENT and componentType: ComponentType.Button is accurate.


528-528: Properly escaping markdown and removing mentions.
Utils.escapeMarkdown and Utils.removeMentions mitigate unwanted markdown parsing while protecting user mentions.

src/interactions/fun/Corgi.js (1)

15-15: Straightforward file usage.
Returning an array with the corgi image URL is a concise approach and is perfectly valid for attachable resources.

src/embeds/BaseEmbed.js (1)

1-1: LGTM! Correctly migrated from MessageEmbed to EmbedBuilder.

The changes align with discord.js v14 migration guide where MessageEmbed was replaced with EmbedBuilder.

Let's verify if any EmbedBuilder methods need updates:

Also applies to: 11-11

✅ Verification successful

🌐 Web query:

What are the breaking changes between MessageEmbed and EmbedBuilder in discord.js v14?

💡 Result:

The transition from `MessageEmbed` to `EmbedBuilder` in discord.js v14 introduced several breaking changes aimed at improving consistency and validation:

## 1. **Class Renaming and Structure**  
- `MessageEmbed` was renamed to `EmbedBuilder`[4][7].  
- All embed-related methods now return immutable objects when received from the API[4]. To modify existing embeds, use:  
  ```javascript
  const modifiedEmbed = EmbedBuilder.from(receivedEmbed).setTitle('Updated Title');
  ```

## 2. **Method Updates**  
- **`.addField()` Removal**: Replaced with `.addFields()`, which accepts an array of field objects[4][9]:  
  ```javascript
  // Old (v13)
  embed.addField('Name', 'Value', true);
  
  // New (v14)
  embed.addFields([{ name: 'Name', value: 'Value', inline: true }]);
  ```
- **`.setAuthor()`/`.setFooter()` Parameter Changes**: Now require objects with explicit properties[4]:  
  ```javascript
  embed.setAuthor({ name: 'Author', iconURL: 'url' });
  embed.setFooter({ text: 'Footer', iconURL: 'url' });
  ```

## 3. **Validation Enhancements**  
- Embeds must include at least one non-empty field[9].  
- Empty/null values in fields or titles will trigger errors[9].  
- Validators are enabled by default (disable via `disableValidators()` if needed)[4].

## 4. **Immutable API Responses**  
Embeds retrieved from messages (`message.embeds`) cannot be directly modified. Use `EmbedBuilder.from()` to create editable instances[4]:  
```javascript
const receivedEmbed = message.embeds[0];
const editedEmbed = EmbedBuilder.from(receivedEmbed).setColor(0xFF0000);
```

## 5. **Color Handling**  
The `.setColor()` method now strictly accepts valid `ColorResolvable` types (e.g., hex strings like `#FF0000`, integers like `0xFF0000`, or RGB arrays)[1][7].

These changes align embeds with discord.js v14’s broader API improvements, emphasizing type safety and validation[4][7]. Developers should update method calls and ensure all embed components adhere to Discord’s formatting rules to avoid errors.

Citations:

- 1: https://discordjs.guide/popular-topics/embeds
- 2: https://www.youtube.com/watch?v=DB8a8i1pXUM
- 3: https://www.youtube.com/watch?v=YkpBaeM_WSM
- 4: https://discordjs.guide/additional-info/changes-in-v14
- 5: https://www.youtube.com/watch?v=YofueNFQEVw
- 6: https://discord.js.org/docs/packages/discord.js/14.17.3/EmbedBuilder:Class
- 7: https://www.youtube.com/watch?v=PhXBtLeUbsA
- 8: https://discord.js.org/docs/packages/discord.js/14.14.0/EmbedBuilder:Class
- 9: https://github.com/AnIdiotsGuide/discordjs-bot-guide/blob/master/first-bot/using-embeds-in-messages.md
- 10: https://discord.js.org/docs/packages/discord.js/14.14.1/Embed:Class

EmbedBuilder migration verified.
The web query confirms that migrating from MessageEmbed to EmbedBuilder requires updating methods like addField (now addFields) as well as parameter adjustments for setAuthor and setFooter. Since the changes in BaseEmbed.js correctly update the import and extend the new EmbedBuilder—and there's no evidence of outdated method calls in this snippet—the update appears correct.

src/eventHandlers/DeleteGuild.js (1)

1-1: LGTM! Correctly updated event constant to camelCase.

The changes align with discord.js v14 migration guide where event constants were renamed to use camelCase.

Also applies to: 14-14

src/eventHandlers/AddGuildToDatabase.js (1)

1-1: LGTM! Correctly updated event constant to camelCase.

The changes align with discord.js v14 migration guide where event constants were renamed to use camelCase.

Also applies to: 14-14

src/eventHandlers/DeleteChannel.js (1)

1-1: LGTM! Correctly updated to use ChannelType enum.

The changes align with discord.js v14 migration guide where string literals for channel types were replaced with ChannelType enum.

Also applies to: 24-24

src/models/Interaction.js (1)

22-24: LGTM! Type annotations correctly updated for discord.js v14.

The parameter and return type annotations have been properly updated to use explicit Discord namespace references, which aligns with discord.js v14's type system.

✅ Verification successful

🌐 Web query:

What are the breaking changes in discord.js v14 regarding Message and MessagePayload types?

💡 Result:

Discord.js v14 introduced several breaking changes affecting `Message` and `MessagePayload` types. Here's a structured breakdown:

---

### **1. Component Renaming and Immutability**
- **Components** (buttons, select menus) now use `Builder` suffixes:
  ```js
  // Before (v13)
  new MessageButton();
  // After (v14)
  new ButtonBuilder();
  ```
- **Components fetched from the API are immutable**. To modify them:
  ```js
  const editedButton = ButtonBuilder.from(receivedButton).setDisabled(true);
  ```

### **2. MessageEmbed Changes**
- `MessageEmbed` renamed to `EmbedBuilder`.
- **Deprecated methods**:
  - `.addField()` ➔ Use `.addFields()` with an array:
    ```js
    new EmbedBuilder().addFields([{ name: 'Field', value: 'Value', inline: true }]);
    ```

### **3. Select Menu Updates**
- `MessageSelectMenu` ➔ `StringSelectMenuBuilder`.
- **Method changes**:
  - `.addOption()` removed ➔ Use `.addOptions()` with an array.

### **4. Enum Formatting**
- Enum values now use **PascalCase** instead of `SCREAMING_SNAKE_CASE`:
  ```js
  // Before
  ApplicationCommandOptionTypes.SUB_COMMAND;
  // After
  ApplicationCommandOptionType.SubCommand;
  ```

### **5. Util Function Removals**
- `Util.removeMentions()` ➔ Use `allowedMentions` in message options.
- `Util.splitMessage()` ➔ Manual handling required.

### **6. API Version Upgrade**
- Discord.js v14 uses **Discord API v10**, which enforces stricter type checks (e.g., enum parameters now require `number` types instead of strings).

### **7. Event Handling**
- The `message` event ➔ Replaced by `messageCreate`.

---

**Examples of Impact**:
- **Before (v13)**:
  ```js
  const embed = new MessageEmbed().addField('Title', 'Content');
  const button = new MessageButton().setLabel('Click');
  ```
- **After (v14)**:
  ```js
  const embed = new EmbedBuilder().addFields([{ name: 'Title', value: 'Content' }]);
  const button = new ButtonBuilder().setLabel('Click');
  ```

For more details on thread management or voice message support updates, refer to the full changelog[9][4].

Citations:

- 1: https://discordjs.guide/whats-new
- 2: https://discord.js.org/docs/packages/discord.js/14.14.1/Message:Class
- 3: https://discord.js.org/docs/packages/discord.js/14.14.1/MessagePayload:Class
- 4: https://github.com/discordjs/discord.js/blob/main/packages/discord.js/CHANGELOG.md
- 5: https://www.youtube.com/watch?v=YkpBaeM_WSM
- 6: https://www.youtube.com/watch?v=jntUHXiFB8g
- 7: https://github.com/discordjs/discord.js/issues/10298
- 8: https://v15.discordjs.guide/additional-info/updating-from-v14
- 9: https://discordjs.guide/additional-info/changes-in-v14
- 10: https://gist.github.com/Iliannnn/f4985563833e2538b1b96a8cb89d72bb

LGTM! Type annotations correctly updated to reflect discord.js v14 changes.

The explicit use of Discord.CommandInteraction, Discord.CommandContext, and the updated return type (Promise<Discord.Message | Discord.MessagePayload>) aligns with the breaking changes in discord.js v14 related to Message and MessagePayload types. No functional changes are introduced, and the adjustments solely improve type safety in accordance with the new discord.js v14 standards.

src/interactions/warframe/PriceCheck.js (1)

1-1: LGTM! Command options correctly updated for discord.js v14.

The changes properly implement the new ApplicationCommandOptionType enum from discord.js v14, replacing the old Types constant.

Also applies to: 14-14, 19-19

src/eventHandlers/AssignDefaultRoles.js (1)

1-1: LGTM! Event handler correctly updated for discord.js v14.

The changes properly implement:

  • Direct Events import
  • Camel case event name (GuildMemberAdd)
  • Correct GuildMember type

Also applies to: 15-15, 20-20

✅ Verification successful

🌐 Web query:

What are the breaking changes in discord.js v14 regarding event names and member types?

💡 Result:

Discord.js v14 introduced several breaking changes related to event names and member handling. Here's a detailed breakdown:

## Event Name Changes
- **`message` ➔ `messageCreate`**: The legacy message event was renamed to align with Discord API v10 terminology[4][5].
- **`interaction` ➔ `interactionCreate`**: All interaction handling now uses this updated event name[4][5].
- **Removed application command events**: 
  - `applicationCommandCreate`
  - `applicationCommandDelete`
  - `applicationCommandUpdate`[4]
- **New thread-related events**:
  - `threadCreate`
  - `threadUpdate`
  - `threadDelete`
  - `threadListSync`[5]

Example of updated event usage:
```javascript
// Old (v13)
client.on('message', message => {});

// New (v14)
client.on(Events.MessageCreate, message => {});
```

## Member Type Changes
1. **GuildMemberManager updates**:
   - Added `addRole()`/`removeRole()` methods for direct role management without caching[4]
   - New `fetchMe()` method to retrieve client's guild member[4]

2. **Role position handling**:
   ```javascript
   // Old
   guild.setRolePositions([{role: '123', position: 2}]);

   // New
   guild.roles.setPositions([{role: '123', position: 2}]);
   ```

3. **Member tracking**:
   - The `guildMemberUpdate` event now provides more detailed change tracking[5]
   - New properties like `flags` added to GuildMember objects[4]

Example of role change detection:
```javascript
client.on(Events.GuildMemberUpdate, (oldMember, newMember) => {
  const addedRoles = newMember.roles.cache.difference(oldMember.roles.cache);
  const removedRoles = oldMember.roles.cache.difference(newMember.roles.cache);
});
```

These changes were implemented to better align with Discord API v10 specifications and improve type safety through enum-based constants like `GatewayIntentBits` and `Partials`. Developers must update their event listeners and member handling logic to use the new naming conventions and methods[4][10].

Citations:

- 1: https://discordjs.guide/whats-new
- 2: https://www.youtube.com/watch?v=pm8X8hzCcTI
- 3: https://docs.botghost.com/getting-started/changelogs-2025/changelogs-2024
- 4: https://discordjs.guide/additional-info/changes-in-v14
- 5: https://gist.github.com/Iliannnn/f4985563833e2538b1b96a8cb89d72bb
- 6: https://www.youtube.com/watch?v=MDdt35tXYEA
- 7: https://github.com/Tolga1452/discord.js-v14-template/releases
- 8: https://discordjs.guide/popular-topics/faq
- 9: https://www.youtube.com/watch?v=sHksse4EUFU
- 10: https://github.com/discordjs/discord.js/discussions/7380

LGTM! Event handler correctly updated for discord.js v14.
The updated changes—importing Events directly, using the camel case constant GuildMemberAdd, and switching to the correct GuildMember type—align perfectly with the breaking changes in discord.js v14 as confirmed by your web query.

src/interactions/fun/8ball.js (1)

1-1: LGTM! Command options correctly updated for discord.js v14.

The changes properly implement the new ApplicationCommandOptionType enum from discord.js v14, replacing the old Types constant.

Also applies to: 38-38

src/eventHandlers/AddChannelToDatabase.js (1)

21-39: LGTM! Channel type checks updated correctly.

The channel type checks have been properly updated to use the new ChannelType enum from discord.js v14.

src/eventHandlers/WelcomeHandler.js (1)

1-1: LGTM! Event constant updated correctly.

The changes align with discord.js v14's best practices:

  • Direct import of Events from discord.js
  • Updated event constant to camelCase (GuildMemberAdd)

Also applies to: 12-12

✅ Verification successful

🌐 Web query:

What are the event constant changes in discord.js v14?

💡 Result:

Discord.js v14 introduced several significant changes to event handling and constants, primarily focusing on standardization and API consistency. Here are the key changes:

## Event Name Changes
- **Deprecated Events Removed**:  
  - `message` ➔ replaced by `messageCreate`  
  - `interaction` ➔ replaced by `interactionCreate`[1][4][7]  
  - Application command events (`applicationCommandCreate`, `applicationCommandUpdate`, etc.) were removed entirely[1][7].

- **Thread Handling**:  
  The `threadMembersUpdate` event now returns three parameters:  
  ```js
  client.on('threadMembersUpdate', (addedMembers, removedMembers, thread) => { ... });
  ```
  instead of just the thread[1][4].

---

## Enum-Based Event Constants
Events now use PascalCase enums instead of string literals:  
```js
// Old (v13)
client.on('guildMemberAdd', () => { ... });

// New (v14)
const { Events } = require('discord.js');
client.on(Events.GuildMemberAdd, () => { ... });
```
Common enum replacements:  
| v13 String          | v14 Enum                     |
|---------------------|-----------------------------|
| `'ready'`           | `Events.ClientReady`        |
| `'interactionCreate'`| `Events.InteractionCreate` |
| `'guildMemberAdd'`  | `Events.GuildMemberAdd`     |

This change improves type safety and IDE autocompletion[1][4][7].

---

## Parameter Changes
- **Guild Member Updates**:  
  ```js
  client.on(Events.GuildMemberUpdate, (oldMember, newMember) => { ... });
  ```
  Now provides both previous and current member states[4][9].

- **Voice Channel Handling**:  
  The `.deleted` property was removed from voice state objects - use cache checks instead[1].

- **Message Components**:  
  Component interaction parsing moved to dedicated methods:
  ```js
  interaction.isButton(); // Check if interaction is button-based
  interaction.isStringSelectMenu(); // Check for select menus
  ```

---

## New Events Added
- **Guild Scheduled Events**:  
  ```js
  client.on(Events.GuildScheduledEventCreate, (event) => { ... });
  client.on(Events.GuildScheduledEventUserAdd, (event, user) => { ... });
  ```

- **Boost Tracking**:  
  ```js
  client.on(Events.GuildMemberBoost, (member) => { ... });
  client.on(Events.GuildMemberUnboost, (member) => { ... });
  ```

Developers should update their codebase to use the new enum-based event constants and verify parameter signatures for modified events. The changes improve type safety and align Discord.js more closely with Discord's official API structure.

Citations:

- 1: https://discordjs.guide/additional-info/changes-in-v14
- 2: https://discordjs.guide/whats-new
- 3: https://www.youtube.com/watch?v=XqPQnSSAg68
- 4: https://gist.github.com/Iliannnn/f4985563833e2538b1b96a8cb89d72bb
- 5: https://github.com/Tolga1452/discord.js-v14-template/releases
- 6: https://www.youtube.com/watch?v=et_bzG3WJDg
- 7: https://discordjs.guide/creating-your-bot/event-handling
- 8: https://support.glitch.com/t/going-to-need-another-node-update-discord-js-node-16-6-0-requirement/45235
- 9: https://www.youtube.com/watch?v=y_MD8A4qvjE
- 10: https://www.youtube.com/watch?v=YkpBaeM_WSM

LGTM! Event constant updated correctly.

The code now directly imports Events from discord.js and correctly uses the PascalCase constant (GuildMemberAdd) as recommended in discord.js v14. The web query confirms that these changes align with the new event naming conventions.

src/eventHandlers/NotifyVulgarName.js (1)

1-1: LGTM! Event constant updated correctly.

The changes align with discord.js v14's best practices:

  • Direct import of Events from discord.js
  • Updated event constant to camelCase (GuildMemberAdd)

Also applies to: 13-13

src/eventHandlers/NotifyOwnerJoin.js (1)

1-1: LGTM! Event constant updated correctly.

The changes align with discord.js v14's best practices:

  • Direct import of Events from discord.js
  • Updated event constant to camelCase (GuildCreate)

Also applies to: 15-15

src/eventHandlers/BulkMessageDeleteHandle.js (1)

1-1: ⚠️ Potential issue

Critical: Incorrect event constant for bulk message deletion.

The handler is designed for bulk message deletion but is using the wrong event constant. Events.MessageDelete is for single message deletion, while this handler expects a collection of messages.

Apply this diff to fix the event constant:

-    super(bot, 'handlers.logMessageDeleteBulk', Events.MessageDelete);
+    super(bot, 'handlers.logMessageDeleteBulk', Events.MessageBulkDelete);

Also applies to: 17-17

src/eventHandlers/LeaveNotify.js (1)

1-1: LGTM! Changes align with discord.js v14 API.

The changes correctly update the event constant to use the new camelCase format (Events.GuildDelete) and import directly from discord.js.

Also applies to: 12-12

src/eventHandlers/JoinNotify.js (1)

1-1: LGTM! Changes align with discord.js v14 API.

The changes correctly update the event constant to use the new camelCase format (Events.GuildCreate) and import directly from discord.js.

Also applies to: 12-12

src/eventHandlers/MessageDeleteHandle.js (1)

1-1: LGTM! Changes align with discord.js v14 API.

The changes correctly update the event constant to use the new camelCase format (Events.MessageDelete) and import directly from discord.js.

Also applies to: 13-13

src/interactions/core/About.js (1)

1-2: LGTM! Changes align with discord.js v14 API.

The changes correctly update the ephemeral flag to use the new MessageFlags.Ephemeral enum instead of the boolean property.

Also applies to: 50-50

src/interactions/warframe/WhatsIn.js (1)

1-1: LGTM! Changes align with discord.js v14 API.

The updates correctly implement the new modular imports and ApplicationCommandOptionType constants from discord.js v14.

Also applies to: 11-11, 27-27

src/interactions/core/Ping.js (1)

1-1: LGTM! Correctly migrated to new EmbedBuilder API.

The changes properly implement the new EmbedBuilder and EmbedType from discord.js v14.

Also applies to: 43-46

src/interactions/warframe/Calculator.js (1)

1-1: LGTM! Properly migrated command option types.

The changes correctly implement ApplicationCommandOptionType constants from discord.js v14 for both integer and subcommand options.

Also applies to: 9-9, 15-15, 21-21, 43-43, 48-48, 53-53

src/interactions/custom/CustomCommands.js (1)

1-1: LGTM! Successfully migrated to new permission system and command option types.

The changes correctly implement:

  • PermissionsBitField for guild management permissions
  • ApplicationCommandOptionType for subcommand and string options

Also applies to: 15-15, 19-19, 23-23, 28-28, 35-35, 39-39, 46-46

src/eventHandlers/DynamicVoiceHandler.js (1)

1-1: LGTM! Changes align with discord.js v14 requirements.

The updates correctly implement:

  • Specific imports from discord.js
  • New PermissionsBitField.Flags for permissions
  • CamelCase event names (VoiceStateUpdate, ChannelDelete)

Also applies to: 4-4, 81-81, 88-88

src/eventHandlers/Ready.js (1)

1-1: LGTM! Changes align with discord.js v14 requirements.

The updates correctly implement:

  • Direct import of Events from discord.js
  • CamelCase event name (ClientReady)

Also applies to: 25-25

src/bot.js (1)

1-1: Verify completeness of GatewayIntentBits.

While the changes to imports, events, and status are correct, please verify if all necessary intents are included. For example, if you're handling message content, you might need GatewayIntentBits.MessageContent.

Also applies to: 8-8, 57-57, 66-70

src/interactions/warframe/Lookup.js (1)

1-1: LGTM! Changes align with discord.js v14 requirements.

The updates correctly implement:

  • Direct import of ApplicationCommandOptionType
  • Proper enum values for command option types (String, Boolean, Subcommand)

Also applies to: 21-21, 27-27, 40-40, 45-45, 50-50, 55-55, 61-61, 66-66

src/interactions/warframe/LFG.js (4)

1-9: LGTM! Import statements have been correctly updated.

The changes properly import specific components from discord.js v14 instead of importing the entire Discord object, which is more efficient and follows best practices.


115-165: LGTM! Command option types have been correctly updated.

The changes properly update the command option types to use the new ApplicationCommandOptionType enum from discord.js v14, replacing the old Types constants.


207-220: LGTM! Button components have been correctly updated.

The changes properly update the button components to use the new builders and styles from discord.js v14:

  • MessageButtonButtonBuilder
  • MessageActionRowActionRowBuilder
  • MessageButtonStylesButtonStyle

235-236: LGTM! Interaction collector configuration has been correctly updated.

The changes properly update the interaction collector to use the new interaction and component types from discord.js v14.

src/utilities/Collectors.js (4)

1-10: LGTM! Import statements have been correctly updated.

The changes properly import specific components from discord.js v14, which is more efficient and follows best practices.


14-33: LGTM! Navigation components have been correctly updated.

The changes properly update the navigation components to use the new builders and styles from discord.js v14:

  • MessageActionRowActionRowBuilder
  • MessageButtonButtonBuilder
  • MessageButtonStylesButtonStyle

35-49: LGTM! Confirmation components have been correctly updated.

The changes properly update the confirmation components to use the new builders and styles from discord.js v14.


333-366: LGTM! Embed builder updates have been correctly implemented.

The changes properly update the embed creation to use the new EmbedBuilder class from discord.js v14, replacing the old MessageEmbed.

src/eventHandlers/InteractionHandler.js (4)

6-6: LGTM! Import statements have been correctly updated.

The changes properly import specific components from discord.js v14, which is more efficient and follows best practices.


54-54: LGTM! Event constant has been correctly updated.

The change properly updates the event constant from Events.INTERACTION_CREATE to Events.InteractionCreate to match the new camelCase format in discord.js v14.


118-121: LGTM! Permission flags have been correctly updated.

The changes properly update the permission flags to use PermissionsBitField.Flags from discord.js v14, replacing the old Permissions.FLAGS.


140-177: LGTM! Command option types have been correctly updated.

The changes properly update the command option types to use ApplicationCommandOptionType from discord.js v14, replacing the old string literals ('ROLE' and 'USER').

src/interactions/warframe/Worldstate.js (3)

1-1: LGTM! Import statements have been correctly updated.

The changes properly import specific components from discord.js v14, which is more efficient and follows best practices.


68-165: LGTM! Command option types have been correctly updated.

The changes properly update the command option types to use ApplicationCommandOptionType from discord.js v14, replacing the old Types constants.


333-366: LGTM! Embed builder updates have been correctly implemented.

The changes properly update the embed creation to use the new EmbedBuilder class from discord.js v14, replacing the old MessageEmbed.

🧰 Tools
🪛 Biome (1.9.4)

[error] 352-354: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)

package.json (1)

54-54: Verify compatibility with discord.js v14.

The upgrade from discord.js v13 to v14 is a major version change that introduces breaking changes. Please ensure:

  1. All breaking changes are addressed across the codebase.
  2. The Node.js version requirement (>=16.6.2) meets discord.js v14's requirements.
src/interactions/channels/Rooms.js (3)

1-1: LGTM! Import optimization.

The import statement has been correctly updated to use specific imports from discord.js v14, which is more efficient than importing the entire module.


31-32: LGTM! Permission flags correctly updated.

All permission flags have been properly updated to use PermissionsBitField.Flags instead of the deprecated Permissions.FLAGS, maintaining appropriate permissions for each context.

Also applies to: 42-47, 60-68, 75-81, 89-97


226-226: LGTM! Command option types correctly updated.

All command option types have been properly updated to use ApplicationCommandOptionType instead of the deprecated Types, maintaining appropriate types for each command option.

Also applies to: 230-231, 237-238, 242-243, 247-248, 252-253, 257-258, 264-265, 268-269, 272-273, 276-277, 280-281, 284-285, 288-289, 292-293, 300-301, 304-305, 312-313, 316-317, 324-325, 328-329

src/utilities/CommonFunctions.js (3)

1-1: LGTM! Import optimization.

The import statement has been correctly updated to use specific imports from discord.js v14.


483-484: LGTM! Type annotations updated.

The type annotations have been correctly updated to use EmbedBuilder instead of MessageEmbed.

Also applies to: 562-563, 581-582


533-533: LGTM! Embed creation updated.

All instances of embed creation have been properly updated to use EmbedBuilder instead of MessageEmbed.

Also applies to: 584-584, 603-603, 674-674, 706-706

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/interactions/tracking/Tracking.js (1)

549-549: Update permission check to use new format.

The permission check is using the old format. Update it to use the new PermissionsBitField format.

-if (channel.permissionsFor(interaction.client.user).has('MANAGE_WEBHOOKS')) {
+if (channel.permissionsFor(interaction.client.user).has(PermissionsBitField.Flags.ManageWebhooks)) {
🧹 Nitpick comments (1)
src/eventHandlers/NotifyOwnerJoin.js (1)

20-20: Fix typo in JSDoc comment.

There's a typo in the comment: "teh" should be "the".

-   * add the guild to teh Database
+   * add the guild to the Database
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 569608f and 9b28790.

📒 Files selected for processing (13)
  • src/eventHandlers/AddGuildToDatabase.js (3 hunks)
  • src/eventHandlers/BulkMessageDeleteHandle.js (3 hunks)
  • src/eventHandlers/DeleteChannel.js (3 hunks)
  • src/eventHandlers/LogMemberBan.js (3 hunks)
  • src/eventHandlers/LogMemberRemove.js (3 hunks)
  • src/eventHandlers/LogMemberUnban.js (3 hunks)
  • src/eventHandlers/MessageDeleteHandle.js (2 hunks)
  • src/eventHandlers/NotifyOwnerJoin.js (3 hunks)
  • src/eventHandlers/UpdateGuildStatistics.js (2 hunks)
  • src/interactions/channels/Rooms.js (11 hunks)
  • src/interactions/channels/Templates.js (2 hunks)
  • src/interactions/tracking/Tracking.js (12 hunks)
  • src/utilities/Webhook.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/eventHandlers/AddGuildToDatabase.js
  • src/eventHandlers/LogMemberRemove.js
  • src/eventHandlers/LogMemberUnban.js
  • src/eventHandlers/BulkMessageDeleteHandle.js
  • src/eventHandlers/UpdateGuildStatistics.js
  • src/utilities/Webhook.js
  • src/eventHandlers/LogMemberBan.js
  • src/interactions/channels/Rooms.js
🔇 Additional comments (22)
src/eventHandlers/NotifyOwnerJoin.js (3)

1-1: LGTM! Import statement updated correctly.

The change to import Events specifically from 'discord.js' aligns with v14's modular import approach.


15-15: LGTM! Event constant updated to v14 format.

The event constant has been correctly updated from GUILD_CREATE to Events.GuildCreate to match discord.js v14's camelCase event naming convention.


31-31: LGTM! Guild owner access updated correctly.

The changes correctly implement discord.js v14's requirement to fetch the guild owner asynchronously using guild.fetchOwner() instead of accessing the owner property directly.

Also applies to: 39-39, 45-45

src/eventHandlers/DeleteChannel.js (3)

1-1: LGTM! Import statement updated correctly for discord.js v14.

The change from importing the entire Discord object to specific imports (ChannelType, Events) follows the recommended modular approach in discord.js v14.


14-14: LGTM! Event constant updated to follow v14 naming convention.

The event constant has been correctly updated from Events.CHANNEL_DELETE to Events.ChannelDelete following discord.js v14's camelCase naming convention.


24-24: LGTM! Channel type check improved using ChannelType enum.

The channel type comparison has been updated to use the ChannelType.GuildVoice enum instead of a string literal, improving type safety and maintainability.

src/eventHandlers/MessageDeleteHandle.js (3)

1-1: LGTM! Import statement updated correctly for discord.js v14.

The change from importing the entire Discord object to specific imports (ChannelType, Events) follows the recommended modular approach in discord.js v14.


13-13: LGTM! Event constant updated to follow v14 naming convention.

The event constant has been correctly updated from Events.MESSAGE_DELETE to Events.MessageDelete following discord.js v14's camelCase naming convention.


30-30: LGTM! Channel type check improved using ChannelType enum.

The channel type comparison has been updated to use the ChannelType.GuildText enum instead of a string literal, improving type safety and maintainability.

src/interactions/channels/Templates.js (6)

1-1: LGTM! Correct modular imports for discord.js v14.

The change properly imports specific components instead of the entire Discord namespace, following discord.js v14's modular approach.


10-10: LGTM! Correct ApplicationCommandOptionType usage.

The change properly uses the new ApplicationCommandOptionType.Channel enum from discord.js v14.


18-18: LGTM! Correct PermissionsBitField usage.

The change properly uses the new PermissionsBitField.Flags.ManageGuild enum from discord.js v14.


22-22: LGTM! Consistent ApplicationCommandOptionType.Subcommand usage.

The changes properly use the new ApplicationCommandOptionType.Subcommand enum consistently across all subcommands.

Also applies to: 27-27, 32-32, 36-36, 48-48


41-41: LGTM! Correct ApplicationCommandOptionType.String usage.

The change properly uses the new ApplicationCommandOptionType.String enum from discord.js v14.


59-59: LGTM! Correct ChannelType enum usage.

The change properly uses the new ChannelType.GuildVoice enum instead of the string literal.

src/interactions/tracking/Tracking.js (7)

1-12: LGTM! Clean import restructuring.

The imports have been correctly updated to use specific components from discord.js v14, which is a recommended practice for better tree-shaking and bundle optimization.


43-43: LGTM! Permission flag updated correctly.

The permission flag has been properly updated from Permissions.FLAGS.MANAGE_GUILD to PermissionsBitField.Flags.ManageGuild as per Discord.js v14.


47-47: LGTM! Command option types updated correctly.

All command option types have been properly updated to use the new ApplicationCommandOptionType enum from Discord.js v14:

  • SUB_COMMANDSubcommand
  • CHANNELChannel
  • STRINGString
  • BOOLEANBoolean

Also applies to: 51-51, 55-55, 65-65, 69-69, 73-73, 77-77, 81-81, 85-85


208-294: LGTM! Component builders updated correctly.

The component builders have been properly updated to use the new builder classes and button styles from Discord.js v14:

  • MessageActionRowActionRowBuilder
  • MessageButtonButtonBuilder
  • MessageSelectMenuStringSelectMenuBuilder
  • MessageButtonStylesButtonStyle

528-530: LGTM! Utility methods updated correctly.

The utility methods have been properly updated to use the new Utils class from Discord.js v14:

  • Discord.Util.escapeMarkdownUtils.escapeMarkdown
  • Discord.Util.removeMentionsUtils.removeMentions

100-100: Verify channel type comparison.

The channel type comparison has been updated, but let's verify that ChannelType.GuildText is the correct constant to use.

✅ Verification successful

🌐 Web query:

What are the available channel types in Discord.js v14?

💡 Result:

Discord.js v14 supports multiple channel types through its type system, which are essential for organizing server spaces and handling different communication formats. Here's a breakdown of available channel types:

## Channel Types
1. **CategoryChannel**  
   Used to group text/voice channels under collapsible sections with synchronized permissions[1][4].

2. **TextChannel**  
   Standard text-based channels for messages and file sharing[2][4].

3. **VoiceChannel**  
   Designed for voice communication and screen sharing[1][5].

4. **NewsChannel**  
   Specialized channels for broadcasting announcements cross-postable to follower servers[4][6].

5. **ForumChannel**  
   Structured channels for organized discussions using threads/posts[3][10].

6. **StageChannel**  
   Dedicated to live audio events with speakers and listeners[4].

7. **MediaChannel**  
   Focused on media sharing (introduced in later Discord updates)[4].

8. **Thread Channels** (`AnyThreadChannel`)  
   Temporary sub-channels under text/forum channels for focused discussions[2][7].

9. **DM Channels** (`DMChannel`, `PartialDMChannel`, `PartialGroupDMChannel`)  
   Private messaging channels between users or small groups[4][9].

## Key Features
- Categories (`CategoryChannel`) enable permission synchronization across nested channels[1][9].
- Forum channels (`ForumChannel`) support tags and structured posts[10].
- Threads inherit properties from parent channels and auto-archive after inactivity[2][7].
- Type checking can be done using `channel.type === ChannelType.GuildText` comparisons[4][6].

This structure allows granular control over permissions, content types, and organizational hierarchies in Discord servers[1][4][9].

Citations:

- 1: https://www.theyurig.com/blog/how-create-categories-discord-v14
- 2: https://www.theyurig.com/blog/how-create-text-channels-discord-v14
- 3: https://discordjs.guide/popular-topics/faq
- 4: https://discord.js.org/docs/packages/discord.js/14.14.1/Channel:TypeAlias
- 5: https://www.youtube.com/watch?v=0AOpNy_6EjU
- 6: https://discord.js.org/docs/packages/discord.js/14.14.1/Message:Class
- 7: https://gist.github.com/Iliannnn/f4985563833e2538b1b96a8cb89d72bb
- 8: https://discord.js.org/docs/packages/discord.js/14.14.0/GuildChannelManager:Class
- 9: https://discord.js.org/docs/packages/discord.js/14.14.0/CategoryChannel:Class
- 10: https://discord.js.org/docs/packages/discord.js/14.14.1/ForumChannel:Class

Channel Type Verification

The use of ChannelType.GuildText is correct for checking that the channel is indeed a guild text channel as per Discord.js v14 documentation. No changes are needed in this comparison.


306-308: Verify interaction collector configuration.

The interaction collector configuration has been updated, but let's verify the correct constants for interactionType and componentType.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/interactions/tracking/Tracking.js (1)

1-622: Consider enhancing error handling and type safety.

While the migration to discord.js v14 is complete and correct, consider these improvements:

  1. Add type annotations for interaction parameters in event handlers
  2. Use more specific error types in catch blocks
  3. Consider implementing rate limiting for webhook operations
🧰 Tools
🪛 Biome (1.9.4)

[error] 378-378: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 536-536: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b28790 and 09458d5.

📒 Files selected for processing (1)
  • src/interactions/tracking/Tracking.js (13 hunks)
🔇 Additional comments (5)
src/interactions/tracking/Tracking.js (5)

1-12: LGTM! Import statements and command definitions are correctly updated.

The changes properly implement discord.js v14's modular imports and new constants for permissions and command options.

Also applies to: 43-43, 47-47, 51-51, 55-55, 65-65, 69-69, 73-73, 77-77, 81-81, 85-85


100-100: LGTM! UI components are correctly migrated to use builders.

The changes properly implement:

  • Channel type checks using the new ChannelType enum
  • Component creation using the new builder pattern (ActionRowBuilder, ButtonBuilder, StringSelectMenuBuilder)
  • Button styles using the new ButtonStyle enum

Also applies to: 208-224, 227-238, 241-252, 255-266, 268-297


306-307: LGTM! Interaction collectors and handlers are properly updated.

The changes correctly implement:

  • New interaction types for collectors
  • New component types for button and select menu interactions

Also applies to: 361-362, 382-393, 403-414


528-530: LGTM! Utils methods are properly used.

The changes correctly use the new Utils methods for escaping markdown and removing mentions.


549-549: LGTM! Permission checks are properly updated.

The changes correctly use PermissionsBitField.Flags for permission checks.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/interactions/tracking/Tracking.js (1)

305-311: Fix interaction collector configuration.

The interactionType value appears incorrect. interaction.MESSAGE_COMPONENT is not a valid property.

 const groupCollector = new InteractionCollector(interaction.client, {
-  interactionType: interaction.MESSAGE_COMPONENT,
+  interactionType: InteractionType.MessageComponent,
   componentType: ComponentType.StringSelect,
   message,
   guild: interaction.guild,
   channel: interaction.channel,
 });
🧹 Nitpick comments (4)
src/interactions/tracking/Tracking.js (3)

99-101: Consider additional channel permission validation.

While the channel type check is correct, consider also validating that the bot has necessary permissions (VIEW_CHANNEL, SEND_MESSAGES) in the channel before proceeding.

 if (options?.getChannel('channel').type !== ChannelType.GuildText) {
   return interaction.editReply({
     ephemeral: ctx.ephemerate,
     content: `:warning: ${options.getChannel('channel')} is not a text channel. :warning:`,
   });
 }
+const permissions = options.getChannel('channel').permissionsFor(interaction.client.user);
+if (!permissions.has([PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages])) {
+  return interaction.editReply({
+    ephemeral: ctx.ephemerate,
+    content: `:warning: Missing required permissions in ${options.getChannel('channel')} :warning:`,
+  });
+}

528-530: Consider wrapping Utils calls in try-catch.

While the Utils methods are correctly used, they could throw errors if the input is malformed.

-const pingsString = ctx.i18n`Adding \`${Utils.escapeMarkdown(
-  Utils.removeMentions(prepend)
-)}\` for ${add?.events?.length || 0} events, ${add?.items?.length || 0} items`;
+let sanitizedPrepend;
+try {
+  sanitizedPrepend = Utils.escapeMarkdown(Utils.removeMentions(prepend));
+} catch (error) {
+  ctx.logger.error('Failed to sanitize prepend:', error);
+  sanitizedPrepend = '[invalid content]';
+}
+const pingsString = ctx.i18n`Adding \`${sanitizedPrepend}\` for ${add?.events?.length || 0} events, ${add?.items?.length || 0} items`;

580-584: Add timeout handling for webhook creation.

Consider adding a timeout for the webhook creation operation to prevent hanging.

+const WEBHOOK_TIMEOUT = 5000; // 5 seconds
 try {
-  webhook = await channel.createWebhook({
-    name: ctx.settings.defaults.username,
-    avatar: ctx.settings.defaults.avatar,
-    reason: 'Automated Webhook setup for Notifications',
-  });
+  const createWebhookPromise = channel.createWebhook({
+    name: ctx.settings.defaults.username,
+    avatar: ctx.settings.defaults.avatar,
+    reason: 'Automated Webhook setup for Notifications',
+  });
+  webhook = await Promise.race([
+    createWebhookPromise,
+    new Promise((_, reject) =>
+      setTimeout(() => reject(new Error('Webhook creation timed out')), WEBHOOK_TIMEOUT)
+    ),
+  ]);
 } catch (e) {
   ctx.logger.error(e);
   await interaction.followUp(`${emojify('red_tick')} Cannot set up webhooks: failed to make new.`);
 }
src/interactions/core/su.js (1)

16-16: Consider removing redundant permission.

Since the command is already restricted with ownerOnly: true, the defaultMemberPermissions setting is redundant and can be safely removed.

-    defaultMemberPermissions: PermissionsBitField.Flags.Administrator,
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09458d5 and 79c6913.

📒 Files selected for processing (3)
  • src/interactions/core/su.js (5 hunks)
  • src/interactions/tracking/Tracking.js (14 hunks)
  • src/utilities/Webhook.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utilities/Webhook.js
🔇 Additional comments (4)
src/interactions/tracking/Tracking.js (1)

1-12: LGTM! Clean modular imports.

The granular imports from discord.js align with v14's modular approach, improving tree-shaking capabilities.

src/interactions/core/su.js (3)

1-1: LGTM! Improved imports.

The change to specific imports from discord.js follows best practices and improves code maintainability.


21-21: LGTM! Correct command option type updates.

The command option types have been correctly updated to use the new ApplicationCommandOptionType enum from discord.js v14.

Also applies to: 26-26, 31-31, 44-44, 57-57, 70-70, 35-35, 48-48, 61-61, 79-79


127-127: Verify ServerInfoEmbed compatibility with EmbedBuilder.

The change from MessageEmbed to EmbedBuilder is correct, but ensure that the ServerInfoEmbed class has been updated to work with EmbedBuilder.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check if ServerInfoEmbed has been updated for EmbedBuilder compatibility

# Search for MessageEmbed usage in ServerInfoEmbed
rg -A 5 "MessageEmbed" "src/embeds/ServerInfoEmbed.js"

# Search for EmbedBuilder usage in ServerInfoEmbed
rg -A 5 "EmbedBuilder" "src/embeds/ServerInfoEmbed.js"

Length of output: 105


Let's take a closer look at the contents of the ServerInfoEmbed file to verify its compatibility with EmbedBuilder. We'll print the file content to inspect if it imports and uses EmbedBuilder appropriately.


🏁 Script executed:

#!/bin/bash
# Display the content of the ServerInfoEmbed file for manual inspection.
cat src/embeds/ServerInfoEmbed.js

Length of output: 2215


Let's inspect the BaseEmbed file to see if it's updated for EmbedBuilder compatibility. That will help us ensure that ServerInfoEmbed (which extends BaseEmbed) is using the updated EmbedBuilder correctly.


🏁 Script executed:

#!/bin/bash
# Display the content of the BaseEmbed file for manual inspection.
cat src/embeds/BaseEmbed.js

Length of output: 642


ServerInfoEmbed is compatible with EmbedBuilder.

Both ServerInfoEmbed and its parent class BaseEmbed correctly use EmbedBuilder from discord.js. BaseEmbed imports EmbedBuilder and initializes the embed with default values, and ServerInfoEmbed extends BaseEmbed while setting its properties appropriately. No outdated MessageEmbed usage is found.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/interactions/core/Settings.js (2)

542-542: Replace this with class name in static context.

Using this in a static context can be confusing. Use the class name instead for better clarity.

Apply this diff to fix the issue:

-          `${perms.has(PermissionsBitField.Flags.ManageRoles) ? this.#check : this.#xmark} Permission Present`
+          `${perms.has(PermissionsBitField.Flags.ManageRoles) ? Settings.#check : Settings.#xmark} Permission Present`

-            perms.has(PermissionsBitField.Flags.ManageWebhooks) ? `${this.#check}  Can` : `${this.#xmark} Cannot`
+            perms.has(PermissionsBitField.Flags.ManageWebhooks) ? `${Settings.#check}  Can` : `${Settings.#xmark} Cannot`

Also applies to: 553-553

🧰 Tools
🪛 Biome (1.9.4)

[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


227-227: Update JSDoc return type.

The JSDoc comment still references the old Discord.MessageEmbed type.

Apply this diff to fix the issue:

-   * @returns {Promise<Array<Discord.MessageEmbed>>}
+   * @returns {Promise<Array<EmbedBuilder>>}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 79c6913 and 1895a79.

📒 Files selected for processing (1)
  • src/interactions/core/Settings.js (12 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/interactions/core/Settings.js

[error] 525-526: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 553-553: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 553-553: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (4)
src/interactions/core/Settings.js (4)

1-1: LGTM! Import statement updated correctly.

The import statement has been properly updated to use specific imports from discord.js v14, which is more efficient than importing the entire Discord object.


26-27: LGTM! Command option types updated correctly.

All command option types have been properly updated to use the new ApplicationCommandOptionType enum from discord.js v14.

Also applies to: 48-49, 59-60, 70-71, 81-82, 92-93, 105-106, 117-118, 122-123, 135-136, 147-148, 161-162, 173-174, 184-185


405-405: LGTM! Permission flags updated correctly.

The permission flags have been properly updated to use the new PermissionsBitField.Flags from discord.js v14.


230-230: LGTM! MessageEmbed replaced with EmbedBuilder.

All instances of MessageEmbed have been correctly replaced with EmbedBuilder from discord.js v14.

Also applies to: 381-381, 525-525

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
src/interactions/channels/Templates.js (1)

115-118: Update reply to use flags instead of ephemeral.

For consistency with other changes in the file, update this reply to use flags instead of ephemeral.

Apply this diff:

-          ephemeral: ctx.ephemerate,
+          flags: ctx.flags,
🧹 Nitpick comments (2)
src/interactions/core/Settings.js (1)

542-542: Replace this with class name in static context.

Using this in a static context can be confusing. Use the class name instead.

Apply this diff to fix the issue:

-          `${perms.has(PermissionsBitField.Flags.ManageRoles) ? this.#check : this.#xmark} Permission Present`
+          `${perms.has(PermissionsBitField.Flags.ManageRoles) ? Settings.#check : Settings.#xmark} Permission Present`
🧰 Tools
🪛 Biome (1.9.4)

[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

src/interactions/tracking/Tracking.js (1)

580-584: Consider adding specific error handling for webhook creation.

While the code correctly uses the new options object pattern for webhook creation, consider adding specific error handling for common webhook creation failures (e.g., rate limits, permission issues) to provide more informative error messages.

 try {
   webhook = await channel.createWebhook({
     name: ctx.settings.defaults.username,
     avatar: ctx.settings.defaults.avatar,
     reason: 'Automated Webhook setup for Notifications',
   });
 } catch (e) {
   ctx.logger.error(e);
+  if (e.code === 30007) {
+    await interaction.followUp(`${emojify('red_tick')} Cannot set up webhooks: webhook limit reached for this channel.`);
+  } else if (e.code === 50013) {
+    await interaction.followUp(`${emojify('red_tick')} Cannot set up webhooks: missing required permissions.`);
+  } else {
     await interaction.followUp(`${emojify('red_tick')} Cannot set up webhooks: failed to make new.`);
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1895a79 and 4efe7ef.

📒 Files selected for processing (19)
  • src/bot.js (4 hunks)
  • src/eventHandlers/InteractionHandler.js (8 hunks)
  • src/interactions/channels/Rooms.js (19 hunks)
  • src/interactions/channels/Templates.js (3 hunks)
  • src/interactions/core/Ping.js (4 hunks)
  • src/interactions/core/Settings.js (13 hunks)
  • src/interactions/core/su.js (6 hunks)
  • src/interactions/custom/CustomCommands.js (3 hunks)
  • src/interactions/fun/Hug.js (1 hunks)
  • src/interactions/fun/Joke.js (2 hunks)
  • src/interactions/tracking/Tracking.js (16 hunks)
  • src/interactions/warframe/Builds.js (10 hunks)
  • src/interactions/warframe/Calculator.js (3 hunks)
  • src/interactions/warframe/LFG.js (6 hunks)
  • src/interactions/warframe/Lookup.js (4 hunks)
  • src/interactions/warframe/PriceCheck.js (3 hunks)
  • src/interactions/warframe/WhatsIn.js (3 hunks)
  • src/interactions/warframe/WhereIs.js (3 hunks)
  • src/utilities/Webhook.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/interactions/core/Ping.js
  • src/interactions/warframe/WhatsIn.js
  • src/interactions/fun/Joke.js
  • src/utilities/Webhook.js
  • src/interactions/warframe/Lookup.js
  • src/eventHandlers/InteractionHandler.js
  • src/interactions/warframe/PriceCheck.js
  • src/interactions/warframe/Calculator.js
  • src/interactions/core/su.js
🧰 Additional context used
🪛 Biome (1.9.4)
src/interactions/warframe/Builds.js

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 524-530: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/interactions/core/Settings.js

[error] 525-526: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 542-542: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 553-553: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 553-553: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (22)
src/interactions/fun/Hug.js (1)

12-12: Verify the flags usage aligns with discord.js v14 documentation.

The change from ephemeral to flags aligns with the discord.js v14 upgrade. However, let's verify this is implemented correctly.

✅ Verification successful

🌐 Web query:

How to set ephemeral messages in discord.js v14?

💡 Result:

To set ephemeral messages in Discord.js v14, use either direct flags in response methods or leverage Discord's API constraints for hidden interactions. Here's how to implement them effectively:

## Initial Ephemeral Replies
Use `ephemeral: true` in reply options:
```javascript
// Basic ephemeral reply
await interaction.reply({ 
  content: 'Secret message', 
  ephemeral: true 
});

// With embeds/components
const embed = new EmbedBuilder().setDescription('Ephemeral embed');
await interaction.reply({
  embeds: [embed],
  components: [actionRow],
  ephemeral: true
});
```
[4][7][9]

## Deferred Ephemeral Responses
When using deferred replies:
```javascript
// Defer with ephemeral flag
await interaction.deferReply({ ephemeral: true });

// Later edit/update (retains ephemeral)
await interaction.editReply('Updated hidden message');
```
[1][4][9]

## Ephemeral Follow-ups
For subsequent messages after initial response:
```javascript
// First reply (non-ephemeral)
await interaction.reply('Public message');

// Ephemeral follow-up
await interaction.followUp({
  content: 'Hidden follow-up',
  flags: MessageFlags.Ephemeral // Alternative syntax
});
```
[9][5]

## Key Limitations
- **Deferral Lock**: Once deferred with `ephemeral`, all subsequent responses inherit this state[1]
- **Message Management**:
  - Ephemeral messages can't be fetched via `messages.fetch()`[2][3]
  - Use interaction methods (`editReply()`, `deleteReply()`) for modifications[4][8]
- **15-Minute Window**: Interaction tokens expire 15 minutes after initial response[9]

For components in ephemeral messages:
```javascript
// Button in ephemeral message
const button = new ButtonBuilder()
  .setCustomId('secret-btn')
  .setLabel('Ephemeral Button');

await interaction.reply({
  components: [new ActionRowBuilder().addComponents(button)],
  ephemeral: true
});
```
[2][7]

When combining deferral and follow-ups:
```javascript
// Defer publicly but send private follow-up
await interaction.deferReply({ ephemeral: false });
await interaction.followUp({
  content: 'Hidden after public defer',
  ephemeral: true 
}); // This will appear as separate message
```
[1][6]

Remember that ephemerality can't be changed after initial response - plan your interaction flow accordingly[1][8]. Use `MessageFlags.Ephemeral` (value 64) for direct flag manipulation when needed[5].

Citations:

- 1: https://github.com/discordjs/discord.js/issues/5702
- 2: https://www.answeroverflow.com/m/1155986363150258217
- 3: https://www.answeroverflow.com/m/1133851560879857674
- 4: https://discord.js.org/docs/packages/discord.js/14.14.0/CommandInteraction:Class
- 5: https://discord.js.org/docs/packages/discord.js/14.17.3/MessageFlags:Enum
- 6: https://www.youtube.com/watch?v=jntUHXiFB8g
- 7: https://discord.js.org/docs/packages/discord.js/14.14.1/MessageComponentInteraction:Class
- 8: https://github.com/discord/discord-api-docs/issues/6007
- 9: https://discordjs.guide/slash-commands/response-methods
- 10: https://support-apps.discord.com/hc/en-us/articles/26501839512855-Ephemeral-Messages-FAQ

Flags usage in Hug.js aligns with discord.js v14 expectations.

The change from using the boolean ephemeral option to passing flags (presumably set to MessageFlags.Ephemeral when needed) is consistent with the standardized approach across the codebase. As verified by the query results, while initial ephemeral replies typically use the ephemeral boolean, using flags is acceptable when the value is properly computed (as with ctx.flags) to represent ephemeral behavior.

• Confirm that ctx.flags holds the appropriate flags value (e.g., MessageFlags.Ephemeral) when an ephemeral reply is intended.
• The updated implementation reflects the intended upgrade for discord.js v14.

src/bot.js (3)

1-1: LGTM! Clean import restructuring.

The direct imports from discord.js improve code clarity and follow the v14 module structure.


64-68: LGTM! Intents correctly updated.

The intents have been properly updated to use GatewayIntentBits enum.


144-172: LGTM! Event names correctly updated.

All event names have been properly updated to use the new camelCase format from the Events enum.

src/interactions/custom/CustomCommands.js (2)

1-1: LGTM! Permissions correctly updated.

The permissions have been properly updated to use PermissionsBitField.Flags.ManageGuild.

Also applies to: 15-15


19-46: LGTM! Command option types correctly updated.

All command option types have been properly updated to use ApplicationCommandOptionType enum.

src/interactions/warframe/WhereIs.js (2)

1-1: LGTM! Embed creation updated.

The embed creation has been properly updated to use EmbedBuilder.

Also applies to: 95-95


14-14: LGTM! Command option type correctly updated.

The command option type has been properly updated to use ApplicationCommandOptionType.String.

src/interactions/channels/Templates.js (1)

1-1: LGTM! Channel type check updated.

The channel type check has been properly updated to use ChannelType.GuildVoice.

Also applies to: 59-59

src/interactions/warframe/LFG.js (4)

1-11: LGTM!

The imports are correctly updated to use specific imports from discord.js v14 instead of importing the entire module.


202-204: LGTM!

The error handling for channel resolution is correctly updated to use flags instead of ephemeral.


206-223: LGTM!

The button components are correctly updated to use the new builders and styles from discord.js v14:

  • MessageActionRowActionRowBuilder
  • MessageButtonButtonBuilder
  • MessageButtonStylesButtonStyle

234-237: LGTM!

The interaction collector is correctly updated to use the new types from discord.js v14:

  • InteractionTypes.MESSAGE_COMPONENTInteractionType.MessageComponent
  • MessageComponentTypes.BUTTONComponentType.Button
src/interactions/core/Settings.js (2)

1-1: LGTM!

The imports are correctly updated to use specific imports from discord.js v14 instead of importing the entire module.


525-526: ⚠️ Potential issue

Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'diag':
+       {
        const embed = new EmbedBuilder();
        embed.setTitle(`Diagnostics for Shard ${interaction.guild.shardId + 1}/${interaction.client.ws.shards.size}`);
+       }

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 525-526: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/interactions/warframe/Builds.js (1)

1-11: LGTM!

The imports are correctly updated to use specific imports from discord.js v14 instead of importing the entire module.

src/interactions/channels/Rooms.js (3)

1-1: LGTM!

The imports are correctly updated to use specific imports from discord.js v14 instead of importing the entire module.


31-97: LGTM!

The permission flags are correctly updated to use PermissionsBitField.Flags instead of the old Permissions.FLAGS.


141-165: LGTM!

The channel types are correctly updated to use ChannelType instead of the old channel type constants.

src/interactions/tracking/Tracking.js (3)

1-12: LGTM! Improved imports for better tree-shaking.

The updated imports follow discord.js v14's recommended pattern of importing specific components instead of the entire Discord namespace. This change enables better tree-shaking and potentially reduces bundle size.


43-86: LGTM! Correctly updated permission flags and command option types.

The changes properly implement discord.js v14's new permission system using PermissionsBitField and command option types using ApplicationCommandOptionType.


305-311: Verify the interaction collector configuration.

The interactionType is using interaction.MESSAGE_COMPONENT which seems incorrect. According to the discord.js v14 documentation, it should be using InteractionType.MessageComponent from the discord.js package.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/utilities/CommonFunctions.js (1)

599-609: Consider using builder methods instead of direct data manipulation.

While the code works, directly manipulating embed.data is not recommended. Consider using the builder methods provided by discord.js v14 for better maintainability and future compatibility.

Apply this diff to use builder methods:

-  if (embed.data.fields?.length > fieldLimit) {
-    const fieldGroups = createGroupedArray(embed.data.fields, fieldLimit);
+  const fields = embed.data.fields || [];
+  if (fields.length > fieldLimit) {
+    const fieldGroups = createGroupedArray(fields, fieldLimit);
     const embeds = [];
     fieldGroups.forEach((fields, index) => {
       const smEmbed = new EmbedBuilder(embedDefaults);
       embed.setTitle(title);

-      smEmbed.data.fields = fields;
+      smEmbed.addFields(fields);
       if (index === 0) {
-        smEmbed.setDescription(embed.data.description);
+        smEmbed.setDescription(embed.description);
       }
       embeds.push(smEmbed);
     });
src/interactions/core/Settings.js (2)

26-27: Consider extracting repeated command option types.

The ApplicationCommandOptionType is repeated across multiple command definitions. Consider extracting these into constants to improve maintainability.

+ const COMMAND_TYPES = {
+   SUBCOMMAND: ApplicationCommandOptionType.Subcommand,
+   BOOLEAN: ApplicationCommandOptionType.Boolean,
+   CHANNEL: ApplicationCommandOptionType.Channel,
+   STRING: ApplicationCommandOptionType.String,
+ };

  static #rooms = [
    {
      ...cmds['settings.allow_rooms'],
-     type: ApplicationCommandOptionType.Subcommand,
+     type: COMMAND_TYPES.SUBCOMMAND,
      // ... rest of the code
    },
    // ... other commands
  ];

Also applies to: 44-45, 55-56, 66-67, 77-78, 88-89, 101-102, 113-114, 131-132, 143-144, 157-158, 169-170, 181-182


535-537: Replace 'this' with class name in static methods.

Using 'this' in static methods can be confusing. Consider using the class name instead for better clarity.

-         `${perms.has(PermissionsBitField.Flags.ManageRoles) ? this.#check : this.#xmark} Permission Present`
+         `${perms.has(PermissionsBitField.Flags.ManageRoles) ? Settings.#check : Settings.#xmark} Permission Present`
-        rolePermTokens.push(`${this.#empty} Bot role position: ${interaction.guild.members.me.roles.highest.position}`);
+        rolePermTokens.push(`${Settings.#empty} Bot role position: ${interaction.guild.members.me.roles.highest.position}`);
          `${
-            perms.has(PermissionsBitField.Flags.ManageWebhooks) ? `${this.#check}  Can` : `${this.#xmark} Cannot`
+            perms.has(PermissionsBitField.Flags.ManageWebhooks) ? `${Settings.#check}  Can` : `${Settings.#xmark} Cannot`
          } Manage Webhooks`,

Also applies to: 546-547

🧰 Tools
🪛 Biome (1.9.4)

[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 537-537: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b8fdd7 and e4c164f.

📒 Files selected for processing (2)
  • src/interactions/core/Settings.js (14 hunks)
  • src/utilities/CommonFunctions.js (8 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/interactions/core/Settings.js

[error] 518-519: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 537-537: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (5)
src/utilities/CommonFunctions.js (3)

1-1: LGTM! Using specific imports.

The change to import specific classes directly from discord.js is aligned with v14's modular import system.


483-483: LGTM! Updated parameter types for discord.js v14.

The parameter type changes from MessageEmbed to EmbedBuilder are consistent with discord.js v14's breaking changes.

Also applies to: 562-562


533-536: LGTM! Correctly implemented EmbedBuilder API.

The changes properly implement the new EmbedBuilder API, including:

  • Using instanceof EmbedBuilder for type checking
  • Using the new object-based setter method for footer

Also applies to: 584-584

src/interactions/core/Settings.js (2)

1-1: LGTM! Clean import statement.

The specific imports from discord.js follow best practices and align with v14 changes.


518-519: Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'diag':
+       {
        const embed = new EmbedBuilder();
        embed.setTitle(`Diagnostics for Shard ${interaction.guild.shardId + 1}/${interaction.client.ws.shards.size}`);
+       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 518-519: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/utilities/CommonFunctions.js (1)

533-536: LGTM! Correctly updated to use EmbedBuilder API.

The changes properly handle the new EmbedBuilder API in discord.js v14. Consider extracting common embed operations into helper functions to reduce duplication and improve maintainability.

Consider creating helper functions for common embed operations:

+const setEmbedFooter = (embed, text, iconURL) => {
+  embed.setFooter({ text, iconURL });
+};
+
+const setEmbedFields = (embed, fields) => {
+  embed.setFields(fields.map(field => ({
+    ...field,
+    inline: true
+  })));
+};

Also applies to: 584-584, 599-601, 606-608

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e4c164f and bdfa009.

📒 Files selected for processing (1)
  • src/utilities/CommonFunctions.js (8 hunks)
🔇 Additional comments (1)
src/utilities/CommonFunctions.js (1)

1-1: LGTM! Improved import statement.

The change to import specific components instead of the entire module is better for tree-shaking and aligns with discord.js v14 practices.

@SlayerOrnstein SlayerOrnstein force-pushed the feat-discord-api-migration branch from bdfa009 to 8fd4d65 Compare February 20, 2025 02:28
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🔭 Outside diff range comments (3)
src/embeds/WhereisEmbed.js (1)

12-12: 🛠️ Refactor suggestion

Remove redundant fields initialization.

The direct assignment to this.fields is unnecessary since fields are now managed through the addFields method. This initialization is redundant and inconsistent with discord.js v14's EmbedBuilder pattern.

-    this.fields = [];
src/embeds/SolarisEmbed.js (1)

31-38: 🛠️ Refactor suggestion

Maintain consistency by using setter methods for all properties.

While setFooter is now used, other properties (title, color, thumbnail, description, timestamp) still use direct assignments. For consistency with discord.js v14's EmbedBuilder API and other embed classes, consider using setter methods for all properties.

-    this.title = `Orb Vallis - ${state.isWarm ? 'Warm' : 'Cold'}`;
-    this.color = state.isWarm ? 0xb64624 : 0x000066;
-    this.thumbnail = {
-      url: solaris,
-    };
+    this.setTitle(`Orb Vallis - ${state.isWarm ? 'Warm' : 'Cold'}`);
+    this.setColor(state.isWarm ? 0xb64624 : 0x000066);
+    this.setThumbnail(solaris);
     const warmstring = i18n`Time remaining until ${state.isWarm ? i18n`Cold` : i18n`Warm`}: ${rTime(state.expiry)}`;
-    this.description = `${state.bounty ? makeJobs(state.bounty) : ''}\n\n${warmstring}`;
+    this.setDescription(`${state.bounty ? makeJobs(state.bounty) : ''}\n\n${warmstring}`);
     this.setFooter({ text: `${state.isWarm ? i18n`Cold` : i18n`Warm`} starts ` });
-    this.timestamp = new Date(state.expiry).getTime();
+    this.setTimestamp(new Date(state.expiry).getTime());

Also applies to: 39-39

src/embeds/ServerInfoEmbed.js (1)

52-53: ⚠️ Potential issue

Update channel type checks for discord.js v14.

The channel type checks use string literals which were updated to enums in v14.

-channel.type === 'GUILD_TEXT'
+channel.type === ChannelType.GuildText

-channel.type === 'GUILD_VOICE'
+channel.type === ChannelType.GuildVoice

Add the import at the top:

+import { ChannelType } from 'discord.js';

Also applies to: 57-58

🧹 Nitpick comments (28)
src/embeds/ErrorEmbed.js (1)

22-23: Simplify timestamp handling.

While the transition to setter methods is correct, the timestamp handling can be simplified.

-    this.setTimestamp(new Date().getTime());
+    this.setTimestamp(new Date());

discord.js can handle Date objects directly, no need to convert to timestamp.

src/embeds/WhereisEmbed.js (1)

30-31: Consider simplifying the title template literal.

The changes correctly implement discord.js v14's EmbedBuilder methods. However, the template literal for the title could be simplified since it only contains a single variable.

-    this.setTitle(`${query}`);
+    this.setTitle(query);
src/embeds/FissureEmbed.js (1)

57-57: Consider using discord.js Colors enum.

Instead of using a hardcoded hex value, consider using the built-in Colors enum from discord.js v14 for better maintainability and consistency.

-    this.data.color = 0x4aa1b2;
+    this.data.color = Colors.Aqua;

Don't forget to add the import at the top:

import { Colors } from 'discord.js';
src/embeds/SteelPathEmbed.js (1)

9-19: LGTM! Consider improving template literal readability.

The migration to setDescription aligns with discord.js v14's EmbedBuilder pattern. The functionality is preserved while improving the code structure.

Consider improving readability by breaking down the template literal into smaller parts:

-    this.setDescription(`${i18n`**Rotating:**`} ${offering.currentReward.name || offering.currentReward}: ${
-      offering.currentReward.cost || '???'
-    }${isCommand ? emojify('steelessence') : i18n` essence`}
-    
-  ${i18n`**Evergreen:**`}
-  ${offering.evergreens
-    .map(
-      (reward) =>
-        `:white_small_square: ${reward.name}: ${reward.cost}${isCommand ? emojify('steelessence') : i18n` essence`}`
-    )
-    .join('\n')}`);
+    const rotatingSection = `${i18n`**Rotating:**`} ${offering.currentReward.name || offering.currentReward}: ${
+      offering.currentReward.cost || '???'
+    }${isCommand ? emojify('steelessence') : i18n` essence`}`;
+    
+    const evergreenSection = `${i18n`**Evergreen:**`}\n${offering.evergreens
+      .map(
+        (reward) =>
+          `:white_small_square: ${reward.name}: ${reward.cost}${isCommand ? emojify('steelessence') : i18n` essence`}`
+      )
+      .join('\n')}`;
+    
+    this.setDescription(`${rotatingSection}\n\n${evergreenSection}`);
src/embeds/KuvaEmbed.js (2)

7-9: Enhance class documentation.

Consider adding more detailed documentation about what Kuva missions are and how this embed is used to display them.

 /**
- * Generates Kuva mission embed embeds
+ * Generates embeds for displaying Kuva missions.
+ *
+ * Kuva missions are special missions that reward players with Kuva,
+ * a resource used for various in-game mechanics like Riven mod rerolling.
+ * This embed organizes missions by enemy type and displays their nodes.
  */

17-34: Consider error handling and method chaining.

Two suggestions to enhance the code:

  1. Add error handling for empty kuver array
  2. Chain setter methods for better readability
   constructor(kuver, { platform, i18n, locale }) {
     super(locale);
+    
+    if (!kuver?.length) {
+      throw new Error('No Kuva missions provided');
+    }
 
-    this.setThumbnail(kuvaThumb);
-    this.setColor(0x742725);
-    this.setTitle(i18n`[${platform.toUpperCase()}] Worldstate - Kuva`);
     const grouped = groupBy(kuver, 'enemy');
-    this.setFields(
-      Object.keys(grouped).map((enemy) => ({
-        name: enemy,
-        value: grouped[enemy].map((kuva) => i18n`${kuva.type} on ${kuva.node}`).join('\n'),
-        inline: false,
-      }))
-    );
-
-    this.setFooter({ text: 'Expires' });
-    this.setTimestamp(kuver[0].expiry);
+    
+    this
+      .setThumbnail(kuvaThumb)
+      .setColor(0x742725)
+      .setTitle(i18n`[${platform.toUpperCase()}] Worldstate - Kuva`)
+      .setFields(
+        Object.keys(grouped).map((enemy) => ({
+          name: enemy,
+          value: grouped[enemy].map((kuva) => i18n`${kuva.type} on ${kuva.node}`).join('\n'),
+          inline: false,
+        }))
+      )
+      .setFooter({ text: 'Expires' })
+      .setTimestamp(kuver[0].expiry);
   }
src/embeds/NightwaveEmbed.js (1)

30-38: Remove redundant setFields call.

The setFields([]) call is unnecessary as addFields will initialize the fields array if it doesn't exist.

    this.setDescription(i18n`Season ${seasonDisplay} • Phase ${nightwave.phase + 1}`);
-   this.setFields([]);
    this.addFields([
      {
        name: i18n`Currently Active`,
        value: String(nightwave.activeChallenges.length),
        inline: false,
      },
    ]);
src/embeds/TwitchEmbed.js (3)

9-9: Consider improving readability of the image URL construction.

While the logic is correct, the URL construction could be more readable by breaking it down into steps.

-    this.setImage(`${streamData.thumbnail_url.replace('{width}', '1280').replace('{height}', '720')}?${Date.now()}`);
+    const thumbnailUrl = streamData.thumbnail_url
+      .replace('{width}', '1280')
+      .replace('{height}', '720');
+    const imageUrl = `${thumbnailUrl}?${Date.now()}`;
+    this.setImage(imageUrl);

11-15: Consider extracting hardcoded values to constants.

The color value and footer icon URL could be moved to a constants file or configuration for better maintainability.

+const TWITCH_PURPLE = 6570405;
+const TWITCH_ICON_URL = 'https://i.imgur.com/urcKWLO.png';

-    this.setColor(6570405);
+    this.setColor(TWITCH_PURPLE);
     this.setFooter({
       text: i18n`Live @`,
-      icon_url: 'https://i.imgur.com/urcKWLO.png',
+      icon_url: TWITCH_ICON_URL,
     });

27-27: Consider extracting URL transformation logic to a helper function.

The width/height replacement logic is duplicated between the thumbnail and image URLs. Consider extracting it to a helper function.

+  static transformTwitchUrl(url, width, height) {
+    return url
+      .replace('{width}', width)
+      .replace('{height}', height);
+  }

   constructor(streamData, { i18n, locale }) {
     // ...
-    this.setImage(`${streamData.thumbnail_url.replace('{width}', '1280').replace('{height}', '720')}?${Date.now()}`);
+    const thumbnailUrl = TwitchEmbed.transformTwitchUrl(streamData.thumbnail_url, '1280', '720');
+    this.setImage(`${thumbnailUrl}?${Date.now()}`);
     // ...
     if (streamData.game) {
-      this.setThumbnail(streamData.game.box_art_url.replace('{width}', '288').replace('{height}', '384'));
+      this.setThumbnail(TwitchEmbed.transformTwitchUrl(streamData.game.box_art_url, '288', '384'));
     }
   }
src/interactions/tracking/Tracking.js (4)

51-52: Consider restricting channel option types.

The channel options should explicitly specify which channel types are allowed using the channelTypes property to prevent users from selecting invalid channel types.

 {
   ...cmds['tracking.manage.channel'],
   type: ApplicationCommandOptionType.Channel,
+  channelTypes: [ChannelType.GuildText],
 }

Also applies to: 55-56, 77-78, 85-86


305-311: Enhance collector configuration.

The collector configuration could be more robust by:

  1. Adding a time limit
  2. Adding an error handler
  3. Adding a proper cleanup on end
 const groupCollector = new InteractionCollector(interaction.client, {
   interactionType: interaction.MESSAGE_COMPONENT,
   componentType: ComponentType.StringSelect,
   message,
   guild: interaction.guild,
   channel: interaction.channel,
+  time: 300000, // 5 minutes
+  idle: 60000, // 1 minute
 });
+
+groupCollector.on('end', (collected, reason) => {
+  if (reason !== 'limit') {
+    message.edit({
+      components: [],
+      content: 'Interaction timed out.'
+    }).catch(console.error);
+  }
+});

372-481: Consider refactoring the button handler.

The button handler has complex branching logic that could be simplified using a command pattern or a map of handlers.

+const buttonHandlers = {
+  save: async (button, current, message) => {
+    await ctx.settings.setTrackables(channel, current);
+    buttonCollector.stop('limit');
+    await this.#generateWebhook(interaction, ctx, channel);
+    return message.edit({...});
+  },
+  // ... other handlers
+};
+
 const buttonHandler = async (button) => {
   await button?.deferUpdate();
-  switch (button?.customId) {
-    case 'save':
-      // ... existing code
-    // ... other cases
-  }
+  const handler = buttonHandlers[button?.customId];
+  if (handler) {
+    return handler(button, current, message);
+  }
   // ... pagination logic
 };
🧰 Tools
🪛 Biome (1.9.4)

[error] 378-378: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


547-622: Enhance webhook error handling and cleanup.

Consider improving the webhook management by:

  1. Adding webhook cleanup for old/unused webhooks
  2. Implementing retry logic for failed operations
  3. Adding more detailed error logging
 static async #generateWebhook(interaction, ctx, channel, thread) {
+  const MAX_RETRIES = 3;
+  const RETRY_DELAY = 1000;
+
   channel = channel || interaction.channel;
   if (channel.permissionsFor(interaction.client.user).has(PermissionsBitField.Flags.ManageWebhooks)) {
     let webhook;
     let existingWebhooks;
     let setupMsg;
-    try {
-      setupMsg = await interaction.followUp({
-        content: 'Setting up webhook...',
-      });
-      existingWebhooks = (await channel.fetchWebhooks()).filter(
-        (w) => w.type === 'Incoming' && w?.owner?.id === interaction?.client?.user?.id && !!w.token
-      );
-    } catch (e) {
-      ctx.logger.error(e);
-      await interaction.followUp(`${emojify('red_tick')} Cannot set up webhooks: failed to get existing.`);
-    }
+    for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
+      try {
+        setupMsg = await interaction.followUp({
+          content: `Setting up webhook... (attempt ${attempt}/${MAX_RETRIES})`,
+        });
+        existingWebhooks = (await channel.fetchWebhooks()).filter(
+          (w) => w.type === 'Incoming' && w?.owner?.id === interaction?.client?.user?.id && !!w.token
+        );
+        
+        // Cleanup old webhooks if there are too many
+        if (existingWebhooks.size > 1) {
+          const [keep, ...remove] = existingWebhooks.values();
+          await Promise.all(remove.map(w => w.delete('Cleaning up old webhooks')));
+        }
+        break;
+      } catch (e) {
+        ctx.logger.error({ attempt, error: e }, 'Failed to set up webhook');
+        if (attempt === MAX_RETRIES) {
+          await interaction.followUp(`${emojify('red_tick')} Cannot set up webhooks after ${MAX_RETRIES} attempts.`);
+          return;
+        }
+        await new Promise(resolve => setTimeout(resolve, RETRY_DELAY));
+      }
+    }
src/embeds/BuildEmbed.js (1)

13-15: LGTM! The migration to discord.js v14 setter methods is correct.

The changes properly migrate from direct property assignments to EmbedBuilder's setter methods while maintaining the same functionality.

Consider extracting the footer text construction to a separate method for better readability:

-    this.setFooter({
-      text: `${build.id}${build.isPublic ? ' • Public' : ''} • Owned by ${
-        typeof build.owner === 'object' ? build.owner.tag : build.owner
-      }`,
-    });
+    this.setFooter({ text: this.#getFooterText(build) });
+  }
+
+  #getFooterText(build) {
+    const ownerText = typeof build.owner === 'object' ? build.owner.tag : build.owner;
+    const publicText = build.isPublic ? ' • Public' : '';
+    return `${build.id}${publicText} • Owned by ${ownerText}`;

Also applies to: 18-18, 26-31

src/embeds/ArbitrationEmbed.js (1)

17-28: LGTM! The migration to discord.js v14 setter methods is correct.

The changes properly migrate from direct property assignments to EmbedBuilder's setter methods while maintaining the same functionality.

Consider using nullish coalescing operator (??) for the field values to make the fallback more explicit:

     this.addFields([
       {
-        name: arbitration.node || '???',
-        value: arbitration.type || '???',
+        name: arbitration.node ?? '???',
+        value: arbitration.type ?? '???',
       },
     ]);
src/embeds/EarthCycleEmbed.js (1)

13-22: LGTM! The migration to discord.js v14 setter methods is correct.

The changes properly migrate from direct property assignments to EmbedBuilder's setter methods while maintaining the same functionality.

Consider using template literals consistently for the description to improve readability:

-    this.setDescription(
-      i18n`Time remaining until ${state.isDay ? 'Night' : 'Day'}: ${rTime(state.expiry)}` +
-        (state.bountyExpiry ? i18n`\nBounties expire in ${bountyExpiry}` : '')
-    );
+    const timeRemaining = i18n`Time remaining until ${state.isDay ? 'Night' : 'Day'}: ${rTime(state.expiry)}`;
+    const bountyInfo = state.bountyExpiry ? i18n`\nBounties expire in ${bountyExpiry}` : '';
+    this.setDescription(`${timeRemaining}${bountyInfo}`);
src/embeds/ModEmbed.js (1)

27-31: Use optional chaining to prevent potential runtime errors.

The levelStats property access could throw if modData.levelStats is undefined.

Apply this diff to use optional chaining:

-    const statsLength = modData.levelStats && modData.levelStats.length;
+    const statsLength = modData.levelStats?.length;
🧰 Tools
🪛 Biome (1.9.4)

[error] 27-27: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/embeds/CambionEmbed.js (1)

17-19: Add null check to prevent potential runtime errors.

The code accesses job.rewardPool[0] without checking if rewardPool exists.

Apply this diff to add a null check:

-      if (job.rewardPool[0] && !job.rewardPool[0].startsWith('Pattern Mismatch.')) {
+      if (job.rewardPool?.length && !job.rewardPool[0].startsWith('Pattern Mismatch.')) {
src/embeds/AcolyteEmbed.js (1)

36-38: Extract repeated string literal to a constant.

The string literal \u200B is used multiple times. Consider extracting it to a constant for better maintainability.

Apply this diff at the top of the file:

 const acolyteThumb = `${assetBase}/img/acolyte.png`;
+const ZERO_WIDTH_SPACE = '\u200B';

Then update the field names:

-        { name: '\u200B', value: `**${e.isDiscovered ? '' : 'Last '}Discovered At:** ${e.lastDiscoveredAt}` },
-        { name: '\u200B', value: `**Health Remaining:** ${(100 * Number(e.healthPercent)).toFixed(2)}%` },
-        { name: '\u200B', value: `Will flee after ${e.fleeDamage} damage.\nGet after the Acolyte, Tenno!` },
+        { name: ZERO_WIDTH_SPACE, value: `**${e.isDiscovered ? '' : 'Last '}Discovered At:** ${e.lastDiscoveredAt}` },
+        { name: ZERO_WIDTH_SPACE, value: `**Health Remaining:** ${(100 * Number(e.healthPercent)).toFixed(2)}%` },
+        { name: ZERO_WIDTH_SPACE, value: `Will flee after ${e.fleeDamage} damage.\nGet after the Acolyte, Tenno!` },
src/embeds/LFGEmbed.js (1)

3-4: Consider adding fallback for invalid color values.

The Number.parseInt could return NaN if the env var contains an invalid hex value.

-const expiredC = process.env.LFG_EXPIRED_COLOR ? Number.parseInt(process.env.LFG_EXPIRED_COLOR, 16) : 0xff0000;
-const activeC = process.env.LFG_ACTIVE_COLOR ? Number.parseInt(process.env.LFG_ACTIVE_COLOR, 16) : 0x9370db;
+const parseColor = (envVar, defaultColor) => {
+  const parsed = envVar ? Number.parseInt(envVar, 16) : defaultColor;
+  return Number.isNaN(parsed) ? defaultColor : parsed;
+};
+const expiredC = parseColor(process.env.LFG_EXPIRED_COLOR, 0xff0000);
+const activeC = parseColor(process.env.LFG_ACTIVE_COLOR, 0x9370db);
src/embeds/RSSEmbed.js (1)

67-77: Add URL validation for image sources.

The image URL processing could be safer with proper validation.

if (!Object.keys(feedItem.image).length) {
  let first = ((feedItem.description || '').match(/<img.*src="(.*)".*>/i) || [])[1];
  if (first) {
+   try {
+     const url = new URL(first.startsWith('//') ? `https:${first}` : first);
+     if (['http:', 'https:'].includes(url.protocol)) {
+       this.setImage(url.href);
+     }
+   } catch (e) {
+     logger.debug(`Invalid image URL: ${first}`);
+   }
-   if (first.startsWith('//')) {
-     first = first.replace('//', 'https://');
-     this.setImage(first);
-   }
  } else if (feed.defaultAttach) {
-   this.setImage(feed.defaultAttach);
+   try {
+     const url = new URL(feed.defaultAttach);
+     if (['http:', 'https:'].includes(url.protocol)) {
+       this.setImage(url.href);
+     }
+   } catch (e) {
+     logger.debug(`Invalid default attachment URL: ${feed.defaultAttach}`);
+   }
  }
}
src/embeds/AlertEmbed.js (2)

40-40: Consider removing redundant empty fields initialization.

The setFields([]) call is unnecessary since fields will be added immediately after using addFields.

-      this.setFields([]);

57-57: Use safer property access for title check.

The condition this.data.title.indexOf('Cr') could throw if title is undefined. Consider using optional chaining.

-      if (this.data.title.indexOf('Cr') === -1) {
+      if (this.data.title?.indexOf('Cr') === -1) {
src/embeds/RivenStatEmbed.js (1)

12-12: Consider removing redundant empty fields initialization.

The setFields([]) call is unnecessary since fields will be added immediately after using addFields.

-    this.setFields([]);
src/embeds/FrameEmbed.js (2)

96-96: Improve field filtering with optional chaining.

The field filtering logic can be improved using optional chaining as suggested by static analysis.

-      this.setFields(this.data.fields.filter((field) => field && field?.value?.length));
+      this.setFields(this.data.fields.filter((field) => field?.value?.length));
🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


93-95: Consider using spread operator with setFields instead of addFields.

Instead of using addFields with spread operator, consider using setFields directly with the mapped array.

-      this.addFields(
-        ...(frame?.abilities?.map((ability) => ({ name: ability.name, value: `_${ability.description}_` })) || [])
-      );
+      this.setFields(
+        frame?.abilities?.map((ability) => ({ name: ability.name, value: `_${ability.description}_` })) || []
+      );
src/embeds/SyndicateEmbed.js (1)

71-77: Optimize title setting logic.

The title is set twice in the conditional flow, where the second setting completely overrides the first one. Consider removing the redundant title setting.

-        this.setTitle(i18n`[${platform.toUpperCase()}] Syndicates`);
         this.setColor(0x00ff00);
         if (syndMissions.length < 2) {
           this.setTitle(`[${platform.toUpperCase()}] ${syndMissions[0].syndicate}`);
           this.setFooter({ text: i18n`Expires in ${syndMissions[0].eta}` });
           this.setTimestamp(syndMissions[0].expiry);
         }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bdfa009 and 8fd4d65.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (92)
  • package.json (1 hunks)
  • src/bot.js (4 hunks)
  • src/embeds/AcolyteEmbed.js (1 hunks)
  • src/embeds/AlertEmbed.js (1 hunks)
  • src/embeds/ArbitrationEmbed.js (1 hunks)
  • src/embeds/BaseEmbed.js (2 hunks)
  • src/embeds/BuildEmbed.js (1 hunks)
  • src/embeds/CambionEmbed.js (1 hunks)
  • src/embeds/CompanionEmbed.js (2 hunks)
  • src/embeds/ComponentEmbed.js (1 hunks)
  • src/embeds/ConclaveChallengeEmbed.js (1 hunks)
  • src/embeds/ConstructionEmbed.js (1 hunks)
  • src/embeds/DarvoEmbed.js (1 hunks)
  • src/embeds/DropsEmbed.js (2 hunks)
  • src/embeds/EarthCycleEmbed.js (1 hunks)
  • src/embeds/EnemyEmbed.js (3 hunks)
  • src/embeds/EnhancementEmbed.js (2 hunks)
  • src/embeds/ErrorEmbed.js (1 hunks)
  • src/embeds/EventEmbed.js (2 hunks)
  • src/embeds/FissureEmbed.js (1 hunks)
  • src/embeds/FrameEmbed.js (2 hunks)
  • src/embeds/InvasionEmbed.js (1 hunks)
  • src/embeds/KuvaEmbed.js (1 hunks)
  • src/embeds/LFGEmbed.js (1 hunks)
  • src/embeds/LogEmbed.js (1 hunks)
  • src/embeds/ModEmbed.js (2 hunks)
  • src/embeds/NewsEmbed.js (2 hunks)
  • src/embeds/NightwaveEmbed.js (1 hunks)
  • src/embeds/PatchnotesEmbed.js (2 hunks)
  • src/embeds/RSSEmbed.js (1 hunks)
  • src/embeds/RaidEmbed.js (2 hunks)
  • src/embeds/RivenStatEmbed.js (1 hunks)
  • src/embeds/SalesEmbed.js (1 hunks)
  • src/embeds/ServerInfoEmbed.js (2 hunks)
  • src/embeds/SettingsEmbed.js (1 hunks)
  • src/embeds/ShieldEmbed.js (1 hunks)
  • src/embeds/SimarisEmbed.js (1 hunks)
  • src/embeds/SolarisEmbed.js (1 hunks)
  • src/embeds/SortieEmbed.js (1 hunks)
  • src/embeds/SteelPathEmbed.js (2 hunks)
  • src/embeds/SyndicateEmbed.js (2 hunks)
  • src/embeds/SynthesisTargetEmbed.js (1 hunks)
  • src/embeds/TweetEmbed.js (1 hunks)
  • src/embeds/TwitchEmbed.js (1 hunks)
  • src/embeds/VoidTraderEmbed.js (1 hunks)
  • src/embeds/WeaponEmbed.js (3 hunks)
  • src/embeds/WhatsinEmbed.js (1 hunks)
  • src/embeds/WhereisEmbed.js (1 hunks)
  • src/eventHandlers/AddChannelToDatabase.js (2 hunks)
  • src/eventHandlers/AddGuildToDatabase.js (3 hunks)
  • src/eventHandlers/AssignDefaultRoles.js (2 hunks)
  • src/eventHandlers/BulkMessageDeleteHandle.js (3 hunks)
  • src/eventHandlers/DeleteChannel.js (3 hunks)
  • src/eventHandlers/DeleteGuild.js (2 hunks)
  • src/eventHandlers/DynamicVoiceHandler.js (2 hunks)
  • src/eventHandlers/InteractionHandler.js (8 hunks)
  • src/eventHandlers/JoinNotify.js (1 hunks)
  • src/eventHandlers/LeaveNotify.js (1 hunks)
  • src/eventHandlers/LogMemberBan.js (3 hunks)
  • src/eventHandlers/LogMemberRemove.js (3 hunks)
  • src/eventHandlers/LogMemberUnban.js (3 hunks)
  • src/eventHandlers/MessageDeleteHandle.js (2 hunks)
  • src/eventHandlers/NotifyOwnerJoin.js (3 hunks)
  • src/eventHandlers/NotifyVulgarName.js (1 hunks)
  • src/eventHandlers/Ready.js (2 hunks)
  • src/eventHandlers/UpdateGuildStatistics.js (2 hunks)
  • src/eventHandlers/WelcomeHandler.js (1 hunks)
  • src/interactions/channels/Rooms.js (19 hunks)
  • src/interactions/channels/Templates.js (3 hunks)
  • src/interactions/core/About.js (2 hunks)
  • src/interactions/core/Ping.js (4 hunks)
  • src/interactions/core/Settings.js (14 hunks)
  • src/interactions/core/su.js (6 hunks)
  • src/interactions/custom/CustomCommands.js (3 hunks)
  • src/interactions/fun/8ball.js (2 hunks)
  • src/interactions/fun/Corgi.js (1 hunks)
  • src/interactions/fun/Hug.js (1 hunks)
  • src/interactions/fun/Joke.js (2 hunks)
  • src/interactions/tracking/Tracking.js (16 hunks)
  • src/interactions/warframe/Builds.js (10 hunks)
  • src/interactions/warframe/Calculator.js (3 hunks)
  • src/interactions/warframe/LFG.js (6 hunks)
  • src/interactions/warframe/Lookup.js (4 hunks)
  • src/interactions/warframe/PriceCheck.js (3 hunks)
  • src/interactions/warframe/WhatsIn.js (3 hunks)
  • src/interactions/warframe/WhereIs.js (3 hunks)
  • src/interactions/warframe/Worldstate.js (9 hunks)
  • src/models/Interaction.js (1 hunks)
  • src/notifications/Broadcaster.js (1 hunks)
  • src/utilities/Collectors.js (8 hunks)
  • src/utilities/CommonFunctions.js (8 hunks)
  • src/utilities/Webhook.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (39)
  • package.json
  • src/interactions/core/About.js
  • src/eventHandlers/LeaveNotify.js
  • src/eventHandlers/DeleteChannel.js
  • src/interactions/fun/Corgi.js
  • src/interactions/fun/Hug.js
  • src/eventHandlers/DeleteGuild.js
  • src/eventHandlers/JoinNotify.js
  • src/eventHandlers/Ready.js
  • src/eventHandlers/WelcomeHandler.js
  • src/interactions/fun/Joke.js
  • src/eventHandlers/MessageDeleteHandle.js
  • src/interactions/warframe/WhatsIn.js
  • src/notifications/Broadcaster.js
  • src/eventHandlers/NotifyVulgarName.js
  • src/eventHandlers/LogMemberUnban.js
  • src/interactions/warframe/Calculator.js
  • src/eventHandlers/BulkMessageDeleteHandle.js
  • src/interactions/warframe/Worldstate.js
  • src/interactions/fun/8ball.js
  • src/eventHandlers/UpdateGuildStatistics.js
  • src/eventHandlers/AddGuildToDatabase.js
  • src/interactions/core/Ping.js
  • src/models/Interaction.js
  • src/eventHandlers/AddChannelToDatabase.js
  • src/eventHandlers/LogMemberBan.js
  • src/eventHandlers/NotifyOwnerJoin.js
  • src/interactions/warframe/WhereIs.js
  • src/interactions/warframe/Lookup.js
  • src/eventHandlers/LogMemberRemove.js
  • src/eventHandlers/AssignDefaultRoles.js
  • src/interactions/channels/Templates.js
  • src/interactions/core/su.js
  • src/eventHandlers/InteractionHandler.js
  • src/interactions/warframe/PriceCheck.js
  • src/eventHandlers/DynamicVoiceHandler.js
  • src/utilities/Webhook.js
  • src/embeds/BaseEmbed.js
  • src/interactions/channels/Rooms.js
🧰 Additional context used
🪛 Biome (1.9.4)
src/embeds/ModEmbed.js

[error] 27-27: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/embeds/FrameEmbed.js

[error] 96-96: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/interactions/warframe/Builds.js

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 524-530: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/interactions/core/Settings.js

[error] 518-519: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 537-537: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (78)
src/embeds/ConstructionEmbed.js (2)

7-7: LGTM! Proper migration to discord.js v14 builder pattern.

The change from direct property assignment to using setColor() aligns with discord.js v14's builder pattern.


8-15: LGTM! Proper migration to discord.js v14 builder pattern.

The change from direct property assignment to using setFields() aligns with discord.js v14's builder pattern. The field structure remains correct and maintains the same functionality.

src/embeds/ErrorEmbed.js (1)

12-14: LGTM! Correctly updated to discord.js v14 setter methods.

The changes properly transition from direct property assignments to the new setter methods required by discord.js v14's EmbedBuilder pattern.

src/embeds/PatchnotesEmbed.js (3)

13-14: LGTM! Good use of builder methods.

The changes properly adopt discord.js v14's builder pattern, which provides better type safety and method chaining capabilities.


15-32: LGTM! Good separation of concerns.

The change improves code readability by clearly separating field generation from field assignment. The mapping logic remains well-structured and maintains proper internationalization.


33-33: LGTM! Proper use of setFields method.

The change correctly uses discord.js v14's setFields method, maintaining consistency with the builder pattern throughout the class.

src/embeds/CompanionEmbed.js (2)

17-29: LGTM! Field addition syntax updated correctly for discord.js v14.

The changes correctly implement the new .addFields() syntax which now accepts an array of field objects instead of variable arguments.


13-16: LGTM! Embed construction follows discord.js v14 patterns.

The embed construction correctly uses the setter methods and chaining pattern supported by discord.js v14's EmbedBuilder.

src/embeds/ConclaveChallengeEmbed.js (4)

16-16: LGTM! Proper migration to discord.js v14 method.

The change from direct property assignment to using setColor() aligns with discord.js v14's builder pattern.


18-25: LGTM! Proper migration to discord.js v14 method.

The change from direct fields assignment to using setFields() maintains the same functionality while adopting discord.js v14's builder pattern.


27-32: LGTM! Proper migration to discord.js v14 method.

The change from direct fields assignment to using setFields() for the error case maintains the same functionality while adopting discord.js v14's builder pattern.


34-37: LGTM! Proper migration to discord.js v14 method.

The changes from direct property assignments to using setTitle() and setThumbnail() maintain the same functionality while adopting discord.js v14's builder pattern.

src/embeds/WhereisEmbed.js (1)

24-24: LGTM! Good use of EmbedBuilder methods.

The changes correctly implement discord.js v14's EmbedBuilder methods for managing embed content. The logic for handling result groups is maintained while adopting the new API.

Also applies to: 26-26

src/embeds/FissureEmbed.js (1)

25-57: LGTM! Property assignments updated for discord.js v14.

The changes correctly migrate from direct property assignments to using the data object, which is the recommended approach in discord.js v14's EmbedBuilder API. The functionality remains unchanged while adopting the new API structure.

src/embeds/SteelPathEmbed.js (1)

21-25: LGTM! Property setters follow discord.js v14 patterns.

The migration to builder-style setters (setFooter, setTimestamp, setTitle, setThumbnail, setColor) aligns with discord.js v14's EmbedBuilder pattern. The functionality is preserved while improving the code structure.

src/embeds/KuvaEmbed.js (1)

20-23: Successfully migrated to discord.js v14 setter methods!

The changes properly implement the new EmbedBuilder setter methods, improving type safety and maintainability.

Also applies to: 24-30, 32-33

src/embeds/NightwaveEmbed.js (6)

22-24: LGTM! Correctly implements discord.js v14 setter methods.

The changes properly migrate from direct property assignments to the new EmbedBuilder setter methods.


41-51: LGTM! Correctly implements discord.js v14 setter methods while preserving logic.

The changes properly migrate to the new EmbedBuilder API while maintaining the existing daily challenges filtering and formatting logic.


58-64: LGTM! Correctly implements discord.js v14 setter methods while preserving logic.

The changes properly migrate to the new EmbedBuilder API while maintaining the existing weekly challenges filtering and formatting logic.


71-77: LGTM! Correctly implements discord.js v14 setter methods while preserving logic.

The changes properly migrate to the new EmbedBuilder API while maintaining the existing elite weekly challenges filtering and formatting logic.


80-83: LGTM! Correctly implements discord.js v14 setter methods while preserving logic.

The changes properly migrate to the new EmbedBuilder API while maintaining the existing footer and timestamp logic.


86-93: LGTM! Correctly implements discord.js v14 setter methods while preserving logic.

The changes properly migrate to the new EmbedBuilder API while maintaining the existing single challenge handling logic.

src/embeds/VoidTraderEmbed.js (5)

13-13: LGTM! Color setting updated to use builder pattern.

The change correctly updates the color assignment to use the setColor() method while preserving the existing conditional logic.


16-26: LGTM! Fields setting updated to use builder pattern.

The change correctly updates the fields assignment to use the setFields() method while preserving the existing inventory mapping logic and field structure.


28-28: LGTM! Empty fields setting updated to use builder pattern.

The change correctly updates the empty fields assignment to use the setFields() method.


30-35: LGTM! Additional fields setting updated to use builder pattern.

The change correctly updates the time-related field addition to use the addFields() method while preserving the existing i18n translations and field structure.


36-37: LGTM! Title and thumbnail setting updated to use builder pattern.

The changes correctly update the title and thumbnail assignments to use their respective setter methods while preserving the existing content.

src/embeds/TwitchEmbed.js (3)

6-7: LGTM! Proper usage of setter methods.

The changes correctly implement the discord.js v14 pattern of using setter methods instead of direct property assignment.


18-21: LGTM! Proper implementation of author data.

The changes correctly implement the discord.js v14 pattern for setting author information with proper null checks.


23-23: LGTM! Proper usage of setDescription.

The change correctly implements the discord.js v14 pattern for setting the description.

src/embeds/SalesEmbed.js (1)

15-22:

❓ Verification inconclusive

LGTM! Correctly implements discord.js v14 setter methods.

The changes properly transition from direct property assignments to the new setter methods required by discord.js v14's EmbedBuilder, while preserving all the existing business logic.

Let's confirm the color value matches the previous version:


🏁 Script executed:

#!/bin/bash
# Search for previous color value in git history
git log -S "color" --patch -- src/embeds/SalesEmbed.js | grep -B 5 -A 5 "color.*0x0000ff"

Length of output: 0


Review Finalization for SalesEmbed.js Setter Methods and Color Value

LGTM! The changes correctly implement the discord.js v14 upgrade by transitioning from direct property assignments to the required setter methods (setColor, setTitle, setThumbnail, setFields), and all business logic is preserved. However, the automated git history search for the color value (0x0000ff) returned no results. This might indicate that the historical usage of the color value isn’t readily available or that it never changed. Please manually verify that the color (0x0000ff) is consistent with what was previously used, to ensure no unintended side effects.

  • Action required: Manually confirm the consistency of the color value (0x0000ff) with the previous implementation if applicable.
src/interactions/tracking/Tracking.js (1)

1-12: LGTM! Well-structured imports.

The imports are properly organized using named imports, which is optimal for tree-shaking and follows discord.js v14 best practices.

src/embeds/DarvoEmbed.js (1)

11-20: LGTM! Clean transition to discord.js v14 API.

The changes correctly replace direct property assignments with setter methods while maintaining the same functionality. The code is well-structured and follows best practices.

src/embeds/ComponentEmbed.js (1)

6-21: LGTM! Clean transition to discord.js v14 API.

The changes correctly replace direct property assignments with setter methods while maintaining the same functionality. The code is well-structured and follows best practices.

src/embeds/SynthesisTargetEmbed.js (1)

11-24: LGTM! The migration to discord.js v14 setter methods is correct.

The changes properly migrate from direct property assignments to EmbedBuilder's setter methods while maintaining the same functionality. The conditional logic for handling single vs multiple targets is preserved.

src/embeds/DropsEmbed.js (2)

9-9: LGTM! Using setter method instead of direct property assignment.

The change from direct property assignment to setDescription() aligns with discord.js v14's preferred approach.


26-32: LGTM! Using setter method instead of direct property assignment.

The change from direct property assignment to setFields() aligns with discord.js v14's preferred approach.

src/embeds/EnhancementEmbed.js (2)

16-21: LGTM! Using setter methods instead of direct property assignments.

The changes align with discord.js v14's preferred approach.


22-38: LGTM! Using setter method instead of direct property assignment.

The change from direct property assignment to setFields() aligns with discord.js v14's preferred approach.

src/embeds/SortieEmbed.js (2)

12-12: LGTM! Using setter methods instead of direct property assignments.

The changes from direct property assignments to setColor() and setFields() align with discord.js v14's preferred approach.

Also applies to: 13-24


26-28: LGTM! Using setter methods instead of direct property assignments.

The changes from direct property assignments to setDescription(), setTitle(), setThumbnail(), and setFooter() align with discord.js v14's preferred approach.

Also applies to: 30-32, 34-34

src/embeds/TweetEmbed.js (4)

6-9: LGTM! Using setter methods instead of direct property assignments.

The changes from direct property assignments to setColor(), setDescription(), setTimestamp(), and setURL() align with discord.js v14's preferred approach.


12-12: LGTM! Using setter method instead of direct property assignment.

The change from direct property assignment to setImage() aligns with discord.js v14's preferred approach.


16-32: LGTM! Using setter methods instead of direct property assignments.

The changes from direct property assignments to setTitle(), setDescription(), and addFields() align with discord.js v14's preferred approach.


34-43: LGTM! Using setter methods instead of direct property assignments.

The changes from direct property assignments to setFooter() and setAuthor() align with discord.js v14's preferred approach.

src/embeds/ShieldEmbed.js (1)

18-21: LGTM! The changes align with discord.js v14's EmbedBuilder API.

The refactoring to use setter methods (setColor, setTitle, setURL, setThumbnail, setFields) instead of direct property assignments follows the recommended patterns in discord.js v14's EmbedBuilder API. The logic remains unchanged while improving maintainability.

Also applies to: 23-26, 32-33, 35-36, 39-39

src/embeds/EnemyEmbed.js (1)

9-11: LGTM! The changes align with discord.js v14's EmbedBuilder API.

The refactoring to use setter methods (setTitle, setColor, setDescription, setFields, addFields) instead of direct property assignments follows the recommended patterns in discord.js v14's EmbedBuilder API. The logic remains unchanged while improving maintainability.

Also applies to: 15-17, 52-52

src/embeds/WhatsinEmbed.js (1)

42-44: LGTM! The changes align with discord.js v14's EmbedBuilder API.

The refactoring to use setter methods (setTitle, setColor, setDescription) instead of direct property assignments follows the recommended patterns in discord.js v14's EmbedBuilder API. The logic remains unchanged while improving maintainability.

src/embeds/InvasionEmbed.js (2)

21-22: LGTM! Correctly migrated to use setter methods.

The migration from direct property assignments to setter methods is implemented correctly, maintaining the same functionality while aligning with discord.js v14's EmbedBuilder pattern.

Also applies to: 37-38, 46-50, 52-52


26-36: Consider adding null checks for rewards.

The rewards string concatenation could throw if i.attacker.reward is undefined.

Add null checks:

-          let rewards = i.defender.reward.asString;
+          let rewards = i.defender?.reward?.asString || '';
           if (!i.vsInfestation) {
-            rewards = i18n`${i.attacker.reward.asString} vs ${rewards}`;
+            rewards = i18n`${i.attacker?.reward?.asString || ''} vs ${rewards}`;
           }
src/embeds/LFGEmbed.js (1)

27-58: LGTM! Clean migration to setter methods.

The transition to setter methods is implemented correctly, maintaining the same functionality while improving code structure.

src/embeds/ServerInfoEmbed.js (1)

36-81: LGTM! Clean migration to setter methods.

The transition to setter methods is implemented correctly, improving code structure.

src/embeds/RSSEmbed.js (1)

48-65: LGTM! Clean migration to setter methods.

The transition to setter methods is implemented correctly, improving code structure.

Also applies to: 79-79

src/embeds/EventEmbed.js (1)

18-20: LGTM! Property assignments correctly updated to use setter methods.

The changes properly implement discord.js v14's preferred method of setting embed properties using setter methods instead of direct property assignments.

src/interactions/custom/CustomCommands.js (1)

1-1: LGTM! Discord.js v14 APIs correctly implemented.

The changes properly implement:

  • Direct imports of specific components
  • Updated permission flags using PermissionsBitField
  • Updated command option types using ApplicationCommandOptionType

Also applies to: 15-15, 19-19, 23-23, 28-28, 35-35, 39-39, 46-46

src/bot.js (2)

1-1: LGTM! Discord.js v14 APIs correctly implemented.

The changes properly implement:

  • Direct imports of specific components
  • Updated presence status using PresenceUpdateStatus enum
  • Updated intents using GatewayIntentBits

Also applies to: 55-55, 64-68


144-171: LGTM! Event names correctly updated to camelCase format.

All event names have been properly updated from uppercase to camelCase format as required by discord.js v14.

src/embeds/WeaponEmbed.js (2)

28-33: LGTM! Property assignments correctly updated to use setter methods.

The changes properly implement discord.js v14's preferred method of setting embed properties using setter methods instead of direct property assignments.


35-70: LGTM! Field additions correctly updated to use addFields method.

The changes properly implement discord.js v14's preferred method of adding fields using the addFields method instead of direct array manipulation.

Also applies to: 72-78, 126-132, 136-142, 146-152, 155-161, 165-171, 174-180, 183-189, 192-198, 201-207, 210-216

🧰 Tools
🪛 Biome (1.9.4)

[error] 67-68: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/interactions/warframe/LFG.js (5)

1-9: LGTM! Import statements are now more specific.

The changes correctly import specific components from discord.js instead of importing the entire Discord object, which is more efficient and clearer.


115-165: LGTM! Command option types updated correctly.

The changes properly update the command option types to use the new ApplicationCommandOptionType enums from discord.js v14.


206-223: LGTM! Button components updated correctly.

The changes properly update the button components to use the new ButtonBuilder and ButtonStyle enums from discord.js v14.


234-237: LGTM! Interaction collector configuration updated correctly.

The changes properly update the interaction collector to use the new InteractionType and ComponentType enums from discord.js v14.


202-204: LGTM! Error handling updated correctly.

The changes properly update the error handling to use flags instead of ephemeral in the reply options.

src/utilities/Collectors.js (3)

1-11: LGTM! Import statements are now more specific.

The changes correctly import specific components from discord.js instead of importing the entire Discord object.


13-33: LGTM! Navigation components updated correctly.

The changes properly update the navigation components to use the new builders and styles from discord.js v14.


34-49: LGTM! Confirmation components updated correctly.

The changes properly update the confirmation components to use the new builders and styles from discord.js v14.

src/interactions/core/Settings.js (2)

1-1: LGTM! Import statements are now more specific.

The changes correctly import specific components from discord.js instead of importing the entire Discord object.


518-519: Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'diag':
+       {
        const embed = new EmbedBuilder();
        embed.setTitle(`Diagnostics for Shard ${interaction.guild.shardId + 1}/${interaction.client.ws.shards.size}`);
+       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 518-519: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/interactions/warframe/Builds.js (3)

1-11: LGTM! Import statements are now more specific.

The changes correctly import specific components from discord.js instead of importing the entire Discord object.


440-458: Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'mod':
+       {
        const navComponents = new ActionRowBuilder({
          components: [
            new ButtonBuilder({
              label: 'Previous',
              customId: 'previous',
              style: ButtonStyle.Secondary,
            }),
            new ButtonBuilder({
              label: 'Save',
              customId: 'save',
              style: ButtonStyle.Primary,
            }),
            new ButtonBuilder({
              label: 'Next',
              customId: 'next',
              style: ButtonStyle.Secondary,
            }),
          ],
        });
+       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


524-530: Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'mod':
+       {
        const modPageCollector = new InteractionCollector(interaction.client, {
          interactionType: InteractionType.MessageComponent,
          componentType: ComponentType.Button,
          message,
          guild: interaction.guild,
          channel: interaction.channel,
        });
+       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 524-530: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/utilities/CommonFunctions.js (4)

1-1: LGTM! Import statement updated for discord.js v14.

The change to use specific imports from discord.js is aligned with v14's modular import system and enables better tree-shaking.


483-483: Verify all MessageEmbed references are updated.

The parameter and return types have been correctly updated from MessageEmbed to EmbedBuilder for discord.js v14 compatibility.

Let's verify that all callers have been updated:

#!/bin/bash
# Description: Search for any remaining MessageEmbed usages that need to be updated

# Search for MessageEmbed in imports and type definitions
rg -i "MessageEmbed"

# Search for potential message.embed usages that might need updating
rg "\.embed\b"

Also applies to: 562-562, 581-581


533-533: LGTM! Embed handling updated for EmbedBuilder API.

The changes correctly implement the new EmbedBuilder API from discord.js v14, including proper type checking and data access patterns.

Also applies to: 599-601, 606-608


584-584: LGTM! Embed creation updated to use EmbedBuilder.

All embed creation instances have been consistently updated to use the new EmbedBuilder class from discord.js v14.

Also applies to: 603-603, 674-674, 706-706

src/embeds/SyndicateEmbed.js (2)

51-59: LGTM! Property initialization follows discord.js v14 patterns.

The changes correctly implement the builder pattern using setter methods instead of direct property assignments, which is the recommended approach in discord.js v14.


47-105:

✅ Verification successful

Verify discord.js v14 compatibility.

Let's verify the compatibility with the latest discord.js v14 version and check for any breaking changes in the Embed API.


🌐 Web query:

What is the latest version of discord.js v14 and are there any breaking changes in the Embed API compared to v13?

💡 Result:

The latest version of discord.js v14 is 14.18.0 as of February 2025[7][9]. The library requires Node.js 22.12.0 or newer[9].

Breaking Changes in Embed API (v13 → v14)

Here are key changes affecting embeds:

v13 Feature v14 Equivalent Details
MessageEmbed EmbedBuilder Class renamed for consistency with builder patterns[4][5]
addField() addFields() Now accepts an array of field objects instead of individual parameters[4][10]
setAuthor(name, iconURL) setAuthor({name, iconURL}) Requires passing an object parameter instead of separate arguments[4][5][10]
setFooter(text, iconURL) setFooter({text, iconURL}) Object parameter required[4][10]
Direct embed mutation Immutable via EmbedBuilder.from() Received embeds must be cloned using EmbedBuilder.from() for modifications[2][4][10]
Field inline formatting Requires consecutive inline fields At least two consecutive fields with inline: true for side-by-side display[2][8]

Additional notable changes:

  • Embeds now validate required properties like author names and thumbnail URLs[8]
  • Masked links (e.g., [Guide](url)) only work in descriptions/field values[2]
  • Mentions in embeds don't trigger notifications[2]

Example migration snippet:

// v13
new MessageEmbed()
  .addField('Field 1', 'Value 1', true)
  .addField('Field 2', 'Value 2', true);

// v14
new EmbedBuilder()
  .addFields([
    { name: 'Field 1', value: 'Value 1', inline: true },
    { name: 'Field 2', value: 'Value 2', inline: true }
  ]);

The changes aim to improve type safety and align with Discord API v10 requirements while maintaining functionality[4][7]. Developers should update Node.js first and remove deprecated packages like @discordjs/builders before migrating[4][6].

Citations:


Discord.js v14 Compatibility Confirmed

The SyndicateEmbed implementation now adheres to the updated Discord.js Embed API patterns. In particular:

• Object syntax is correctly used for embed elements (e.g., setFooter({ text: ... })), aligning with v14 requirements.
• Methods such as setFields and setColor are used consistently, matching the updated builder approach.
• Ensure that the underlying BaseEmbed properly wraps or extends EmbedBuilder from discord.js v14 and that your environment meets the Node.js version requirements (>= 22.12.0).

No further modifications are needed regarding Discord.js v14 embed compatibility.

@SlayerOrnstein SlayerOrnstein force-pushed the feat-discord-api-migration branch from 07cae0c to 237b550 Compare March 26, 2025 11:43
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/interactions/warframe/Builds.js (2)

440-458: ⚠️ Potential issue

Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'mod':
+       {
        const navComponents = new ActionRowBuilder({
          components: [
            new ButtonBuilder({
              label: 'Previous',
              customId: 'previous',
              style: ButtonStyle.Secondary,
            }),
            new ButtonBuilder({
              label: 'Save',
              customId: 'save',
              style: ButtonStyle.Primary,
            }),
            new ButtonBuilder({
              label: 'Next',
              customId: 'next',
              style: ButtonStyle.Secondary,
            }),
          ],
        });
+       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


524-530: ⚠️ Potential issue

Fix variable declaration in switch statement.

The variable declaration in the switch statement can be erroneously accessed by other cases. This could lead to unexpected behavior.

Apply this diff to fix the issue:

      case 'mod':
+       {
        const modPageCollector = new InteractionCollector(interaction.client, {
          interactionType: InteractionType.MessageComponent,
          componentType: ComponentType.Button,
          message,
          guild: interaction.guild,
          channel: interaction.channel,
        });
+       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 524-530: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🧹 Nitpick comments (3)
src/embeds/ModEmbed.js (1)

27-28: Consider using optional chaining

The static analysis tool correctly suggests using optional chaining for the conditional check on modData.levelStats.

- const statsLength = modData.levelStats && modData.levelStats.length;
+ const statsLength = modData.levelStats?.length;
🧰 Tools
🪛 Biome (1.9.4)

[error] 27-27: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/embeds/FrameEmbed.js (1)

93-96: Properly implemented addFields and field filtering

The code now correctly uses addFields to append additional field entries and properly filters fields before setting them. However, there's an optional chaining opportunity in the filter method.

- this.setFields(this.data.fields.filter((field) => field && field?.value?.length));
+ this.setFields(this.data.fields.filter((field) => field && field.value?.length));

The current code mixes traditional null checking (field &&) with optional chaining (field?.value), which is inconsistent. Either use optional chaining throughout or traditional checks.

🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/interactions/core/Settings.js (1)

546-546: Check manage webhooks
Same note: using this statically can be replaced with direct references to the class if desired.

🧰 Tools
🪛 Biome (1.9.4)

[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07cae0c and 237b550.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (92)
  • package.json (1 hunks)
  • src/bot.js (4 hunks)
  • src/embeds/AcolyteEmbed.js (1 hunks)
  • src/embeds/AlertEmbed.js (1 hunks)
  • src/embeds/ArbitrationEmbed.js (1 hunks)
  • src/embeds/BaseEmbed.js (2 hunks)
  • src/embeds/BuildEmbed.js (1 hunks)
  • src/embeds/CambionEmbed.js (1 hunks)
  • src/embeds/CompanionEmbed.js (2 hunks)
  • src/embeds/ComponentEmbed.js (1 hunks)
  • src/embeds/ConclaveChallengeEmbed.js (1 hunks)
  • src/embeds/ConstructionEmbed.js (1 hunks)
  • src/embeds/DarvoEmbed.js (1 hunks)
  • src/embeds/DropsEmbed.js (2 hunks)
  • src/embeds/EarthCycleEmbed.js (1 hunks)
  • src/embeds/EnemyEmbed.js (3 hunks)
  • src/embeds/EnhancementEmbed.js (2 hunks)
  • src/embeds/ErrorEmbed.js (1 hunks)
  • src/embeds/EventEmbed.js (2 hunks)
  • src/embeds/FissureEmbed.js (1 hunks)
  • src/embeds/FrameEmbed.js (2 hunks)
  • src/embeds/InvasionEmbed.js (1 hunks)
  • src/embeds/KuvaEmbed.js (1 hunks)
  • src/embeds/LFGEmbed.js (1 hunks)
  • src/embeds/LogEmbed.js (1 hunks)
  • src/embeds/ModEmbed.js (2 hunks)
  • src/embeds/NewsEmbed.js (2 hunks)
  • src/embeds/NightwaveEmbed.js (1 hunks)
  • src/embeds/PatchnotesEmbed.js (2 hunks)
  • src/embeds/RSSEmbed.js (1 hunks)
  • src/embeds/RaidEmbed.js (2 hunks)
  • src/embeds/RivenStatEmbed.js (1 hunks)
  • src/embeds/SalesEmbed.js (1 hunks)
  • src/embeds/ServerInfoEmbed.js (2 hunks)
  • src/embeds/SettingsEmbed.js (2 hunks)
  • src/embeds/ShieldEmbed.js (1 hunks)
  • src/embeds/SimarisEmbed.js (1 hunks)
  • src/embeds/SolarisEmbed.js (1 hunks)
  • src/embeds/SortieEmbed.js (1 hunks)
  • src/embeds/SteelPathEmbed.js (2 hunks)
  • src/embeds/SyndicateEmbed.js (2 hunks)
  • src/embeds/SynthesisTargetEmbed.js (1 hunks)
  • src/embeds/TweetEmbed.js (1 hunks)
  • src/embeds/TwitchEmbed.js (1 hunks)
  • src/embeds/VoidTraderEmbed.js (1 hunks)
  • src/embeds/WeaponEmbed.js (3 hunks)
  • src/embeds/WhatsinEmbed.js (1 hunks)
  • src/embeds/WhereisEmbed.js (1 hunks)
  • src/eventHandlers/AddChannelToDatabase.js (2 hunks)
  • src/eventHandlers/AddGuildToDatabase.js (3 hunks)
  • src/eventHandlers/AssignDefaultRoles.js (2 hunks)
  • src/eventHandlers/BulkMessageDeleteHandle.js (3 hunks)
  • src/eventHandlers/DeleteChannel.js (3 hunks)
  • src/eventHandlers/DeleteGuild.js (2 hunks)
  • src/eventHandlers/DynamicVoiceHandler.js (2 hunks)
  • src/eventHandlers/InteractionHandler.js (8 hunks)
  • src/eventHandlers/JoinNotify.js (1 hunks)
  • src/eventHandlers/LeaveNotify.js (1 hunks)
  • src/eventHandlers/LogMemberBan.js (3 hunks)
  • src/eventHandlers/LogMemberRemove.js (3 hunks)
  • src/eventHandlers/LogMemberUnban.js (3 hunks)
  • src/eventHandlers/MessageDeleteHandle.js (2 hunks)
  • src/eventHandlers/NotifyOwnerJoin.js (3 hunks)
  • src/eventHandlers/NotifyVulgarName.js (1 hunks)
  • src/eventHandlers/Ready.js (2 hunks)
  • src/eventHandlers/UpdateGuildStatistics.js (2 hunks)
  • src/eventHandlers/WelcomeHandler.js (1 hunks)
  • src/interactions/channels/Rooms.js (19 hunks)
  • src/interactions/channels/Templates.js (3 hunks)
  • src/interactions/core/About.js (2 hunks)
  • src/interactions/core/Ping.js (4 hunks)
  • src/interactions/core/Settings.js (14 hunks)
  • src/interactions/core/su.js (6 hunks)
  • src/interactions/custom/CustomCommands.js (3 hunks)
  • src/interactions/fun/8ball.js (2 hunks)
  • src/interactions/fun/Corgi.js (1 hunks)
  • src/interactions/fun/Hug.js (1 hunks)
  • src/interactions/fun/Joke.js (2 hunks)
  • src/interactions/tracking/Tracking.js (16 hunks)
  • src/interactions/warframe/Builds.js (10 hunks)
  • src/interactions/warframe/Calculator.js (3 hunks)
  • src/interactions/warframe/LFG.js (6 hunks)
  • src/interactions/warframe/Lookup.js (4 hunks)
  • src/interactions/warframe/PriceCheck.js (3 hunks)
  • src/interactions/warframe/WhatsIn.js (3 hunks)
  • src/interactions/warframe/WhereIs.js (3 hunks)
  • src/interactions/warframe/Worldstate.js (9 hunks)
  • src/models/Interaction.js (1 hunks)
  • src/notifications/Broadcaster.js (1 hunks)
  • src/utilities/Collectors.js (8 hunks)
  • src/utilities/CommonFunctions.js (8 hunks)
  • src/utilities/Webhook.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (80)
  • src/eventHandlers/DeleteGuild.js
  • src/embeds/DropsEmbed.js
  • package.json
  • src/embeds/CompanionEmbed.js
  • src/interactions/fun/8ball.js
  • src/interactions/fun/Corgi.js
  • src/embeds/SalesEmbed.js
  • src/embeds/PatchnotesEmbed.js
  • src/embeds/InvasionEmbed.js
  • src/embeds/ArbitrationEmbed.js
  • src/eventHandlers/LeaveNotify.js
  • src/embeds/DarvoEmbed.js
  • src/embeds/ServerInfoEmbed.js
  • src/embeds/NightwaveEmbed.js
  • src/embeds/BuildEmbed.js
  • src/embeds/EarthCycleEmbed.js
  • src/interactions/warframe/WhatsIn.js
  • src/embeds/BaseEmbed.js
  • src/embeds/SimarisEmbed.js
  • src/embeds/SettingsEmbed.js
  • src/embeds/ErrorEmbed.js
  • src/notifications/Broadcaster.js
  • src/embeds/VoidTraderEmbed.js
  • src/embeds/RivenStatEmbed.js
  • src/embeds/EnhancementEmbed.js
  • src/eventHandlers/LogMemberUnban.js
  • src/embeds/SynthesisTargetEmbed.js
  • src/interactions/warframe/Worldstate.js
  • src/embeds/ComponentEmbed.js
  • src/embeds/TwitchEmbed.js
  • src/embeds/SortieEmbed.js
  • src/eventHandlers/Ready.js
  • src/embeds/SteelPathEmbed.js
  • src/eventHandlers/JoinNotify.js
  • src/interactions/fun/Hug.js
  • src/eventHandlers/BulkMessageDeleteHandle.js
  • src/interactions/fun/Joke.js
  • src/interactions/warframe/WhereIs.js
  • src/interactions/core/About.js
  • src/embeds/KuvaEmbed.js
  • src/embeds/LogEmbed.js
  • src/embeds/ConclaveChallengeEmbed.js
  • src/embeds/WhatsinEmbed.js
  • src/eventHandlers/NotifyOwnerJoin.js
  • src/eventHandlers/NotifyVulgarName.js
  • src/eventHandlers/MessageDeleteHandle.js
  • src/eventHandlers/DeleteChannel.js
  • src/interactions/core/Ping.js
  • src/embeds/RaidEmbed.js
  • src/eventHandlers/AddGuildToDatabase.js
  • src/embeds/TweetEmbed.js
  • src/embeds/EnemyEmbed.js
  • src/embeds/WhereisEmbed.js
  • src/embeds/NewsEmbed.js
  • src/eventHandlers/LogMemberRemove.js
  • src/embeds/WeaponEmbed.js
  • src/embeds/AlertEmbed.js
  • src/eventHandlers/AssignDefaultRoles.js
  • src/embeds/CambionEmbed.js
  • src/embeds/EventEmbed.js
  • src/interactions/warframe/Lookup.js
  • src/embeds/SolarisEmbed.js
  • src/embeds/FissureEmbed.js
  • src/embeds/SyndicateEmbed.js
  • src/embeds/ConstructionEmbed.js
  • src/embeds/AcolyteEmbed.js
  • src/eventHandlers/AddChannelToDatabase.js
  • src/eventHandlers/DynamicVoiceHandler.js
  • src/embeds/ShieldEmbed.js
  • src/models/Interaction.js
  • src/eventHandlers/LogMemberBan.js
  • src/interactions/warframe/PriceCheck.js
  • src/interactions/channels/Templates.js
  • src/embeds/LFGEmbed.js
  • src/embeds/RSSEmbed.js
  • src/interactions/warframe/Calculator.js
  • src/utilities/Webhook.js
  • src/interactions/warframe/LFG.js
  • src/eventHandlers/WelcomeHandler.js
  • src/eventHandlers/UpdateGuildStatistics.js
🧰 Additional context used
🧬 Code Definitions (4)
src/interactions/core/su.js (1)
src/interactions/core/Settings.js (1)
  • Settings (19-589)
src/interactions/custom/CustomCommands.js (1)
src/models/Interaction.js (1)
  • Interaction (1-28)
src/interactions/core/Settings.js (3)
src/resources/index.js (4)
  • localeMap (13-13)
  • localeMap (13-13)
  • platformMap (35-35)
  • platformMap (35-35)
src/interactions/core/su.js (1)
  • Settings (9-159)
src/utilities/CommonFunctions.js (3)
  • embedDefaults (387-394)
  • embedDefaults (387-394)
  • embed (584-584)
src/interactions/tracking/Tracking.js (3)
src/resources/index.js (2)
  • cmds (84-84)
  • cmds (84-84)
src/utilities/CommonFunctions.js (1)
  • chunks (586-586)
src/utilities/Webhook.js (1)
  • webhook (14-108)
🪛 Biome (1.9.4)
src/interactions/warframe/Builds.js

[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 524-530: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/interactions/core/Settings.js

[error] 518-519: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 537-537: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 546-546: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

src/embeds/FrameEmbed.js

[error] 96-96: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/embeds/ModEmbed.js

[error] 27-27: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (173)
src/embeds/ModEmbed.js (4)

18-19: Direct property assignments replaced with setter methods

The changes from direct property assignments to setter methods align with discord.js v14's EmbedBuilder API, which no longer supports direct property assignments. This is a correct implementation of the required changes.


23-23: Consistent use of setDescription

The setDescription calls properly replace the direct assignment of the description property, maintaining the same content formatting. This is correctly implemented.

Also applies to: 30-31


33-35: URL and image settings correctly implemented

The setURL and setImage methods correctly replace direct property assignments, matching the discord.js v14 API requirements.


36-67: Fields array properly converted to setFields method

The array of field objects is now correctly passed to setFields() instead of being directly assigned to the fields property. This follows the discord.js v14 EmbedBuilder pattern.

src/embeds/FrameEmbed.js (4)

18-28: Thumbnail, title, URL and color properties correctly updated

The changes to use setter methods instead of direct property assignments correctly implement the discord.js v14 EmbedBuilder pattern. All properties are set using their respective setter methods.


25-25: Footer format updated to use object parameter

The setFooter method now correctly accepts an object parameter with a text property, which matches the discord.js v14 API.


28-91: Fields initialization correctly implemented

The array of field objects is now properly passed to setFields() rather than directly assigned to fields property, following discord.js v14 patterns.


98-99: Fallback section correctly updated

The fallback logic when no frame is provided now correctly uses setter methods instead of direct property assignments.

src/bot.js (4)

1-1: Good refactoring of imports for better modularity

The change from importing the entire Discord object to importing specific components directly from discord.js follows best practices. This approach can reduce bundle size and makes dependencies explicit.


55-55: Nice upgrade to enum-based status

Replacing the string literal 'dnd' with the enum value PresenceUpdateStatus.DoNotDisturb improves type safety and makes the code less prone to errors from typos.


64-68: Proper use of GatewayIntentBits enum

Updated intents to use the GatewayIntentBits enum as required by Discord.js v14. This makes the code more type-safe and future-proof.


144-172: Successfully updated event names to camelCase format

The event names have been updated from uppercase constants (e.g., CLIENT_READY) to camelCase format (e.g., ClientReady) as required by Discord.js v14. This change has been consistently applied across all event handlers.

src/interactions/custom/CustomCommands.js (4)

1-1: Good practice using specific imports

Importing specific components directly from discord.js rather than the entire module improves code clarity and can help with tree-shaking.


15-15: Successfully updated permissions to use PermissionsBitField

The change from Permissions.FLAGS.MANAGE_GUILD to PermissionsBitField.Flags.ManageGuild is required for Discord.js v14 compatibility.


19-46: Updated command option types to use ApplicationCommandOptionType

All command option types have been correctly updated to use the ApplicationCommandOptionType enum as required by Discord.js v14, improving type safety.


53-93: Proper update of ephemeral replies to use flags

Changed from using the ephemeral property to flags for handling ephemeral messages, which is the new approach in Discord.js v14.

🧰 Tools
🪛 Biome (1.9.4)

[error] 70-73: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 74-74: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 77-77: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 78-78: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 87-87: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 88-92: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

src/interactions/core/su.js (5)

1-1: Good practice using specific imports

Importing specific components directly from discord.js is a good practice that improves code clarity and can help with tree-shaking.


16-16: Successfully updated administrator permissions

Changed from Permissions.FLAGS.ADMINISTRATOR to PermissionsBitField.Flags.Administrator as required by Discord.js v14.


21-79: Successfully updated command option types

All command option types have been updated to use the ApplicationCommandOptionType enum instead of Types constants as required by Discord.js v14.


127-127: Updated MessageEmbed to EmbedBuilder

Changed from MessageEmbed to EmbedBuilder as required by Discord.js v14. This is a significant part of the upgrade as the library has changed how embeds are created.


148-150: Updated ephemeral handling to use flags

The change from using ephemeral property to flags for ephemeral messages is aligned with Discord.js v14 requirements.

src/interactions/warframe/Builds.js (6)

1-11: Good practice using specific imports

Importing specific components directly from discord.js rather than the entire module improves code clarity and helps with tree-shaking.


141-214: Successfully updated command option types

All command option types have been updated to use the ApplicationCommandOptionType enum as required by Discord.js v14.


271-271: Updated to use EmbedBuilder

Changed from MessageEmbed to EmbedBuilder as required by Discord.js v14.


353-586: Updated ephemeral handling to use flags

The change from using the ephemeral property to flags for ephemeral messages aligns with Discord.js v14 requirements.

🧰 Tools
🪛 Biome (1.9.4)

[error] 366-366: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 366-366: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 390-392: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 398-398: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 399-399: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 405-418: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 420-437: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 434-434: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 438-438: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 439-439: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 440-458: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 459-485: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 486-509: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 494-494: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 500-500: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 510-514: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 515-521: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 524-530: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 531-582: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


516-527: Successfully updated interaction and component types

Updated InteractionType and ComponentType enums to align with Discord.js v14 requirements.


558-564: Updated button styles to use ButtonStyle enum

Changed from MessageButtonStyles to ButtonStyle enum as required by Discord.js v14.

src/utilities/CommonFunctions.js (8)

483-483: Accurate JSDoc update for pages parameter.

Changing from MessageEmbed to EmbedBuilder in the JSDoc is correct and aligns with the new Discord.js v14 API.


533-533: Proper runtime type check with instanceof EmbedBuilder.

Using instanceof EmbedBuilder instead of checking for MessageEmbed is necessary after the library upgrade; the logic remains correct.


562-562: Updated JSDoc for pages array parameter.

Stating the parameter as Array.<Object|EmbedBuilder> ensures clarity for future maintainers when passing embed arrays.


581-581: Return type reflects new EmbedBuilder usage.

Replacing Discord.MessageEmbed with Discord.EmbedBuilder in the return annotation is a valid reflection of the new class name.


584-584: Instantiating EmbedBuilder with defaults.

Creating a new EmbedBuilder(embedDefaults) is an appropriate way to apply default embed properties.


599-608: Correctly accessing fields in v14.

• Swapping embed.fields for embed.data.fields is aligned with the updated internal structure.
• Constructing additional embeds on overflow remains logically sound.


674-674: Creating EmbedBuilder for event trackables.

Utilizing const embed = new EmbedBuilder(embedDefaults); properly reflects the recommended approach for building embeds under discord.js v14.


706-706: Consistent embed instantiation in constructItemEmbeds.

Maintaining a uniform constructor for new embeds enhances consistency across all embed-generating routines.

src/utilities/Collectors.js (11)

1-10: Updated selective imports from discord.js.

Switching from older imports to direct references, including EmbedBuilder, ActionRowBuilder, ButtonBuilder, and typed enums like ButtonStyle, ensures compatibility with discord.js v14 and reduces namespace polluting.


14-30: Replacing legacy button creation with builders and enum styles.

ActionRowBuilder({ components: [...] }) is valid usage.
new ButtonBuilder({ style: ButtonStyle.* }) properly replaces the old style approach from v13.


35-48: Confirmation button row with new builder references.

Consistent application of ActionRowBuilder and ButtonBuilder for the "yes/no" confirmation component.


56-58: Refined JSDoc to mention EmbedBuilder.

These lines accurately reflect the new embed type, reducing confusion around older MessageEmbed references.


65-65: Ensuring instanceof EmbedBuilder logic.

Checks whether the page is indeed a v14 embed instance before appending page-index info.


79-79: Constructing a new EmbedBuilder from the original object.

This deepens the v14 embed usage, preventing any leftover v13 references.


87-87: JSDoc specifying an array of EmbedBuilder pages.

Ensures future maintainers know the updated parameter type for the selection method.


131-132: Use of InteractionType and ComponentType for select menus.

Switching to enumerations ensures type-safety and clarity, matching new v14 constants.


170-170: Explicit JSDoc for paged embeds parameter.

Documenting that the method expects an array of EmbedBuilder clarifies the type and usage.


199-200: Collector configured for button interactions.

Using interactionType: InteractionType.MessageComponent and componentType: ComponentType.Button is the correct approach under v14.


278-279: Confirmation collector configuration under v14.

Again, referencing InteractionType.MessageComponent and ComponentType.Button synchronizes with the new API for confirmation flows.

src/eventHandlers/InteractionHandler.js (8)

6-6: Targeted imports from discord.js.

Adopting CommandInteraction, Events, PermissionsBitField, and ApplicationCommandOptionType from the new entry points is correct for v14.


54-54: Usage of Events.InteractionCreate event constant.

Replacing 'interactionCreate' with Events.InteractionCreate follows the updated naming convention in v14.


118-120: Revised permission flags for guild roles.

Switching from Permissions.FLAGS to PermissionsBitField.Flags is required after the permission system changes in v14.


145-145: ApplicationCommandOptionType.User for command permission entry.

Ensures that user-specific overrides follow the updated enumerations introduced in v14.


151-151: Revised role-based command permission override.

Applying ApplicationCommandOptionType.Role properly represents role permissions in the updated system.


165-165: Owner override using ApplicationCommandOptionType.User.

Assigning the application owner to user-based permissions is correct with the new enum.


177-177: Granting command permission to application owner members.

Using ApplicationCommandOptionType.User ensures that all relevant owners or members are allowed.


320-320: Elevated command gating based on manage-guild permission.

interaction.member.permissions.has(PermissionsBitField.Flags.ManageGuild, false) properly checks for the updated bitfield permission.

src/interactions/channels/Rooms.js (48)

1-1: Adopt v14 submodule imports from discord.js
This updated import statement aligns with best practices in discord.js v14.


31-32: Confirm intent of permission denial logic
Denying Connect (and conditionally ViewChannel) for everyone when the channel is marked isPublic feels counterintuitive. Consider verifying whether these permissions should be allowed or denied.


42-46: Granting invite user permissions
Allowing these flags for invited users is consistent with typical voice-channel usage.


54-54: Double-check fallback permissions
Even if isPublic is false, everyone is explicitly allowed to connect here. Confirm that this matches the desired logic for non-public channels.


60-67: Bot permissions
These allow the bot to manage all relevant aspects of the channel. This is standard for administrative operations.


75-80: Author channel privileges
Granting the channel creator control to manage messages and speak is appropriate.


89-96: Moderator role permissions
Permissions for moderation tasks (manage messages, voice control, etc.) look correct for a mod role.


128-128: Switch to EmbedBuilder
Replacing MessageEmbed references with EmbedBuilder is recommended in v14.


143-143: Use of ChannelType.GuildCategory
Correctly specifying the category channel type for v14.


150-150: Use of ChannelType.GuildText
Defining a text channel using GuildText helps ensure clarity in v14.


160-160: Use of ChannelType.GuildVoice
Correctly creating a voice channel under the new typed enum.


188-188: Embed creation
Creating a new EmbedBuilder for confirmation is fully compatible with v14.


218-218: Subcommand option
Using ApplicationCommandOptionType.Subcommand is the correct approach in v14.


230-230: Switch to ApplicationCommandOptionType.Number
Replacing the older numeric type usage with v14’s enum is valid.


237-237: Boolean command option
Transition to ApplicationCommandOptionType.Boolean is correct for v14.


242-242: Boolean command option
Continued alignment with the new enum for subcommand options.


247-247: Boolean command option
Maintains consistent usage of the v14 Boolean enum.


252-252: String command option
Updating from older string references to the official enum is good practice.


257-257: String command option
Ensures type safety and clarity for user input.


264-264: Subcommand option
Matches discord.js v14 subcommand usage.


268-268: Subcommand option
Another subcommand consistent with the v14 approach.


272-272: Subcommand option
Correct usage for the next rooms-based subcommand.


276-276: Subcommand option
Maintaining uniform usage across the file.


280-280: Subcommand option
Complies with discord.js v14 subcommand syntax.


284-284: Subcommand option
Matches the established pattern for subcommands.


288-288: Subcommand option
Continued alignment with v14 best practices.


292-292: String command option
Correctly mapping the rename subcommand to String.


304-304: User command option
Switching from USER to ApplicationCommandOptionType.User is accurate in v14.


316-316: User command option
Consistent usage for the block subcommand.


324-324: Subcommand for resizing
Properly updated to v14’s Subcommand type.


382-383: Reading permission flags
Capturing current ViewChannel and Connect states for everyone is useful for toggling show/lock states.


388-388: Verifying manage permissions
Checking for both ManageChannels and ManageGuild is appropriate before proceeding.


390-390: Immediate feedback for missing perms
Returning early helps the user understand the issue promptly.


392-392: Deferred reply
Ensures compliance with interaction flow and ephemeral usage.


401-402: Ternary reply structure
Delivering a string if needed or an embed otherwise provides flexibility.


412-412: Deletion confirmation
Straightforward response verifying private room removal.


414-414: Guard for non-existent channel
Helpful user feedback when there's nothing to delete.


448-448: Room updated
Indicates the hide/show/lock/unlock operation was successful.


450-450: No relevant channel
Informs the user that there is nothing to update.


465-465: Rename confirmation
Short and clear success message.


467-467: No rename
Repeats the established user feedback pattern.


471-471: Resize success
Indicates the user limit was updated accordingly.


473-473: Resize failure
Handled gracefully with an informative message.


482-482: Report successful invite
Notifies the user that the invite operation is complete.


496-496: Block acknowledgment
Clearly states which user was blocked.


510-510: Fallback response
Provides a final catch-all reply.


537-537: Private room updated
Parallel to earlier success messages for consistent feedback.


539-539: Prompt user that no action was taken
Maintains the same pattern of user-engagement for no-op scenarios.

src/interactions/core/Settings.js (38)

26-26: Boolean command option
Transitioning to the v14 ApplicationCommandOptionType.Boolean helps maintain clarity.


44-44: Subcommand usage
Successfully aligning with the v14 subcommand requirement.


48-48: Boolean option
Consistent usage of ApplicationCommandOptionType.Boolean.


59-59: Boolean option
Following the new discord.js enum standard.


67-67: Boolean option
Retains uniform approach.


71-71: Boolean option
Ensuring coherent code for toggling settings.


77-77: Boolean option
Keeps the subcommand’s usage direct and clear.


81-81: Boolean option
Maintaining synergy with the rest of the subcommands.


88-88: Updated subcommand type
Moving to ApplicationCommandOptionType.Subcommand is correct.


93-93: Channel option
Now explicitly using the Channel enum value.


101-101: Subcommand type
Reflects modern approach in v14 for nested setting configurations.


105-105: Channel option
Direct usage for referencing the relevant channel.


113-113: Subcommand
Compatible with v14 for the LFG setting approach.


117-117: Channel type
Focuses on channel references for LFG.


122-122: String type
Using ApplicationCommandOptionType.String for the platform specification is correct.


131-131: Subcommand
Adjusted to v14 conventions for custom subcommands.


135-135: Boolean
Ensures toggling custom settings remains consistent.


143-143: Subcommand
Keeps code uniform with the updated approach to subcommands.


147-147: Boolean
Another instance of correct boolean conversion.


157-157: Subcommand
Converted from older types to the official v14 enum.


161-161: String
Adding language or text-based input in the new format.


169-169: Subcommand
Proper alignment for the platform setting subcommand.


173-173: String
Collecting user input from enumerated string choices.


181-181: Subcommand
Utilizing the new subcommand approach.


184-184: Boolean
Clear usage for ephemeral toggling.


230-230: EmbedBuilder with defaults
Instantiating an embed using embedDefaults ensures consistent styling.


381-381: Constructing a new EmbedBuilder
Creating an additional page embed is a suitable approach for presenting data.


405-405: ManageGuild permission
Using the new bitfield flag for default member permissions.


409-409: SubcommandGroup usage
Ensures a nested structure for “set” commands.


419-419: Subcommand
Allows clearing certain settings under a hierarchical approach.


425-425: Subcommand
Adds clarity to the temp_category clearing logic.


430-430: Subcommand
Wiping out all settings is now typed as a subcommand.


435-435: Subcommand
Standard approach for retrieving settings.


439-439: Subcommand
Diag subcommand also updated to the official v14 format.


449-451: Inline subcommand assignment
Collecting either a subcommand group or subcommand for more flexible processing.


518-518: Embed creation
Representing diagnostics clearly in a brand-new embed.

🧰 Tools
🪛 Biome (1.9.4)

[error] 518-519: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


535-535: Potential confusion using this statically
Referencing the class’s static properties with this may be acceptable, but some style guides prefer the class name. Confirm your preference to avoid confusion.

🧰 Tools
🪛 Biome (1.9.4)

[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 535-535: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


537-537: Potential confusion using this statically
Reiterating that referencing this.#empty in a static context can sometimes be unclear.

🧰 Tools
🪛 Biome (1.9.4)

[error] 537-537: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

src/interactions/tracking/Tracking.js (33)

1-12: Switch to explicit discord.js v14 imports
Decomposing the import ensures clarity and compliance with the new version’s recommended usage.


43-43: Use ManageGuild for default permissions
Updating from the older Permissions.FLAGS to the v14 bitfield is correct.


47-47: Subcommand
Aligning with the official ApplicationCommandOptionType.Subcommand for “manage.”


51-51: Channel option
Correctly referencing the v14 Channel type for a subcommand field.


55-55: Channel option
Permitting a thread input also aligns with the updated enum.


61-61: Subcommand
Switching the custom subcommand to the new v14 pattern.


65-65: String command
This field now properly indicates a string-based argument.


69-69: String command
Another textual parameter designated with v14’s String.


73-73: String command
Allows for more robust user input handling.


77-77: Channel command
Handling a potential voice/text channel for custom usage.


81-81: Boolean command
Toggling or clearing certain pre-defined states.


85-85: Channel command
Again referencing the v14 channel enum.


93-93: Deferred reply
Ensures the command’s operation can be asynchronous, preventing timeouts.


100-100: Thread type check
Confirming the specified channel is a text channel, preventing misuse with voice channels.


102-102: Applying custom flags
Using ctx.flags for ephemeral or other specialized reply settings.


117-117: Thread check feedback
Quickly informing the user that the given channel is not a valid thread.


123-123: Applying custom flags
Again reapplying ctx.flags for consistent ephemeral usage.


306-307: InteractionCollector types
Replacing older references with interactionType: interaction.MESSAGE_COMPONENT and componentType: ComponentType.StringSelect is appropriate in v14.


361-362: Button collector
Mirrors the same updated approach for button interactions.


208-219: Add pagination buttons
Constructing ActionRowBuilder and ButtonBuilder with the new ButtonStyle is correct.


229-229: Initialize StringSelectMenuBuilder
Complies with v14 by using structured builders for select menus.


242-243: Creating action row for subgroups
Displays the subgroup selection with StringSelectMenuBuilder.


255-257: Creating trackable selection
Enables choosing from a dynamic list of items or events.


269-294: Action buttons row
Incorporates multiple new ButtonBuilder calls with appropriate styles (Primary, Secondary, Danger).


382-389: Commit save feedback
Uses a success button style to indicate tracking data was saved.


403-410: Cancel feedback
Adjusts the UI to indicate the request was canceled.


509-509: Using flags in editReply
Applies the same ephemeral or pinned logic from ctx.flags.


515-515: Again applying flags
Maintains consistency for ephemeral or localized responses.


524-524: Show addition/removal summary
Combines added and removed trackables in one message.


528-529: Escape markdown and remove mentions
Prevents potential misuse or formatting issues for the new ping string.


532-532: Include pings string
Provides the combined user feedback with the new ping text.


550-550: Check ManageWebhooks permission
Ensures the bot can create or reuse a webhook in this channel.


580-581: Channel webhook creation
Using the newly introduced async createWebhook call with updated settings, including name and avatar.

@@ -177,7 +171,7 @@ const create = async (guild, options) => {
options.author
);
// send invites
if (voiceChannel.permissionsFor(guild.me).has(Permissions.FLAGS.CREATE_INSTANT_INVITE)) {
if (voiceChannel.permissionsFor(guild.me).has(PermissionsBitField.Flags.CreateInstantInvite)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Potential usage of deprecated guild.me
In discord.js v14, guild.members.me is the recommended approach for referencing the bot’s role. Consider updating guild.me.

- if (voiceChannel.permissionsFor(guild.me).has(PermissionsBitField.Flags.CreateInstantInvite)) {
+ if (voiceChannel.permissionsFor(guild.members.me).has(PermissionsBitField.Flags.CreateInstantInvite)) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (voiceChannel.permissionsFor(guild.me).has(PermissionsBitField.Flags.CreateInstantInvite)) {
if (voiceChannel.permissionsFor(guild.members.me).has(PermissionsBitField.Flags.CreateInstantInvite)) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

upgrade discord.js v13 -> v14
2 participants