diff --git a/packages/discord.js/src/structures/ChatInputCommandInteraction.js b/packages/discord.js/src/structures/ChatInputCommandInteraction.js index 6b40037dd7dd..17f6589366f8 100644 --- a/packages/discord.js/src/structures/ChatInputCommandInteraction.js +++ b/packages/discord.js/src/structures/ChatInputCommandInteraction.js @@ -2,7 +2,7 @@ const CommandInteraction = require('./CommandInteraction'); const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver'); -const { transformResolved } = require('../util/transformResolved'); +const { transformResolved } = require('../util/Util'); /** * Represents a command interaction. diff --git a/packages/discord.js/src/structures/ContextMenuCommandInteraction.js b/packages/discord.js/src/structures/ContextMenuCommandInteraction.js index efa848775976..7df06b68b35c 100644 --- a/packages/discord.js/src/structures/ContextMenuCommandInteraction.js +++ b/packages/discord.js/src/structures/ContextMenuCommandInteraction.js @@ -4,7 +4,7 @@ const { lazy } = require('@discordjs/util'); const { ApplicationCommandOptionType } = require('discord-api-types/v10'); const CommandInteraction = require('./CommandInteraction'); const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver'); -const { transformResolved } = require('../util/transformResolved'); +const { transformResolved } = require('../util/Util'); const getMessage = lazy(() => require('./Message').Message); diff --git a/packages/discord.js/src/structures/Message.js b/packages/discord.js/src/structures/Message.js index 811eceac8db1..eb6d1c680c41 100644 --- a/packages/discord.js/src/structures/Message.js +++ b/packages/discord.js/src/structures/Message.js @@ -25,8 +25,7 @@ const { createComponent } = require('../util/Components'); const { NonSystemMessageTypes, MaxBulkDeletableMessageAge, DeletableMessageTypes } = require('../util/Constants'); const MessageFlagsBitField = require('../util/MessageFlagsBitField'); const PermissionsBitField = require('../util/PermissionsBitField'); -const { cleanContent, resolvePartialEmoji } = require('../util/Util'); -const { transformResolved } = require('../util/transformResolved'); +const { cleanContent, resolvePartialEmoji, transformResolved } = require('../util/Util'); /** * Represents a message on Discord. diff --git a/packages/discord.js/src/util/Util.js b/packages/discord.js/src/util/Util.js index eeef8bab09f4..e5b8d4f8e09b 100644 --- a/packages/discord.js/src/util/Util.js +++ b/packages/discord.js/src/util/Util.js @@ -6,6 +6,7 @@ const { ChannelType, RouteBases, Routes } = require('discord-api-types/v10'); const { fetch } = require('undici'); const Colors = require('./Colors'); const { DiscordjsError, DiscordjsRangeError, DiscordjsTypeError, ErrorCodes } = require('../errors'); +const Attachment = require('../structures/Attachment'); const isObject = d => typeof d === 'object' && d !== null; /** @@ -409,6 +410,75 @@ function parseWebhookURL(url) { }; } +/** + * Supportive data for interaction resolved data. + * @typedef {Object} SupportingInteractionResolvedData + * @property {Client} client The client + * @property {Guild} [guild] A guild + * @property {BaseChannel} [channel] A channel + * @private + */ + +/** + * Transforms the resolved data received from the API. + * @param {SupportingInteractionResolvedData} supportingData Data to support the transformation + * @param {APIInteractionDataResolved} [data] The received resolved objects + * @returns {CommandInteractionResolvedData} + * @private + */ +function transformResolved( + { client, guild, channel }, + { members, users, channels, roles, messages, attachments } = {}, +) { + const result = {}; + + if (members) { + result.members = new Collection(); + for (const [id, member] of Object.entries(members)) { + const user = users[id]; + result.members.set(id, guild?.members._add({ user, ...member }) ?? member); + } + } + + if (users) { + result.users = new Collection(); + for (const user of Object.values(users)) { + result.users.set(user.id, client.users._add(user)); + } + } + + if (roles) { + result.roles = new Collection(); + for (const role of Object.values(roles)) { + result.roles.set(role.id, guild?.roles._add(role) ?? role); + } + } + + if (channels) { + result.channels = new Collection(); + for (const apiChannel of Object.values(channels)) { + result.channels.set(apiChannel.id, client.channels._add(apiChannel, guild) ?? apiChannel); + } + } + + if (messages) { + result.messages = new Collection(); + for (const message of Object.values(messages)) { + result.messages.set(message.id, channel?.messages?._add(message) ?? message); + } + } + + if (attachments) { + result.attachments = new Collection(); + for (const attachment of Object.values(attachments)) { + const patched = new Attachment(attachment); + result.attachments.set(attachment.id, patched); + } + } + + return result; +} + module.exports = { flatten, fetchRecommendedShardCount, @@ -426,6 +496,7 @@ module.exports = { cleanContent, cleanCodeBlockContent, parseWebhookURL, + transformResolved, }; // Fixes Circular diff --git a/packages/discord.js/src/util/transformResolved.js b/packages/discord.js/src/util/transformResolved.js deleted file mode 100644 index 720f0c40e736..000000000000 --- a/packages/discord.js/src/util/transformResolved.js +++ /dev/null @@ -1,75 +0,0 @@ -'use strict'; - -const { Collection } = require('@discordjs/collection'); -const Attachment = require('../structures/Attachment'); - -/** - * Supportive data for interaction resolved data. - * @typedef {Object} SupportingInteractionResolvedData - * @property {Client} client The client - * @property {Guild} [guild] A guild - * @property {BaseChannel} [channel] A channel - * @private - */ - -/** - * Transforms the resolved data received from the API. - * @param {SupportingInteractionResolvedData} supportingData Data to support the transformation - * @param {APIInteractionDataResolved} [data] The received resolved objects - * @returns {CommandInteractionResolvedData} - * @ignore - */ -function transformResolved( - { client, guild, channel }, - { members, users, channels, roles, messages, attachments } = {}, -) { - const result = {}; - - if (members) { - result.members = new Collection(); - for (const [id, member] of Object.entries(members)) { - const user = users[id]; - result.members.set(id, guild?.members._add({ user, ...member }) ?? member); - } - } - - if (users) { - result.users = new Collection(); - for (const user of Object.values(users)) { - result.users.set(user.id, client.users._add(user)); - } - } - - if (roles) { - result.roles = new Collection(); - for (const role of Object.values(roles)) { - result.roles.set(role.id, guild?.roles._add(role) ?? role); - } - } - - if (channels) { - result.channels = new Collection(); - for (const apiChannel of Object.values(channels)) { - result.channels.set(apiChannel.id, client.channels._add(apiChannel, guild) ?? apiChannel); - } - } - - if (messages) { - result.messages = new Collection(); - for (const message of Object.values(messages)) { - result.messages.set(message.id, channel?.messages?._add(message) ?? message); - } - } - - if (attachments) { - result.attachments = new Collection(); - for (const attachment of Object.values(attachments)) { - const patched = new Attachment(attachment); - result.attachments.set(attachment.id, patched); - } - } - - return result; -} - -module.exports = { transformResolved }; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 9074892ad366..8d4e4b3adcf2 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3221,6 +3221,10 @@ export function setPosition( reason?: string, ): Promise<{ id: Snowflake; position: number }[]>; export function parseWebhookURL(url: string): WebhookClientDataIdWithToken | null; +export function transformResolved( + supportingData: SupportingInteractionResolvedData, + data?: APIApplicationCommandInteractionData['resolved'], +): CommandInteractionResolvedData; export interface MappedComponentBuilderTypes { [ComponentType.Button]: ButtonBuilder; @@ -6361,6 +6365,12 @@ export interface StageInstanceEditOptions { privacyLevel?: StageInstancePrivacyLevel; } +export interface SupportingInteractionResolvedData { + client: Client; + guild?: Guild; + channel?: BaseChannel; +} + export type SweeperKey = keyof SweeperDefinitions; export type CollectionSweepFilter = (value: V, key: K, collection: Collection) => boolean;