From b5288ffe8b393cbb2b234f08903647ac6a352802 Mon Sep 17 00:00:00 2001 From: Jaw0r3k Date: Tue, 3 Oct 2023 21:19:41 +0200 Subject: [PATCH 01/12] feat: default select menu values --- .../selectMenu/ChannelSelectMenu.ts | 41 +++++++++++++- .../selectMenu/MentionableSelectMenu.ts | 55 ++++++++++++++++++- .../components/selectMenu/RoleSelectMenu.ts | 36 +++++++++++- .../components/selectMenu/UserSelectMenu.ts | 36 +++++++++++- 4 files changed, 159 insertions(+), 9 deletions(-) diff --git a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts index fe5b27b83ae1..56fb25d423e2 100644 --- a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts @@ -1,7 +1,12 @@ -import type { APIChannelSelectComponent, ChannelType } from 'discord-api-types/v10'; -import { ComponentType } from 'discord-api-types/v10'; +import type { + APIChannelSelectComponent, + APISelectMenuDefaultValue, + ChannelType, + Snowflake, +} from 'discord-api-types/v10'; +import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js'; -import { channelTypesValidator, customIdValidator } from '../Assertions.js'; +import { channelTypesValidator, customIdValidator, optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; /** @@ -59,6 +64,36 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder) { + const normalizedValues = channels.map((id) => { + return { id, type: SelectMenuDefaultValueType.Channel }; + }) as APISelectMenuDefaultValue[]; + this.data.default_values ??= []; + optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); + this.data.default_values.push(...normalizedValues); + return this; + } + + /** + * Sets default channels to this auto populated select menu. + * + * @param channels - The channels to set + */ + public setDefaultChannels(...channels: RestOrArray) { + const normalizedValues = channels.map((id) => { + return { id, type: SelectMenuDefaultValueType.Channel }; + }) as APISelectMenuDefaultValue[]; + optionsLengthValidator.parse(normalizedValues.length); + this.data.default_values ??= []; + this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); + return this; + } + /** * {@inheritDoc BaseSelectMenuBuilder.toJSON} */ diff --git a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts index a3a39a975fd8..f90ad443bc5b 100644 --- a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts @@ -1,5 +1,8 @@ -import type { APIMentionableSelectComponent } from 'discord-api-types/v10'; -import { ComponentType } from 'discord-api-types/v10'; +import type { APIMentionableSelectComponent, APISelectMenuDefaultValue, Snowflake } from 'discord-api-types/v10'; +import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; +import type { RestOrArray } from '../../index.js'; +import { normalizeArray } from '../../index.js'; +import { optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; /** @@ -31,4 +34,52 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder) { super({ ...data, type: ComponentType.MentionableSelect }); } + + /** + * Adds default roles to this auto populated select menu. + * + * @param roles - The roles to add + */ + public addDefaultRoles(...roles: RestOrArray) { + const normalizedValues = roles.map((id) => { + return { id, type: SelectMenuDefaultValueType.Role }; + }) as APISelectMenuDefaultValue[]; + this.data.default_values ??= []; + optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); + this.data.default_values.push(...normalizedValues); + return this; + } + + /** + * Adds default users to this auto populated select menu. + * + * @param users - The users to add + */ + public addDefaultUsers(...users: RestOrArray) { + const normalizedValues = users.map((id) => { + return { id, type: SelectMenuDefaultValueType.User }; + }) as APISelectMenuDefaultValue[]; + this.data.default_values ??= []; + optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); + this.data.default_values.push(...normalizedValues); + return this; + } + + /** + * Sets default values to this auto populated select menu. + * + * @param values - The values to set + */ + public setDefaultValues( + ...values: RestOrArray< + | APISelectMenuDefaultValue + | APISelectMenuDefaultValue + > + ) { + const normalizedValues = normalizeArray(values); + optionsLengthValidator.parse(normalizedValues.length); + this.data.default_values ??= []; + this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); + return this; + } } diff --git a/packages/builders/src/components/selectMenu/RoleSelectMenu.ts b/packages/builders/src/components/selectMenu/RoleSelectMenu.ts index 2055b5f536cc..658e76d05807 100644 --- a/packages/builders/src/components/selectMenu/RoleSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/RoleSelectMenu.ts @@ -1,5 +1,7 @@ -import type { APIRoleSelectComponent } from 'discord-api-types/v10'; -import { ComponentType } from 'discord-api-types/v10'; +import type { APIRoleSelectComponent, APISelectMenuDefaultValue, Snowflake } from 'discord-api-types/v10'; +import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; +import type { RestOrArray } from '../../index.js'; +import { optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; /** @@ -31,4 +33,34 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder) { super({ ...data, type: ComponentType.RoleSelect }); } + + /** + * Adds default roles to this auto populated select menu. + * + * @param roles - The roles to add + */ + public addDefaultRoles(...roles: RestOrArray) { + const normalizedValues = roles.map((id) => { + return { id, type: SelectMenuDefaultValueType.Role }; + }) as APISelectMenuDefaultValue[]; + this.data.default_values ??= []; + optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); + this.data.default_values.push(...normalizedValues); + return this; + } + + /** + * Sets default roles to this auto populated select menu. + * + * @param roles - The roles to set + */ + public setDefaultRoles(...roles: RestOrArray) { + const normalizedValues = roles.map((id) => { + return { id, type: SelectMenuDefaultValueType.Role }; + }) as APISelectMenuDefaultValue[]; + optionsLengthValidator.parse(normalizedValues.length); + this.data.default_values ??= []; + this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); + return this; + } } diff --git a/packages/builders/src/components/selectMenu/UserSelectMenu.ts b/packages/builders/src/components/selectMenu/UserSelectMenu.ts index 09e184d65e99..8d12c909e847 100644 --- a/packages/builders/src/components/selectMenu/UserSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/UserSelectMenu.ts @@ -1,5 +1,7 @@ -import type { APIUserSelectComponent } from 'discord-api-types/v10'; -import { ComponentType } from 'discord-api-types/v10'; +import type { APISelectMenuDefaultValue, APIUserSelectComponent, Snowflake } from 'discord-api-types/v10'; +import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; +import type { RestOrArray } from '../../index.js'; +import { optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; /** @@ -31,4 +33,34 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder) { super({ ...data, type: ComponentType.UserSelect }); } + + /** + * Adds default users to this auto populated select menu. + * + * @param users - The users to add + */ + public addDefaultUsers(...users: RestOrArray) { + const normalizedValues = users.map((id) => { + return { id, type: SelectMenuDefaultValueType.User }; + }) as APISelectMenuDefaultValue[]; + this.data.default_values ??= []; + optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); + this.data.default_values.push(...normalizedValues); + return this; + } + + /** + * Sets default users to this auto populated select menu. + * + * @param users - The users to set + */ + public setDefaultUsers(...users: RestOrArray) { + const normalizedValues = users.map((id) => { + return { id, type: SelectMenuDefaultValueType.User }; + }) as APISelectMenuDefaultValue[]; + optionsLengthValidator.parse(normalizedValues.length); + this.data.default_values ??= []; + this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); + return this; + } } From 4ce333c58d13baa0a21bc80e1a46229a0de63fe0 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sat, 11 Nov 2023 21:16:31 +0000 Subject: [PATCH 02/12] feat(Message): support --- .../structures/ChatInputCommandInteraction.js | 3 +- .../src/structures/CommandInteraction.js | 57 -------------- .../ContextMenuCommandInteraction.js | 3 +- packages/discord.js/src/structures/Message.js | 14 ++++ .../discord.js/src/util/transformResolved.js | 75 +++++++++++++++++++ packages/discord.js/typings/index.d.ts | 4 +- 6 files changed, 94 insertions(+), 62 deletions(-) create mode 100644 packages/discord.js/src/util/transformResolved.js diff --git a/packages/discord.js/src/structures/ChatInputCommandInteraction.js b/packages/discord.js/src/structures/ChatInputCommandInteraction.js index 4c4daf832a8b..6b40037dd7dd 100644 --- a/packages/discord.js/src/structures/ChatInputCommandInteraction.js +++ b/packages/discord.js/src/structures/ChatInputCommandInteraction.js @@ -2,6 +2,7 @@ const CommandInteraction = require('./CommandInteraction'); const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver'); +const { transformResolved } = require('../util/transformResolved'); /** * Represents a command interaction. @@ -18,7 +19,7 @@ class ChatInputCommandInteraction extends CommandInteraction { this.options = new CommandInteractionOptionResolver( this.client, data.data.options?.map(option => this.transformOption(option, data.data.resolved)) ?? [], - this.transformResolved(data.data.resolved ?? {}), + transformResolved({ client: this.client, guild: this.guild, channel: this.channel }, data.data.resolved), ); } diff --git a/packages/discord.js/src/structures/CommandInteraction.js b/packages/discord.js/src/structures/CommandInteraction.js index f5cbb8337d9c..88086f9605b2 100644 --- a/packages/discord.js/src/structures/CommandInteraction.js +++ b/packages/discord.js/src/structures/CommandInteraction.js @@ -1,6 +1,5 @@ 'use strict'; -const { Collection } = require('@discordjs/collection'); const Attachment = require('./Attachment'); const BaseInteraction = require('./BaseInteraction'); const InteractionWebhook = require('./InteractionWebhook'); @@ -91,62 +90,6 @@ class CommandInteraction extends BaseInteraction { * @property {Collection} [attachments] The resolved attachments */ - /** - * Transforms the resolved received from the API. - * @param {APIInteractionDataResolved} resolved The received resolved objects - * @returns {CommandInteractionResolvedData} - * @private - */ - transformResolved({ 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, this.guild?.members._add({ user, ...member }) ?? member); - } - } - - if (users) { - result.users = new Collection(); - for (const user of Object.values(users)) { - result.users.set(user.id, this.client.users._add(user)); - } - } - - if (roles) { - result.roles = new Collection(); - for (const role of Object.values(roles)) { - result.roles.set(role.id, this.guild?.roles._add(role) ?? role); - } - } - - if (channels) { - result.channels = new Collection(); - for (const channel of Object.values(channels)) { - result.channels.set(channel.id, this.client.channels._add(channel, this.guild) ?? channel); - } - } - - if (messages) { - result.messages = new Collection(); - for (const message of Object.values(messages)) { - result.messages.set(message.id, this.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; - } - /** * Represents an option of a received command interaction. * @typedef {Object} CommandInteractionOption diff --git a/packages/discord.js/src/structures/ContextMenuCommandInteraction.js b/packages/discord.js/src/structures/ContextMenuCommandInteraction.js index fc49ca56d3eb..efa848775976 100644 --- a/packages/discord.js/src/structures/ContextMenuCommandInteraction.js +++ b/packages/discord.js/src/structures/ContextMenuCommandInteraction.js @@ -4,6 +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 getMessage = lazy(() => require('./Message').Message); @@ -21,7 +22,7 @@ class ContextMenuCommandInteraction extends CommandInteraction { this.options = new CommandInteractionOptionResolver( this.client, this.resolveContextMenuOptions(data.data), - this.transformResolved(data.data.resolved), + transformResolved({ client: this.client, guild: this.guild, channel: this.channel }, data.data.resolved), ); /** diff --git a/packages/discord.js/src/structures/Message.js b/packages/discord.js/src/structures/Message.js index 7f145b3b8436..811eceac8db1 100644 --- a/packages/discord.js/src/structures/Message.js +++ b/packages/discord.js/src/structures/Message.js @@ -26,6 +26,7 @@ const { NonSystemMessageTypes, MaxBulkDeletableMessageAge, DeletableMessageTypes const MessageFlagsBitField = require('../util/MessageFlagsBitField'); const PermissionsBitField = require('../util/PermissionsBitField'); const { cleanContent, resolvePartialEmoji } = require('../util/Util'); +const { transformResolved } = require('../util/transformResolved'); /** * Represents a message on Discord. @@ -223,6 +224,19 @@ class Message extends Base { this.roleSubscriptionData ??= null; } + if ('resolved' in data) { + /** + * Resolved data from auto-populated select menus. + * @typedef {Object} CommandInteractionResolvedData; + */ + this.resolved = transformResolved( + { client: this.client, guild: this.guild, channel: this.channel }, + data.resolved, + ); + } else { + this.resolved ??= null; + } + // Discord sends null if the message has not been edited if (data.edited_timestamp) { /** diff --git a/packages/discord.js/src/util/transformResolved.js b/packages/discord.js/src/util/transformResolved.js new file mode 100644 index 000000000000..fef34f84ccf2 --- /dev/null +++ b/packages/discord.js/src/util/transformResolved.js @@ -0,0 +1,75 @@ +'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 {Channel} [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 876cd8384a06..9074892ad366 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -586,9 +586,6 @@ export abstract class CommandInteraction e option: APIApplicationCommandOption, resolved: APIApplicationCommandInteractionData['resolved'], ): CommandInteractionOption; - private transformResolved( - resolved: APIApplicationCommandInteractionData['resolved'], - ): CommandInteractionResolvedData; } export class InteractionResponse { @@ -2037,6 +2034,7 @@ export class Message extends Base { public stickers: Collection; public position: number | null; public roleSubscriptionData: RoleSubscriptionData | null; + public resolved: CommandInteractionResolvedData | null; public system: boolean; public get thread(): AnyThreadChannel | null; public tts: boolean; From 3231ee996c39abd260739356f11645687b32175b Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sat, 11 Nov 2023 21:30:49 +0000 Subject: [PATCH 03/12] fix: fix crashes when an array is supplied and remove assertion --- .../selectMenu/ChannelSelectMenu.ts | 30 +++++++++++-------- .../selectMenu/MentionableSelectMenu.ts | 28 ++++++++++------- .../components/selectMenu/RoleSelectMenu.ts | 26 ++++++++++------ .../components/selectMenu/UserSelectMenu.ts | 26 ++++++++++------ 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts index 56fb25d423e2..0a0a3ecc0aaf 100644 --- a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts @@ -1,11 +1,11 @@ -import type { - APIChannelSelectComponent, - APISelectMenuDefaultValue, - ChannelType, - Snowflake, +import { + type APIChannelSelectComponent, + type ChannelType, + type Snowflake, + ComponentType, + SelectMenuDefaultValueType, } from 'discord-api-types/v10'; -import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; -import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js'; +import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js'; import { channelTypesValidator, customIdValidator, optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; @@ -70,9 +70,11 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = channels.map((id) => { - return { id, type: SelectMenuDefaultValueType.Channel }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(channels).map((id) => ({ + id, + type: SelectMenuDefaultValueType.Channel as const, + })); + this.data.default_values ??= []; optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); this.data.default_values.push(...normalizedValues); @@ -85,9 +87,11 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = channels.map((id) => { - return { id, type: SelectMenuDefaultValueType.Channel }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(channels).map((id) => ({ + id, + type: SelectMenuDefaultValueType.Channel as const, + })); + optionsLengthValidator.parse(normalizedValues.length); this.data.default_values ??= []; this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); diff --git a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts index f90ad443bc5b..1f0b3736c7b8 100644 --- a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts @@ -1,7 +1,11 @@ -import type { APIMentionableSelectComponent, APISelectMenuDefaultValue, Snowflake } from 'discord-api-types/v10'; -import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; -import type { RestOrArray } from '../../index.js'; -import { normalizeArray } from '../../index.js'; +import { + type APIMentionableSelectComponent, + type APISelectMenuDefaultValue, + type Snowflake, + ComponentType, + SelectMenuDefaultValueType, +} from 'discord-api-types/v10'; +import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js'; import { optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; @@ -41,9 +45,11 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = roles.map((id) => { - return { id, type: SelectMenuDefaultValueType.Role }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(roles).map((id) => ({ + id, + type: SelectMenuDefaultValueType.Role as const, + })); + this.data.default_values ??= []; optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); this.data.default_values.push(...normalizedValues); @@ -56,9 +62,11 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = users.map((id) => { - return { id, type: SelectMenuDefaultValueType.User }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(users).map((id) => ({ + id, + type: SelectMenuDefaultValueType.User as const, + })); + this.data.default_values ??= []; optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); this.data.default_values.push(...normalizedValues); diff --git a/packages/builders/src/components/selectMenu/RoleSelectMenu.ts b/packages/builders/src/components/selectMenu/RoleSelectMenu.ts index 658e76d05807..271bc09bab00 100644 --- a/packages/builders/src/components/selectMenu/RoleSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/RoleSelectMenu.ts @@ -1,6 +1,10 @@ -import type { APIRoleSelectComponent, APISelectMenuDefaultValue, Snowflake } from 'discord-api-types/v10'; -import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; -import type { RestOrArray } from '../../index.js'; +import { + type APIRoleSelectComponent, + type Snowflake, + ComponentType, + SelectMenuDefaultValueType, +} from 'discord-api-types/v10'; +import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js'; import { optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; @@ -40,9 +44,11 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = roles.map((id) => { - return { id, type: SelectMenuDefaultValueType.Role }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(roles).map((id) => ({ + id, + type: SelectMenuDefaultValueType.Role as const, + })); + this.data.default_values ??= []; optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); this.data.default_values.push(...normalizedValues); @@ -55,9 +61,11 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = roles.map((id) => { - return { id, type: SelectMenuDefaultValueType.Role }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(roles).map((id) => ({ + id, + type: SelectMenuDefaultValueType.Role as const, + })); + optionsLengthValidator.parse(normalizedValues.length); this.data.default_values ??= []; this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); diff --git a/packages/builders/src/components/selectMenu/UserSelectMenu.ts b/packages/builders/src/components/selectMenu/UserSelectMenu.ts index 8d12c909e847..4ae071b70ba7 100644 --- a/packages/builders/src/components/selectMenu/UserSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/UserSelectMenu.ts @@ -1,6 +1,10 @@ -import type { APISelectMenuDefaultValue, APIUserSelectComponent, Snowflake } from 'discord-api-types/v10'; -import { ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10'; -import type { RestOrArray } from '../../index.js'; +import { + type APIUserSelectComponent, + type Snowflake, + ComponentType, + SelectMenuDefaultValueType, +} from 'discord-api-types/v10'; +import { type RestOrArray, normalizeArray } from '../../util/normalizeArray.js'; import { optionsLengthValidator } from '../Assertions.js'; import { BaseSelectMenuBuilder } from './BaseSelectMenu.js'; @@ -40,9 +44,11 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = users.map((id) => { - return { id, type: SelectMenuDefaultValueType.User }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(users).map((id) => ({ + id, + type: SelectMenuDefaultValueType.User as const, + })); + this.data.default_values ??= []; optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); this.data.default_values.push(...normalizedValues); @@ -55,9 +61,11 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = users.map((id) => { - return { id, type: SelectMenuDefaultValueType.User }; - }) as APISelectMenuDefaultValue[]; + const normalizedValues = normalizeArray(users).map((id) => ({ + id, + type: SelectMenuDefaultValueType.User as const, + })); + optionsLengthValidator.parse(normalizedValues.length); this.data.default_values ??= []; this.data.default_values.splice(0, this.data.default_values.length, ...normalizedValues); From 00fc0e45b7ba6a7d067c8d06cb7368f13d1f43b0 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 14:50:30 +0000 Subject: [PATCH 04/12] docs(transformResolved): `BaseChannel` is the correct type --- packages/discord.js/src/util/transformResolved.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord.js/src/util/transformResolved.js b/packages/discord.js/src/util/transformResolved.js index fef34f84ccf2..720f0c40e736 100644 --- a/packages/discord.js/src/util/transformResolved.js +++ b/packages/discord.js/src/util/transformResolved.js @@ -8,7 +8,7 @@ const Attachment = require('../structures/Attachment'); * @typedef {Object} SupportingInteractionResolvedData * @property {Client} client The client * @property {Guild} [guild] A guild - * @property {Channel} [channel] A channel + * @property {BaseChannel} [channel] A channel * @private */ From eea42a909c5db66bcd90609e1d666c2fda69dcab Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 14:57:25 +0000 Subject: [PATCH 05/12] refactor: prefer assignment --- .../builders/src/components/selectMenu/ChannelSelectMenu.ts | 3 +-- .../src/components/selectMenu/MentionableSelectMenu.ts | 3 +-- packages/builders/src/components/selectMenu/RoleSelectMenu.ts | 3 +-- packages/builders/src/components/selectMenu/UserSelectMenu.ts | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts index 0a0a3ecc0aaf..28a7c1edf994 100644 --- a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts @@ -93,8 +93,7 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder Date: Sun, 12 Nov 2023 15:10:39 +0000 Subject: [PATCH 06/12] chore: export function again --- .../structures/ChatInputCommandInteraction.js | 2 +- .../ContextMenuCommandInteraction.js | 2 +- packages/discord.js/src/structures/Message.js | 3 +- packages/discord.js/src/util/Util.js | 71 ++++++++++++++++++ .../discord.js/src/util/transformResolved.js | 75 ------------------- packages/discord.js/typings/index.d.ts | 10 +++ 6 files changed, 84 insertions(+), 79 deletions(-) delete mode 100644 packages/discord.js/src/util/transformResolved.js 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..50c419bd25f8 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?: Channel; +} + export type SweeperKey = keyof SweeperDefinitions; export type CollectionSweepFilter = (value: V, key: K, collection: Collection) => boolean; From ad636721f64101484a112ac45e2bb5cb741cb74e Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 15:19:38 +0000 Subject: [PATCH 07/12] fix(Util): fix circular dependency --- packages/discord.js/src/util/Util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord.js/src/util/Util.js b/packages/discord.js/src/util/Util.js index e5b8d4f8e09b..748a1f9b99c1 100644 --- a/packages/discord.js/src/util/Util.js +++ b/packages/discord.js/src/util/Util.js @@ -6,7 +6,6 @@ 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; /** @@ -500,4 +499,5 @@ module.exports = { }; // Fixes Circular +const Attachment = require('../structures/Attachment'); const GuildChannel = require('../structures/GuildChannel'); From ae206f09b0054ab0aa00e3e86cabf50222c3c243 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 15:35:26 +0000 Subject: [PATCH 08/12] refactor(MentionableSelectMenu): clone in method --- .../builders/src/components/selectMenu/MentionableSelectMenu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts index b0f577a02990..2f4cfee224ce 100644 --- a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts @@ -86,7 +86,7 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder Date: Sun, 12 Nov 2023 15:41:21 +0000 Subject: [PATCH 09/12] docs: remove semicolon --- packages/discord.js/src/structures/Message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord.js/src/structures/Message.js b/packages/discord.js/src/structures/Message.js index eb6d1c680c41..679b34a8d5a9 100644 --- a/packages/discord.js/src/structures/Message.js +++ b/packages/discord.js/src/structures/Message.js @@ -226,7 +226,7 @@ class Message extends Base { if ('resolved' in data) { /** * Resolved data from auto-populated select menus. - * @typedef {Object} CommandInteractionResolvedData; + * @typedef {Object} CommandInteractionResolvedData */ this.resolved = transformResolved( { client: this.client, guild: this.guild, channel: this.channel }, From edf73f07f935e8f447032db8fa9bc9d4217b6775 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 16:12:07 +0000 Subject: [PATCH 10/12] feat(MentionableSelectMenu): add `addDefaultValues()` --- .../selectMenu/MentionableSelectMenu.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts index 2f4cfee224ce..82b709e846b2 100644 --- a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts @@ -73,6 +73,24 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder + | APISelectMenuDefaultValue + > + ) { + const normalizedValues = normalizeArray(values); + this.data.default_values ??= []; + optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); + this.data.default_values.push(...normalizedValues); + return this; + } + /** * Sets default values to this auto populated select menu. * From c1e7ee8ffb8be5634d8bd26f5d4cb4f2b1c9f0ee Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 16:24:02 +0000 Subject: [PATCH 11/12] refactor: reduce overhead --- .../selectMenu/ChannelSelectMenu.ts | 24 +++++++------ .../selectMenu/MentionableSelectMenu.ts | 36 +++++++++++-------- .../components/selectMenu/RoleSelectMenu.ts | 24 +++++++------ .../components/selectMenu/UserSelectMenu.ts | 24 +++++++------ 4 files changed, 63 insertions(+), 45 deletions(-) diff --git a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts index 28a7c1edf994..35dfb9a53a0b 100644 --- a/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/ChannelSelectMenu.ts @@ -70,14 +70,17 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(channels).map((id) => ({ - id, - type: SelectMenuDefaultValueType.Channel as const, - })); - + const normalizedValues = normalizeArray(channels); + optionsLengthValidator.parse((this.data.default_values?.length ?? 0) + normalizedValues.length); this.data.default_values ??= []; - optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); - this.data.default_values.push(...normalizedValues); + + this.data.default_values.push( + ...normalizedValues.map((id) => ({ + id, + type: SelectMenuDefaultValueType.Channel as const, + })), + ); + return this; } @@ -87,13 +90,14 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(channels).map((id) => ({ + const normalizedValues = normalizeArray(channels); + optionsLengthValidator.parse(normalizedValues.length); + + this.data.default_values = normalizedValues.map((id) => ({ id, type: SelectMenuDefaultValueType.Channel as const, })); - optionsLengthValidator.parse(normalizedValues.length); - this.data.default_values = normalizedValues; return this; } diff --git a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts index 82b709e846b2..b577822e9e0a 100644 --- a/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/MentionableSelectMenu.ts @@ -45,14 +45,17 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(roles).map((id) => ({ - id, - type: SelectMenuDefaultValueType.Role as const, - })); - + const normalizedValues = normalizeArray(roles); + optionsLengthValidator.parse((this.data.default_values?.length ?? 0) + normalizedValues.length); this.data.default_values ??= []; - optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); - this.data.default_values.push(...normalizedValues); + + this.data.default_values.push( + ...normalizedValues.map((id) => ({ + id, + type: SelectMenuDefaultValueType.Role as const, + })), + ); + return this; } @@ -62,14 +65,17 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(users).map((id) => ({ - id, - type: SelectMenuDefaultValueType.User as const, - })); - + const normalizedValues = normalizeArray(users); + optionsLengthValidator.parse((this.data.default_values?.length ?? 0) + normalizedValues.length); this.data.default_values ??= []; - optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); - this.data.default_values.push(...normalizedValues); + + this.data.default_values.push( + ...normalizedValues.map((id) => ({ + id, + type: SelectMenuDefaultValueType.User as const, + })), + ); + return this; } @@ -85,8 +91,8 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder ) { const normalizedValues = normalizeArray(values); + optionsLengthValidator.parse((this.data.default_values?.length ?? 0) + normalizedValues.length); this.data.default_values ??= []; - optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); this.data.default_values.push(...normalizedValues); return this; } diff --git a/packages/builders/src/components/selectMenu/RoleSelectMenu.ts b/packages/builders/src/components/selectMenu/RoleSelectMenu.ts index bd5801ce10a3..f3ae4ab01421 100644 --- a/packages/builders/src/components/selectMenu/RoleSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/RoleSelectMenu.ts @@ -44,14 +44,17 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(roles).map((id) => ({ - id, - type: SelectMenuDefaultValueType.Role as const, - })); - + const normalizedValues = normalizeArray(roles); + optionsLengthValidator.parse((this.data.default_values?.length ?? 0) + normalizedValues.length); this.data.default_values ??= []; - optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); - this.data.default_values.push(...normalizedValues); + + this.data.default_values.push( + ...normalizedValues.map((id) => ({ + id, + type: SelectMenuDefaultValueType.Role as const, + })), + ); + return this; } @@ -61,13 +64,14 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(roles).map((id) => ({ + const normalizedValues = normalizeArray(roles); + optionsLengthValidator.parse(normalizedValues.length); + + this.data.default_values = normalizedValues.map((id) => ({ id, type: SelectMenuDefaultValueType.Role as const, })); - optionsLengthValidator.parse(normalizedValues.length); - this.data.default_values = normalizedValues; return this; } } diff --git a/packages/builders/src/components/selectMenu/UserSelectMenu.ts b/packages/builders/src/components/selectMenu/UserSelectMenu.ts index aff23d339f40..1d32583ab095 100644 --- a/packages/builders/src/components/selectMenu/UserSelectMenu.ts +++ b/packages/builders/src/components/selectMenu/UserSelectMenu.ts @@ -44,14 +44,17 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(users).map((id) => ({ - id, - type: SelectMenuDefaultValueType.User as const, - })); - + const normalizedValues = normalizeArray(users); + optionsLengthValidator.parse((this.data.default_values?.length ?? 0) + normalizedValues.length); this.data.default_values ??= []; - optionsLengthValidator.parse(this.data.default_values.length + normalizedValues.length); - this.data.default_values.push(...normalizedValues); + + this.data.default_values.push( + ...normalizedValues.map((id) => ({ + id, + type: SelectMenuDefaultValueType.User as const, + })), + ); + return this; } @@ -61,13 +64,14 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder) { - const normalizedValues = normalizeArray(users).map((id) => ({ + const normalizedValues = normalizeArray(users); + optionsLengthValidator.parse(normalizedValues.length); + + this.data.default_values = normalizedValues.map((id) => ({ id, type: SelectMenuDefaultValueType.User as const, })); - optionsLengthValidator.parse(normalizedValues.length); - this.data.default_values = normalizedValues; return this; } } From 256821b272e9cc8fa52bcd445471c9e3882db20d Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Sun, 12 Nov 2023 16:26:43 +0000 Subject: [PATCH 12/12] types: adjust `channel` --- packages/discord.js/src/util/Util.js | 2 +- packages/discord.js/typings/index.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/discord.js/src/util/Util.js b/packages/discord.js/src/util/Util.js index 748a1f9b99c1..0f8ff0a3cee8 100644 --- a/packages/discord.js/src/util/Util.js +++ b/packages/discord.js/src/util/Util.js @@ -414,7 +414,7 @@ function parseWebhookURL(url) { * @typedef {Object} SupportingInteractionResolvedData * @property {Client} client The client * @property {Guild} [guild] A guild - * @property {BaseChannel} [channel] A channel + * @property {GuildTextBasedChannel} [channel] A channel * @private */ diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 50c419bd25f8..8265c709e702 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -6368,7 +6368,7 @@ export interface StageInstanceEditOptions { export interface SupportingInteractionResolvedData { client: Client; guild?: Guild; - channel?: Channel; + channel?: GuildTextBasedChannel; } export type SweeperKey = keyof SweeperDefinitions;