mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat: new select menus (#8793)
* feat(builders): new select menus * chore: better re-exporting of deprecated classes * feat: new select menus * chore: typings * chore: add missing todo comment * chore: finish updating tests * chore: add runtime deprecation warnings * chore: format deprecation warning * feat(BaseInteraction): isAnySelectMenu * chore: requested changes * fix: deprecation comments * chore: update @deprecated comments in typings * chore: add tests for select menu type narrowing * fix: bad auto imports Co-authored-by: Julian Vennen <julian@aternos.org> * fix: properly handle resolved members * fix: collectors * chore: suggested changes Co-authored-by: Almeida <almeidx@pm.me> * fix(typings): bad class extends * feat(ChannelSelectMenuBuilder): validation * chore: update todo comment * refactor(ChannelSelectMenu): better handling of channel_types state * chore: style nit * chore: suggested nits Co-authored-by: Aura Román <kyradiscord@gmail.com> Co-authored-by: Julian Vennen <julian@aternos.org> Co-authored-by: Almeida <almeidx@pm.me> Co-authored-by: Aura Román <kyradiscord@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -9,8 +9,8 @@ import {
|
|||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
createComponentBuilder,
|
createComponentBuilder,
|
||||||
SelectMenuBuilder,
|
StringSelectMenuBuilder,
|
||||||
SelectMenuOptionBuilder,
|
StringSelectMenuOptionBuilder,
|
||||||
} from '../../src/index.js';
|
} from '../../src/index.js';
|
||||||
|
|
||||||
const rowWithButtonData: APIActionRowComponent<APIMessageActionRowComponent> = {
|
const rowWithButtonData: APIActionRowComponent<APIMessageActionRowComponent> = {
|
||||||
@@ -29,7 +29,7 @@ const rowWithSelectMenuData: APIActionRowComponent<APIMessageActionRowComponent>
|
|||||||
type: ComponentType.ActionRow,
|
type: ComponentType.ActionRow,
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
type: ComponentType.SelectMenu,
|
type: ComponentType.StringSelect,
|
||||||
custom_id: '1234',
|
custom_id: '1234',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@@ -73,7 +73,7 @@ describe('Action Row Components', () => {
|
|||||||
url: 'https://google.com',
|
url: 'https://google.com',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: ComponentType.SelectMenu,
|
type: ComponentType.StringSelect,
|
||||||
placeholder: 'test',
|
placeholder: 'test',
|
||||||
custom_id: 'test',
|
custom_id: 'test',
|
||||||
options: [
|
options: [
|
||||||
@@ -108,7 +108,7 @@ describe('Action Row Components', () => {
|
|||||||
type: ComponentType.ActionRow,
|
type: ComponentType.ActionRow,
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
type: ComponentType.SelectMenu,
|
type: ComponentType.StringSelect,
|
||||||
custom_id: '1234',
|
custom_id: '1234',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@@ -134,17 +134,17 @@ describe('Action Row Components', () => {
|
|||||||
|
|
||||||
test('GIVEN valid builder options THEN valid JSON output is given 2', () => {
|
test('GIVEN valid builder options THEN valid JSON output is given 2', () => {
|
||||||
const button = new ButtonBuilder().setLabel('test').setStyle(ButtonStyle.Primary).setCustomId('123');
|
const button = new ButtonBuilder().setLabel('test').setStyle(ButtonStyle.Primary).setCustomId('123');
|
||||||
const selectMenu = new SelectMenuBuilder()
|
const selectMenu = new StringSelectMenuBuilder()
|
||||||
.setCustomId('1234')
|
.setCustomId('1234')
|
||||||
.setMaxValues(10)
|
.setMaxValues(10)
|
||||||
.setMinValues(12)
|
.setMinValues(12)
|
||||||
.setOptions(
|
.setOptions(
|
||||||
new SelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
new StringSelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
||||||
new SelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
new StringSelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
||||||
)
|
)
|
||||||
.setOptions([
|
.setOptions([
|
||||||
new SelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
new StringSelectMenuOptionBuilder().setLabel('one').setValue('one'),
|
||||||
new SelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
new StringSelectMenuOptionBuilder().setLabel('two').setValue('two'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(new ActionRowBuilder().addComponents(button).toJSON()).toEqual(rowWithButtonData);
|
expect(new ActionRowBuilder().addComponents(button).toJSON()).toEqual(rowWithButtonData);
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ import {
|
|||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
createComponentBuilder,
|
createComponentBuilder,
|
||||||
SelectMenuBuilder,
|
StringSelectMenuBuilder,
|
||||||
TextInputBuilder,
|
TextInputBuilder,
|
||||||
} from '../../src/index.js';
|
} from '../../src/index.js';
|
||||||
|
|
||||||
describe('createComponentBuilder', () => {
|
describe('createComponentBuilder', () => {
|
||||||
test.each([ButtonBuilder, SelectMenuBuilder, TextInputBuilder])(
|
test.each([ButtonBuilder, StringSelectMenuBuilder, TextInputBuilder])(
|
||||||
'passing an instance of %j should return itself',
|
'passing an instance of %j should return itself',
|
||||||
(Builder) => {
|
(Builder) => {
|
||||||
const builder = new Builder();
|
const builder = new Builder();
|
||||||
@@ -45,14 +45,14 @@ describe('createComponentBuilder', () => {
|
|||||||
expect(createComponentBuilder(button)).toBeInstanceOf(ButtonBuilder);
|
expect(createComponentBuilder(button)).toBeInstanceOf(ButtonBuilder);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('GIVEN a select menu component THEN returns a SelectMenuBuilder', () => {
|
test('GIVEN a select menu component THEN returns a StringSelectMenuBuilder', () => {
|
||||||
const selectMenu: APISelectMenuComponent = {
|
const selectMenu: APISelectMenuComponent = {
|
||||||
custom_id: 'abc',
|
custom_id: 'abc',
|
||||||
options: [],
|
options: [],
|
||||||
type: ComponentType.SelectMenu,
|
type: ComponentType.StringSelect,
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(createComponentBuilder(selectMenu)).toBeInstanceOf(SelectMenuBuilder);
|
expect(createComponentBuilder(selectMenu)).toBeInstanceOf(StringSelectMenuBuilder);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('GIVEN a text input component THEN returns a TextInputBuilder', () => {
|
test('GIVEN a text input component THEN returns a TextInputBuilder', () => {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ComponentType, type APISelectMenuComponent, type APISelectMenuOption } from 'discord-api-types/v10';
|
import { ComponentType, type APISelectMenuComponent, type APISelectMenuOption } from 'discord-api-types/v10';
|
||||||
import { describe, test, expect } from 'vitest';
|
import { describe, test, expect } from 'vitest';
|
||||||
import { SelectMenuBuilder, SelectMenuOptionBuilder } from '../../src/index.js';
|
import { StringSelectMenuBuilder, StringSelectMenuOptionBuilder } from '../../src/index.js';
|
||||||
|
|
||||||
const selectMenu = () => new SelectMenuBuilder();
|
const selectMenu = () => new StringSelectMenuBuilder();
|
||||||
const selectMenuOption = () => new SelectMenuOptionBuilder();
|
const selectMenuOption = () => new StringSelectMenuOptionBuilder();
|
||||||
|
|
||||||
const longStr = 'a'.repeat(256);
|
const longStr = 'a'.repeat(256);
|
||||||
|
|
||||||
@@ -165,16 +165,16 @@ describe('Select Menu Components', () => {
|
|||||||
|
|
||||||
test('GIVEN valid JSON input THEN valid JSON history is correct', () => {
|
test('GIVEN valid JSON input THEN valid JSON history is correct', () => {
|
||||||
expect(
|
expect(
|
||||||
new SelectMenuBuilder(selectMenuDataWithoutOptions)
|
new StringSelectMenuBuilder(selectMenuDataWithoutOptions)
|
||||||
.addOptions(new SelectMenuOptionBuilder(selectMenuOptionData))
|
.addOptions(new StringSelectMenuOptionBuilder(selectMenuOptionData))
|
||||||
.toJSON(),
|
.toJSON(),
|
||||||
).toEqual(selectMenuData);
|
).toEqual(selectMenuData);
|
||||||
expect(
|
expect(
|
||||||
new SelectMenuBuilder(selectMenuDataWithoutOptions)
|
new StringSelectMenuBuilder(selectMenuDataWithoutOptions)
|
||||||
.addOptions([new SelectMenuOptionBuilder(selectMenuOptionData)])
|
.addOptions([new StringSelectMenuOptionBuilder(selectMenuOptionData)])
|
||||||
.toJSON(),
|
.toJSON(),
|
||||||
).toEqual(selectMenuData);
|
).toEqual(selectMenuData);
|
||||||
expect(new SelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData);
|
expect(new StringSelectMenuOptionBuilder(selectMenuOptionData).toJSON()).toEqual(selectMenuOptionData);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/util": "workspace:^",
|
"@discordjs/util": "workspace:^",
|
||||||
"@sapphire/shapeshift": "^3.7.0",
|
"@sapphire/shapeshift": "^3.7.0",
|
||||||
"discord-api-types": "^0.37.14",
|
"discord-api-types": "^0.37.15",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"ts-mixer": "^6.0.1",
|
"ts-mixer": "^6.0.1",
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
|
|||||||
@@ -11,14 +11,24 @@ import { normalizeArray, type RestOrArray } from '../util/normalizeArray.js';
|
|||||||
import { ComponentBuilder } from './Component.js';
|
import { ComponentBuilder } from './Component.js';
|
||||||
import { createComponentBuilder } from './Components.js';
|
import { createComponentBuilder } from './Components.js';
|
||||||
import type { ButtonBuilder } from './button/Button.js';
|
import type { ButtonBuilder } from './button/Button.js';
|
||||||
import type { SelectMenuBuilder } from './selectMenu/SelectMenu.js';
|
import type { ChannelSelectMenuBuilder } from './selectMenu/ChannelSelectMenu.js';
|
||||||
|
import type { MentionableSelectMenuBuilder } from './selectMenu/MentionableSelectMenu.js';
|
||||||
|
import type { RoleSelectMenuBuilder } from './selectMenu/RoleSelectMenu.js';
|
||||||
|
import type { StringSelectMenuBuilder } from './selectMenu/StringSelectMenu.js';
|
||||||
|
import type { UserSelectMenuBuilder } from './selectMenu/UserSelectMenu.js';
|
||||||
import type { TextInputBuilder } from './textInput/TextInput.js';
|
import type { TextInputBuilder } from './textInput/TextInput.js';
|
||||||
|
|
||||||
export type MessageComponentBuilder =
|
export type MessageComponentBuilder =
|
||||||
| ActionRowBuilder<MessageActionRowComponentBuilder>
|
| ActionRowBuilder<MessageActionRowComponentBuilder>
|
||||||
| MessageActionRowComponentBuilder;
|
| MessageActionRowComponentBuilder;
|
||||||
export type ModalComponentBuilder = ActionRowBuilder<ModalActionRowComponentBuilder> | ModalActionRowComponentBuilder;
|
export type ModalComponentBuilder = ActionRowBuilder<ModalActionRowComponentBuilder> | ModalActionRowComponentBuilder;
|
||||||
export type MessageActionRowComponentBuilder = ButtonBuilder | SelectMenuBuilder;
|
export type MessageActionRowComponentBuilder =
|
||||||
|
| ButtonBuilder
|
||||||
|
| ChannelSelectMenuBuilder
|
||||||
|
| MentionableSelectMenuBuilder
|
||||||
|
| RoleSelectMenuBuilder
|
||||||
|
| StringSelectMenuBuilder
|
||||||
|
| UserSelectMenuBuilder;
|
||||||
export type ModalActionRowComponentBuilder = TextInputBuilder;
|
export type ModalActionRowComponentBuilder = TextInputBuilder;
|
||||||
export type AnyComponentBuilder = MessageActionRowComponentBuilder | ModalActionRowComponentBuilder;
|
export type AnyComponentBuilder = MessageActionRowComponentBuilder | ModalActionRowComponentBuilder;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { s } from '@sapphire/shapeshift';
|
import { s } from '@sapphire/shapeshift';
|
||||||
import { ButtonStyle, type APIMessageComponentEmoji } from 'discord-api-types/v10';
|
import { ButtonStyle, ChannelType, type APIMessageComponentEmoji } from 'discord-api-types/v10';
|
||||||
import { isValidationEnabled } from '../util/validation.js';
|
import { isValidationEnabled } from '../util/validation.js';
|
||||||
import { SelectMenuOptionBuilder } from './selectMenu/SelectMenuOption.js';
|
import { StringSelectMenuOptionBuilder } from './selectMenu/StringSelectMenuOption.js';
|
||||||
|
|
||||||
export const customIdValidator = s.string
|
export const customIdValidator = s.string
|
||||||
.lengthGreaterThanOrEqual(1)
|
.lengthGreaterThanOrEqual(1)
|
||||||
@@ -46,7 +46,7 @@ export const jsonOptionValidator = s
|
|||||||
})
|
})
|
||||||
.setValidationEnabled(isValidationEnabled);
|
.setValidationEnabled(isValidationEnabled);
|
||||||
|
|
||||||
export const optionValidator = s.instance(SelectMenuOptionBuilder).setValidationEnabled(isValidationEnabled);
|
export const optionValidator = s.instance(StringSelectMenuOptionBuilder).setValidationEnabled(isValidationEnabled);
|
||||||
|
|
||||||
export const optionsValidator = optionValidator.array
|
export const optionsValidator = optionValidator.array
|
||||||
.lengthGreaterThanOrEqual(0)
|
.lengthGreaterThanOrEqual(0)
|
||||||
@@ -56,7 +56,7 @@ export const optionsLengthValidator = s.number.int
|
|||||||
.lessThanOrEqual(25)
|
.lessThanOrEqual(25)
|
||||||
.setValidationEnabled(isValidationEnabled);
|
.setValidationEnabled(isValidationEnabled);
|
||||||
|
|
||||||
export function validateRequiredSelectMenuParameters(options: SelectMenuOptionBuilder[], customId?: string) {
|
export function validateRequiredSelectMenuParameters(options: StringSelectMenuOptionBuilder[], customId?: string) {
|
||||||
customIdValidator.parse(customId);
|
customIdValidator.parse(customId);
|
||||||
optionsValidator.parse(options);
|
optionsValidator.parse(options);
|
||||||
}
|
}
|
||||||
@@ -68,6 +68,8 @@ export function validateRequiredSelectMenuOptionParameters(label?: string, value
|
|||||||
labelValueDescriptionValidator.parse(value);
|
labelValueDescriptionValidator.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const channelTypesValidator = s.nativeEnum(ChannelType).array.setValidationEnabled(isValidationEnabled);
|
||||||
|
|
||||||
export const urlValidator = s.string
|
export const urlValidator = s.string
|
||||||
.url({
|
.url({
|
||||||
allowedProtocols: ['http:', 'https:', 'discord:'],
|
allowedProtocols: ['http:', 'https:', 'discord:'],
|
||||||
|
|||||||
@@ -7,14 +7,22 @@ import {
|
|||||||
} from './ActionRow.js';
|
} from './ActionRow.js';
|
||||||
import { ComponentBuilder } from './Component.js';
|
import { ComponentBuilder } from './Component.js';
|
||||||
import { ButtonBuilder } from './button/Button.js';
|
import { ButtonBuilder } from './button/Button.js';
|
||||||
import { SelectMenuBuilder } from './selectMenu/SelectMenu.js';
|
import { ChannelSelectMenuBuilder } from './selectMenu/ChannelSelectMenu.js';
|
||||||
|
import { MentionableSelectMenuBuilder } from './selectMenu/MentionableSelectMenu.js';
|
||||||
|
import { RoleSelectMenuBuilder } from './selectMenu/RoleSelectMenu.js';
|
||||||
|
import { StringSelectMenuBuilder } from './selectMenu/StringSelectMenu.js';
|
||||||
|
import { UserSelectMenuBuilder } from './selectMenu/UserSelectMenu.js';
|
||||||
import { TextInputBuilder } from './textInput/TextInput.js';
|
import { TextInputBuilder } from './textInput/TextInput.js';
|
||||||
|
|
||||||
export interface MappedComponentTypes {
|
export interface MappedComponentTypes {
|
||||||
[ComponentType.ActionRow]: ActionRowBuilder<AnyComponentBuilder>;
|
[ComponentType.ActionRow]: ActionRowBuilder<AnyComponentBuilder>;
|
||||||
[ComponentType.Button]: ButtonBuilder;
|
[ComponentType.Button]: ButtonBuilder;
|
||||||
[ComponentType.SelectMenu]: SelectMenuBuilder;
|
[ComponentType.StringSelect]: StringSelectMenuBuilder;
|
||||||
[ComponentType.TextInput]: TextInputBuilder;
|
[ComponentType.TextInput]: TextInputBuilder;
|
||||||
|
[ComponentType.UserSelect]: UserSelectMenuBuilder;
|
||||||
|
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
|
||||||
|
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
|
||||||
|
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,10 +47,18 @@ export function createComponentBuilder(
|
|||||||
return new ActionRowBuilder(data);
|
return new ActionRowBuilder(data);
|
||||||
case ComponentType.Button:
|
case ComponentType.Button:
|
||||||
return new ButtonBuilder(data);
|
return new ButtonBuilder(data);
|
||||||
case ComponentType.SelectMenu:
|
case ComponentType.StringSelect:
|
||||||
return new SelectMenuBuilder(data);
|
return new StringSelectMenuBuilder(data);
|
||||||
case ComponentType.TextInput:
|
case ComponentType.TextInput:
|
||||||
return new TextInputBuilder(data);
|
return new TextInputBuilder(data);
|
||||||
|
case ComponentType.UserSelect:
|
||||||
|
return new UserSelectMenuBuilder(data);
|
||||||
|
case ComponentType.RoleSelect:
|
||||||
|
return new RoleSelectMenuBuilder(data);
|
||||||
|
case ComponentType.MentionableSelect:
|
||||||
|
return new MentionableSelectMenuBuilder(data);
|
||||||
|
case ComponentType.ChannelSelect:
|
||||||
|
return new ChannelSelectMenuBuilder(data);
|
||||||
default:
|
default:
|
||||||
// @ts-expect-error: This case can still occur if we get a newer unsupported component type
|
// @ts-expect-error: This case can still occur if we get a newer unsupported component type
|
||||||
throw new Error(`Cannot properly serialize component type: ${data.type}`);
|
throw new Error(`Cannot properly serialize component type: ${data.type}`);
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import type { APISelectMenuComponent } from 'discord-api-types/v10';
|
||||||
|
import { customIdValidator, disabledValidator, minMaxValidator, placeholderValidator } from '../Assertions.js';
|
||||||
|
import { ComponentBuilder } from '../Component.js';
|
||||||
|
|
||||||
|
export class BaseSelectMenuBuilder<
|
||||||
|
SelectMenuType extends APISelectMenuComponent,
|
||||||
|
> extends ComponentBuilder<SelectMenuType> {
|
||||||
|
/**
|
||||||
|
* Sets the placeholder for this select menu
|
||||||
|
*
|
||||||
|
* @param placeholder - The placeholder to use for this select menu
|
||||||
|
*/
|
||||||
|
public setPlaceholder(placeholder: string) {
|
||||||
|
this.data.placeholder = placeholderValidator.parse(placeholder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the minimum values that must be selected in the select menu
|
||||||
|
*
|
||||||
|
* @param minValues - The minimum values that must be selected
|
||||||
|
*/
|
||||||
|
public setMinValues(minValues: number) {
|
||||||
|
this.data.min_values = minMaxValidator.parse(minValues);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum values that must be selected in the select menu
|
||||||
|
*
|
||||||
|
* @param maxValues - The maximum values that must be selected
|
||||||
|
*/
|
||||||
|
public setMaxValues(maxValues: number) {
|
||||||
|
this.data.max_values = minMaxValidator.parse(maxValues);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the custom id for this select menu
|
||||||
|
*
|
||||||
|
* @param customId - The custom id to use for this select menu
|
||||||
|
*/
|
||||||
|
public setCustomId(customId: string) {
|
||||||
|
this.data.custom_id = customIdValidator.parse(customId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether this select menu is disabled
|
||||||
|
*
|
||||||
|
* @param disabled - Whether this select menu is disabled
|
||||||
|
*/
|
||||||
|
public setDisabled(disabled = true) {
|
||||||
|
this.data.disabled = disabledValidator.parse(disabled);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toJSON(): SelectMenuType {
|
||||||
|
customIdValidator.parse(this.data.custom_id);
|
||||||
|
return {
|
||||||
|
...this.data,
|
||||||
|
} as SelectMenuType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import type { APIChannelSelectComponent, ChannelType } from 'discord-api-types/v10';
|
||||||
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
|
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
||||||
|
import { channelTypesValidator, customIdValidator } from '../Assertions.js';
|
||||||
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSelectComponent> {
|
||||||
|
/**
|
||||||
|
* Creates a new select menu from API data
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this select menu with
|
||||||
|
* @example
|
||||||
|
* Creating a select menu from an API data object
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new ChannelSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* placeholder: 'select an option',
|
||||||
|
* max_values: 2,
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* Creating a select menu using setters and API data
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new ChannelSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* })
|
||||||
|
* .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
|
||||||
|
* .setMinValues(2)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public constructor(data?: Partial<APIChannelSelectComponent>) {
|
||||||
|
super({ ...data, type: ComponentType.ChannelSelect });
|
||||||
|
}
|
||||||
|
|
||||||
|
public addChannelTypes(...types: RestOrArray<ChannelType>) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
types = normalizeArray(types);
|
||||||
|
|
||||||
|
this.data.channel_types ??= [];
|
||||||
|
this.data.channel_types.push(...channelTypesValidator.parse(types));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setChannelTypes(...types: RestOrArray<ChannelType>) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
types = normalizeArray(types);
|
||||||
|
|
||||||
|
this.data.channel_types ??= [];
|
||||||
|
this.data.channel_types.splice(0, this.data.channel_types.length, ...channelTypesValidator.parse(types));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ComponentBuilder.toJSON}
|
||||||
|
*/
|
||||||
|
public override toJSON(): APIChannelSelectComponent {
|
||||||
|
customIdValidator.parse(this.data.custom_id);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...this.data,
|
||||||
|
} as APIChannelSelectComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import type { APIMentionableSelectComponent } from 'discord-api-types/v10';
|
||||||
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMentionableSelectComponent> {
|
||||||
|
/**
|
||||||
|
* Creates a new select menu from API data
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this select menu with
|
||||||
|
* @example
|
||||||
|
* Creating a select menu from an API data object
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new MentionableSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* placeholder: 'select an option',
|
||||||
|
* max_values: 2,
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* Creating a select menu using setters and API data
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new MentionableSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* })
|
||||||
|
* .setMinValues(1)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public constructor(data?: Partial<APIMentionableSelectComponent>) {
|
||||||
|
super({ ...data, type: ComponentType.MentionableSelect });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import type { APIRoleSelectComponent } from 'discord-api-types/v10';
|
||||||
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectComponent> {
|
||||||
|
/**
|
||||||
|
* Creates a new select menu from API data
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this select menu with
|
||||||
|
* @example
|
||||||
|
* Creating a select menu from an API data object
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new RoleSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* placeholder: 'select an option',
|
||||||
|
* max_values: 2,
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* Creating a select menu using setters and API data
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new RoleSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* })
|
||||||
|
* .setMinValues(1)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public constructor(data?: Partial<APIRoleSelectComponent>) {
|
||||||
|
super({ ...data, type: ComponentType.RoleSelect });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
import { ComponentType, type APISelectMenuComponent, type APISelectMenuOption } from 'discord-api-types/v10';
|
|
||||||
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
|
||||||
import {
|
|
||||||
customIdValidator,
|
|
||||||
disabledValidator,
|
|
||||||
jsonOptionValidator,
|
|
||||||
minMaxValidator,
|
|
||||||
optionsLengthValidator,
|
|
||||||
placeholderValidator,
|
|
||||||
validateRequiredSelectMenuParameters,
|
|
||||||
} from '../Assertions.js';
|
|
||||||
import { ComponentBuilder } from '../Component.js';
|
|
||||||
import { SelectMenuOptionBuilder } from './SelectMenuOption.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a select menu component
|
|
||||||
*/
|
|
||||||
export class SelectMenuBuilder extends ComponentBuilder<APISelectMenuComponent> {
|
|
||||||
/**
|
|
||||||
* The options within this select menu
|
|
||||||
*/
|
|
||||||
public readonly options: SelectMenuOptionBuilder[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new select menu from API data
|
|
||||||
*
|
|
||||||
* @param data - The API data to create this select menu with
|
|
||||||
* @example
|
|
||||||
* Creating a select menu from an API data object
|
|
||||||
* ```ts
|
|
||||||
* const selectMenu = new SelectMenuBuilder({
|
|
||||||
* custom_id: 'a cool select menu',
|
|
||||||
* placeholder: 'select an option',
|
|
||||||
* max_values: 2,
|
|
||||||
* options: [
|
|
||||||
* { label: 'option 1', value: '1' },
|
|
||||||
* { label: 'option 2', value: '2' },
|
|
||||||
* { label: 'option 3', value: '3' },
|
|
||||||
* ],
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
* @example
|
|
||||||
* Creating a select menu using setters and API data
|
|
||||||
* ```ts
|
|
||||||
* const selectMenu = new SelectMenuBuilder({
|
|
||||||
* custom_id: 'a cool select menu',
|
|
||||||
* })
|
|
||||||
* .setMinValues(1)
|
|
||||||
* .addOptions({
|
|
||||||
* label: 'Catchy',
|
|
||||||
* value: 'catch',
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
public constructor(data?: Partial<APISelectMenuComponent>) {
|
|
||||||
const { options, ...initData } = data ?? {};
|
|
||||||
super({ type: ComponentType.SelectMenu, ...initData });
|
|
||||||
this.options = options?.map((option) => new SelectMenuOptionBuilder(option)) ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the placeholder for this select menu
|
|
||||||
*
|
|
||||||
* @param placeholder - The placeholder to use for this select menu
|
|
||||||
*/
|
|
||||||
public setPlaceholder(placeholder: string) {
|
|
||||||
this.data.placeholder = placeholderValidator.parse(placeholder);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the minimum values that must be selected in the select menu
|
|
||||||
*
|
|
||||||
* @param minValues - The minimum values that must be selected
|
|
||||||
*/
|
|
||||||
public setMinValues(minValues: number) {
|
|
||||||
this.data.min_values = minMaxValidator.parse(minValues);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the maximum values that must be selected in the select menu
|
|
||||||
*
|
|
||||||
* @param maxValues - The maximum values that must be selected
|
|
||||||
*/
|
|
||||||
public setMaxValues(maxValues: number) {
|
|
||||||
this.data.max_values = minMaxValidator.parse(maxValues);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the custom id for this select menu
|
|
||||||
*
|
|
||||||
* @param customId - The custom id to use for this select menu
|
|
||||||
*/
|
|
||||||
public setCustomId(customId: string) {
|
|
||||||
this.data.custom_id = customIdValidator.parse(customId);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether this select menu is disabled
|
|
||||||
*
|
|
||||||
* @param disabled - Whether this select menu is disabled
|
|
||||||
*/
|
|
||||||
public setDisabled(disabled = true) {
|
|
||||||
this.data.disabled = disabledValidator.parse(disabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds options to this select menu
|
|
||||||
*
|
|
||||||
* @param options - The options to add to this select menu
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
public addOptions(...options: RestOrArray<APISelectMenuOption | SelectMenuOptionBuilder>) {
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
options = normalizeArray(options);
|
|
||||||
optionsLengthValidator.parse(this.options.length + options.length);
|
|
||||||
this.options.push(
|
|
||||||
...options.map((option) =>
|
|
||||||
option instanceof SelectMenuOptionBuilder
|
|
||||||
? option
|
|
||||||
: new SelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the options on this select menu
|
|
||||||
*
|
|
||||||
* @param options - The options to set on this select menu
|
|
||||||
*/
|
|
||||||
public setOptions(...options: RestOrArray<APISelectMenuOption | SelectMenuOptionBuilder>) {
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
options = normalizeArray(options);
|
|
||||||
optionsLengthValidator.parse(options.length);
|
|
||||||
this.options.splice(
|
|
||||||
0,
|
|
||||||
this.options.length,
|
|
||||||
...options.map((option) =>
|
|
||||||
option instanceof SelectMenuOptionBuilder
|
|
||||||
? option
|
|
||||||
: new SelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc ComponentBuilder.toJSON}
|
|
||||||
*/
|
|
||||||
public toJSON(): APISelectMenuComponent {
|
|
||||||
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...this.data,
|
|
||||||
options: this.options.map((option) => option.toJSON()),
|
|
||||||
} as APISelectMenuComponent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
106
packages/builders/src/components/selectMenu/StringSelectMenu.ts
Normal file
106
packages/builders/src/components/selectMenu/StringSelectMenu.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import type { APIStringSelectComponent } from 'discord-api-types/v10';
|
||||||
|
import { ComponentType, type APISelectMenuOption } from 'discord-api-types/v10';
|
||||||
|
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
||||||
|
import { jsonOptionValidator, optionsLengthValidator, validateRequiredSelectMenuParameters } from '../Assertions.js';
|
||||||
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
import { StringSelectMenuOptionBuilder } from './StringSelectMenuOption.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a string select menu component
|
||||||
|
*/
|
||||||
|
export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSelectComponent> {
|
||||||
|
/**
|
||||||
|
* The options within this select menu
|
||||||
|
*/
|
||||||
|
public readonly options: StringSelectMenuOptionBuilder[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu from API data
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this select menu with
|
||||||
|
* @example
|
||||||
|
* Creating a select menu from an API data object
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new StringSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* placeholder: 'select an option',
|
||||||
|
* max_values: 2,
|
||||||
|
* options: [
|
||||||
|
* { label: 'option 1', value: '1' },
|
||||||
|
* { label: 'option 2', value: '2' },
|
||||||
|
* { label: 'option 3', value: '3' },
|
||||||
|
* ],
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* Creating a select menu using setters and API data
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new StringSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* })
|
||||||
|
* .setMinValues(1)
|
||||||
|
* .addOptions({
|
||||||
|
* label: 'Catchy',
|
||||||
|
* value: 'catch',
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public constructor(data?: Partial<APIStringSelectComponent>) {
|
||||||
|
const { options, ...initData } = data ?? {};
|
||||||
|
super({ ...initData, type: ComponentType.StringSelect });
|
||||||
|
this.options = options?.map((option: APISelectMenuOption) => new StringSelectMenuOptionBuilder(option)) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds options to this select menu
|
||||||
|
*
|
||||||
|
* @param options - The options to add to this select menu
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public addOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
options = normalizeArray(options);
|
||||||
|
optionsLengthValidator.parse(this.options.length + options.length);
|
||||||
|
this.options.push(
|
||||||
|
...options.map((option) =>
|
||||||
|
option instanceof StringSelectMenuOptionBuilder
|
||||||
|
? option
|
||||||
|
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the options on this select menu
|
||||||
|
*
|
||||||
|
* @param options - The options to set on this select menu
|
||||||
|
*/
|
||||||
|
public setOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
options = normalizeArray(options);
|
||||||
|
optionsLengthValidator.parse(options.length);
|
||||||
|
this.options.splice(
|
||||||
|
0,
|
||||||
|
this.options.length,
|
||||||
|
...options.map((option) =>
|
||||||
|
option instanceof StringSelectMenuOptionBuilder
|
||||||
|
? option
|
||||||
|
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ComponentBuilder.toJSON}
|
||||||
|
*/
|
||||||
|
public override toJSON(): APIStringSelectComponent {
|
||||||
|
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...this.data,
|
||||||
|
options: this.options.map((option) => option.toJSON()),
|
||||||
|
} as APIStringSelectComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,15 +8,15 @@ import {
|
|||||||
} from '../Assertions.js';
|
} from '../Assertions.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a option within a select menu component
|
* Represents an option within a string select menu component
|
||||||
*/
|
*/
|
||||||
export class SelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOption> {
|
export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOption> {
|
||||||
/**
|
/**
|
||||||
* Creates a new select menu option from API data
|
* Creates a new string select menu option from API data
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this select menu option with
|
* @param data - The API data to create this string select menu option with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu option from an API data object
|
* Creating a string select menu option from an API data object
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenuOption = new SelectMenuOptionBuilder({
|
* const selectMenuOption = new SelectMenuOptionBuilder({
|
||||||
* label: 'catchy label',
|
* label: 'catchy label',
|
||||||
@@ -24,7 +24,7 @@ export class SelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOptio
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu option using setters and API data
|
* Creating a string select menu option using setters and API data
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenuOption = new SelectMenuOptionBuilder({
|
* const selectMenuOption = new SelectMenuOptionBuilder({
|
||||||
* default: true,
|
* default: true,
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import type { APIUserSelectComponent } from 'discord-api-types/v10';
|
||||||
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
export class UserSelectMenuBuilder extends BaseSelectMenuBuilder<APIUserSelectComponent> {
|
||||||
|
/**
|
||||||
|
* Creates a new select menu from API data
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this select menu with
|
||||||
|
* @example
|
||||||
|
* Creating a select menu from an API data object
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new UserSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* placeholder: 'select an option',
|
||||||
|
* max_values: 2,
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* Creating a select menu using setters and API data
|
||||||
|
* ```ts
|
||||||
|
* const selectMenu = new UserSelectMenuBuilder({
|
||||||
|
* custom_id: 'a cool select menu',
|
||||||
|
* })
|
||||||
|
* .setMinValues(1)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public constructor(data?: Partial<APIUserSelectComponent>) {
|
||||||
|
super({ ...data, type: ComponentType.UserSelect });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,8 +11,27 @@ export * from './components/textInput/TextInput.js';
|
|||||||
export * as TextInputAssertions from './components/textInput/Assertions.js';
|
export * as TextInputAssertions from './components/textInput/Assertions.js';
|
||||||
export * from './interactions/modals/Modal.js';
|
export * from './interactions/modals/Modal.js';
|
||||||
export * as ModalAssertions from './interactions/modals/Assertions.js';
|
export * as ModalAssertions from './interactions/modals/Assertions.js';
|
||||||
export * from './components/selectMenu/SelectMenu.js';
|
|
||||||
export * from './components/selectMenu/SelectMenuOption.js';
|
export * from './components/selectMenu/BaseSelectMenu.js';
|
||||||
|
export * from './components/selectMenu/ChannelSelectMenu.js';
|
||||||
|
export * from './components/selectMenu/MentionableSelectMenu.js';
|
||||||
|
export * from './components/selectMenu/RoleSelectMenu.js';
|
||||||
|
export * from './components/selectMenu/StringSelectMenu.js';
|
||||||
|
// TODO: Remove those aliases in v2
|
||||||
|
export {
|
||||||
|
/**
|
||||||
|
* @deprecated Will be removed in the next major version, use {@link StringSelectMenuBuilder} instead.
|
||||||
|
*/
|
||||||
|
StringSelectMenuBuilder as SelectMenuBuilder,
|
||||||
|
} from './components/selectMenu/StringSelectMenu.js';
|
||||||
|
export {
|
||||||
|
/**
|
||||||
|
* @deprecated Will be removed in the next major version, use {@link StringSelectMenuOptionBuilder} instead.
|
||||||
|
*/
|
||||||
|
StringSelectMenuOptionBuilder as SelectMenuOptionBuilder,
|
||||||
|
} from './components/selectMenu/StringSelectMenuOption.js';
|
||||||
|
export * from './components/selectMenu/StringSelectMenuOption.js';
|
||||||
|
export * from './components/selectMenu/UserSelectMenu.js';
|
||||||
|
|
||||||
export * as SlashCommandAssertions from './interactions/slashCommands/Assertions.js';
|
export * as SlashCommandAssertions from './interactions/slashCommands/Assertions.js';
|
||||||
export * from './interactions/slashCommands/SlashCommandBuilder.js';
|
export * from './interactions/slashCommands/SlashCommandBuilder.js';
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
"@discordjs/util": "workspace:^",
|
"@discordjs/util": "workspace:^",
|
||||||
"@sapphire/snowflake": "^3.2.2",
|
"@sapphire/snowflake": "^3.2.2",
|
||||||
"@types/ws": "^8.5.3",
|
"@types/ws": "^8.5.3",
|
||||||
"discord-api-types": "^0.37.14",
|
"discord-api-types": "^0.37.15",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"lodash.snakecase": "^4.1.1",
|
"lodash.snakecase": "^4.1.1",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
|
|||||||
@@ -4,11 +4,15 @@ const { InteractionType, ComponentType, ApplicationCommandType } = require('disc
|
|||||||
const Action = require('./Action');
|
const Action = require('./Action');
|
||||||
const AutocompleteInteraction = require('../../structures/AutocompleteInteraction');
|
const AutocompleteInteraction = require('../../structures/AutocompleteInteraction');
|
||||||
const ButtonInteraction = require('../../structures/ButtonInteraction');
|
const ButtonInteraction = require('../../structures/ButtonInteraction');
|
||||||
|
const ChannelSelectMenuInteraction = require('../../structures/ChannelSelectMenuInteraction');
|
||||||
const ChatInputCommandInteraction = require('../../structures/ChatInputCommandInteraction');
|
const ChatInputCommandInteraction = require('../../structures/ChatInputCommandInteraction');
|
||||||
|
const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction');
|
||||||
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
|
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
|
||||||
const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction');
|
const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction');
|
||||||
const SelectMenuInteraction = require('../../structures/SelectMenuInteraction');
|
const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction');
|
||||||
|
const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction');
|
||||||
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
|
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
|
||||||
|
const UserSelectMenuInteraction = require('../../structures/UserSelectMenuInteraction');
|
||||||
const Events = require('../../util/Events');
|
const Events = require('../../util/Events');
|
||||||
|
|
||||||
class InteractionCreateAction extends Action {
|
class InteractionCreateAction extends Action {
|
||||||
@@ -49,8 +53,20 @@ class InteractionCreateAction extends Action {
|
|||||||
case ComponentType.Button:
|
case ComponentType.Button:
|
||||||
InteractionClass = ButtonInteraction;
|
InteractionClass = ButtonInteraction;
|
||||||
break;
|
break;
|
||||||
case ComponentType.SelectMenu:
|
case ComponentType.StringSelect:
|
||||||
InteractionClass = SelectMenuInteraction;
|
InteractionClass = StringSelectMenuInteraction;
|
||||||
|
break;
|
||||||
|
case ComponentType.UserSelect:
|
||||||
|
InteractionClass = UserSelectMenuInteraction;
|
||||||
|
break;
|
||||||
|
case ComponentType.RoleSelect:
|
||||||
|
InteractionClass = RoleSelectMenuInteraction;
|
||||||
|
break;
|
||||||
|
case ComponentType.MentionableSelect:
|
||||||
|
InteractionClass = MentionableSelectMenuInteraction;
|
||||||
|
break;
|
||||||
|
case ComponentType.ChannelSelect:
|
||||||
|
InteractionClass = ChannelSelectMenuInteraction;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
client.emit(
|
client.emit(
|
||||||
|
|||||||
@@ -154,9 +154,27 @@ exports.ReactionEmoji = require('./structures/ReactionEmoji');
|
|||||||
exports.RichPresenceAssets = require('./structures/Presence').RichPresenceAssets;
|
exports.RichPresenceAssets = require('./structures/Presence').RichPresenceAssets;
|
||||||
exports.Role = require('./structures/Role').Role;
|
exports.Role = require('./structures/Role').Role;
|
||||||
exports.SelectMenuBuilder = require('./structures/SelectMenuBuilder');
|
exports.SelectMenuBuilder = require('./structures/SelectMenuBuilder');
|
||||||
|
exports.ChannelSelectMenuBuilder = require('./structures/ChannelSelectMenuBuilder');
|
||||||
|
exports.MentionableSelectMenuBuilder = require('./structures/MentionableSelectMenuBuilder');
|
||||||
|
exports.RoleSelectMenuBuilder = require('./structures/RoleSelectMenuBuilder');
|
||||||
|
exports.StringSelectMenuBuilder = require('./structures/StringSelectMenuBuilder');
|
||||||
|
exports.UserSelectMenuBuilder = require('./structures/UserSelectMenuBuilder');
|
||||||
|
exports.BaseSelectMenuComponent = require('./structures/BaseSelectMenuComponent');
|
||||||
exports.SelectMenuComponent = require('./structures/SelectMenuComponent');
|
exports.SelectMenuComponent = require('./structures/SelectMenuComponent');
|
||||||
|
exports.ChannelSelectMenuComponent = require('./structures/ChannelSelectMenuComponent');
|
||||||
|
exports.MentionableSelectMenuComponent = require('./structures/MentionableSelectMenuComponent');
|
||||||
|
exports.RoleSelectMenuComponent = require('./structures/RoleSelectMenuComponent');
|
||||||
|
exports.StringSelectMenuComponent = require('./structures/StringSelectMenuComponent');
|
||||||
|
exports.UserSelectMenuComponent = require('./structures/UserSelectMenuComponent');
|
||||||
exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction');
|
exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction');
|
||||||
|
exports.ChannelSelectMenuInteraction = require('./structures/ChannelSelectMenuInteraction');
|
||||||
|
exports.MentionableSelectMenuInteraction = require('./structures/MentionableSelectMenuInteraction');
|
||||||
|
exports.MentionableSelectMenuInteraction = require('./structures/MentionableSelectMenuInteraction');
|
||||||
|
exports.RoleSelectMenuInteraction = require('./structures/RoleSelectMenuInteraction');
|
||||||
|
exports.StringSelectMenuInteraction = require('./structures/StringSelectMenuInteraction');
|
||||||
|
exports.UserSelectMenuInteraction = require('./structures/UserSelectMenuInteraction');
|
||||||
exports.SelectMenuOptionBuilder = require('./structures/SelectMenuOptionBuilder');
|
exports.SelectMenuOptionBuilder = require('./structures/SelectMenuOptionBuilder');
|
||||||
|
exports.StringSelectMenuOptionBuilder = require('./structures/StringSelectMenuOptionBuilder');
|
||||||
exports.StageChannel = require('./structures/StageChannel');
|
exports.StageChannel = require('./structures/StageChannel');
|
||||||
exports.StageInstance = require('./structures/StageInstance').StageInstance;
|
exports.StageInstance = require('./structures/StageInstance').StageInstance;
|
||||||
exports.Sticker = require('./structures/Sticker').Sticker;
|
exports.Sticker = require('./structures/Sticker').Sticker;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { deprecate } = require('node:util');
|
||||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||||
const { InteractionType, ApplicationCommandType, ComponentType } = require('discord-api-types/v10');
|
const { InteractionType, ApplicationCommandType, ComponentType } = require('discord-api-types/v10');
|
||||||
const Base = require('./Base');
|
const Base = require('./Base');
|
||||||
|
const { SelectMenuTypes } = require('../util/Constants');
|
||||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -268,12 +270,63 @@ class BaseInteraction extends Base {
|
|||||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.Button;
|
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.Button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Get rid of this in the next major
|
||||||
/**
|
/**
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction}.
|
* Indicates whether this interaction is a {@link StringSelectMenuInteraction}.
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link Interaction#isStringSelectMenu} instead
|
||||||
*/
|
*/
|
||||||
isSelectMenu() {
|
isSelectMenu() {
|
||||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.SelectMenu;
|
return this.isStringSelectMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a select menu of any known type.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isAnySelectMenu() {
|
||||||
|
return this.type === InteractionType.MessageComponent && SelectMenuTypes.includes(this.componentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a {@link StringSelectMenuInteraction}.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isStringSelectMenu() {
|
||||||
|
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.StringSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a {@link UserSelectMenuInteraction}
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isUserSelectMenu() {
|
||||||
|
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.UserSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a {@link RoleSelectMenuInteraction}
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isRoleSelectMenu() {
|
||||||
|
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.RoleSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a {@link ChannelSelectMenuInteraction}
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isChannelSelectMenu() {
|
||||||
|
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.ChannelSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a {@link MenionableSelectMenuInteraction}
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isMentionableSelectMenu() {
|
||||||
|
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.MentionableSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,4 +338,9 @@ class BaseInteraction extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseInteraction.prototype.isSelectMenu = deprecate(
|
||||||
|
BaseInteraction.prototype.isSelectMenu,
|
||||||
|
'BaseInteraction#isSelectMenu() is deprecated. Use BaseInteraction#isStringSelectMenu() instead.',
|
||||||
|
);
|
||||||
|
|
||||||
module.exports = BaseInteraction;
|
module.exports = BaseInteraction;
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Component = require('./Component');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a select menu component
|
||||||
|
* @extends {Component}
|
||||||
|
*/
|
||||||
|
class BaseSelectMenuComponent extends Component {
|
||||||
|
/**
|
||||||
|
* The placeholder for this select menu
|
||||||
|
* @type {?string}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get placeholder() {
|
||||||
|
return this.data.placeholder ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum amount of options that can be selected
|
||||||
|
* @type {?number}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get maxValues() {
|
||||||
|
return this.data.max_values ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount of options that must be selected
|
||||||
|
* @type {?number}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get minValues() {
|
||||||
|
return this.data.min_values ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The custom id of this select menu
|
||||||
|
* @type {string}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get customId() {
|
||||||
|
return this.data.custom_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this select menu is disabled
|
||||||
|
* @type {?boolean}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get disabled() {
|
||||||
|
return this.data.disabled ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BaseSelectMenuComponent;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { ChannelSelectMenuBuilder: BuildersChannelSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||||
|
const { toSnakeCase } = require('../util/Transformers');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to build select menu components to be sent through the API
|
||||||
|
* @extends {BuildersChannelSelectMenu}
|
||||||
|
*/
|
||||||
|
class ChannelSelectMenuBuilder extends BuildersChannelSelectMenu {
|
||||||
|
constructor(data = {}) {
|
||||||
|
super(toSnakeCase(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu builder from json data
|
||||||
|
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||||
|
* @returns {ChannelSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
static from(other) {
|
||||||
|
if (isJSONEncodable(other)) {
|
||||||
|
return new this(other.toJSON());
|
||||||
|
}
|
||||||
|
return new this(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ChannelSelectMenuBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external BuildersChannelSelectMenu
|
||||||
|
* @see {@link https://discord.js.org/#/docs/builders/main/class/ChannelSelectMenuBuilder}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a channel select menu component
|
||||||
|
* @extends {BaseSelectMenuComponent}
|
||||||
|
*/
|
||||||
|
class ChannelSelectMenuComponent extends BaseSelectMenuComponent {
|
||||||
|
/**
|
||||||
|
* The options in this select menu
|
||||||
|
* @type {?(ChannelType[])}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get channelTypes() {
|
||||||
|
return this.data.channel_types ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ChannelSelectMenuComponent;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a {@link ComponentType.ChannelSelect} select menu interaction.
|
||||||
|
* @extends {MessageComponentInteraction}
|
||||||
|
*/
|
||||||
|
class ChannelSelectMenuInteraction extends MessageComponentInteraction {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected channels
|
||||||
|
* @type {Collection<Snowflake, Channel|APIChannel>}
|
||||||
|
*/
|
||||||
|
this.channels = new Collection();
|
||||||
|
for (const channel of Object.values(data.data.resolved.channels)) {
|
||||||
|
this.channels.set(channel.id, this.client.channels._add(channel, this.guild) ?? channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ChannelSelectMenuInteraction;
|
||||||
@@ -147,10 +147,17 @@ class InteractionCollector extends Collector {
|
|||||||
* @event InteractionCollector#collect
|
* @event InteractionCollector#collect
|
||||||
* @param {BaseInteraction} interaction The interaction that was collected
|
* @param {BaseInteraction} interaction The interaction that was collected
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (this.interactionType && interaction.type !== this.interactionType) return null;
|
if (this.interactionType && interaction.type !== this.interactionType) return null;
|
||||||
if (this.componentType && interaction.componentType !== this.componentType) return null;
|
if (this.componentType && interaction.componentType !== this.componentType) return null;
|
||||||
if (this.messageId && interaction.message?.id !== this.messageId) return null;
|
if (this.messageId && interaction.message?.id !== this.messageId) return null;
|
||||||
if (this.messageInteractionId && interaction.message?.interaction?.id !== this.messageInteractionId) return null;
|
if (
|
||||||
|
this.messageInteractionId &&
|
||||||
|
interaction.message?.interaction?.id &&
|
||||||
|
interaction.message.interaction.id !== this.messageInteractionId
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (this.channelId && interaction.channelId !== this.channelId) return null;
|
if (this.channelId && interaction.channelId !== this.channelId) return null;
|
||||||
if (this.guildId && interaction.guildId !== this.guildId) return null;
|
if (this.guildId && interaction.guildId !== this.guildId) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { MentionableSelectMenuBuilder: BuildersMentionableSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||||
|
const { toSnakeCase } = require('../util/Transformers');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to build select menu components to be sent through the API
|
||||||
|
* @extends {BuildersMentionableSelectMenu}
|
||||||
|
*/
|
||||||
|
class MentionableSelectMenuBuilder extends BuildersMentionableSelectMenu {
|
||||||
|
constructor(data = {}) {
|
||||||
|
super(toSnakeCase(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu builder from json data
|
||||||
|
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||||
|
* @returns {MentionableSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
static from(other) {
|
||||||
|
if (isJSONEncodable(other)) {
|
||||||
|
return new this(other.toJSON());
|
||||||
|
}
|
||||||
|
return new this(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = MentionableSelectMenuBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external BuildersMentionableSelectMenu
|
||||||
|
* @see {@link https://discord.js.org/#/docs/builders/main/class/MentionableSelectMenuBuilder}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a mentionable select menu component
|
||||||
|
* @extends {BaseSelectMenuComponent}
|
||||||
|
*/
|
||||||
|
class MentionableSelectMenuComponent extends BaseSelectMenuComponent {}
|
||||||
|
|
||||||
|
module.exports = MentionableSelectMenuComponent;
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||||
|
const Events = require('../util/Events');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a {@link ComponentType.MentionableSelect} select menu interaction.
|
||||||
|
* @extends {MessageComponentInteraction}
|
||||||
|
*/
|
||||||
|
class MentionableSelectMenuInteraction extends MessageComponentInteraction {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
|
||||||
|
const { members, users, roles } = data.data.resolved ?? {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected users
|
||||||
|
* @type {Collection<Snowflake, User>}
|
||||||
|
*/
|
||||||
|
this.users = new Collection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected users
|
||||||
|
* @type {Collection<Snowflake, GuildMember|APIGuildMember>}
|
||||||
|
*/
|
||||||
|
this.members = new Collection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected roles
|
||||||
|
* @type {Collection<Snowflake, Role|APIRole>}
|
||||||
|
*/
|
||||||
|
this.roles = new Collection();
|
||||||
|
|
||||||
|
if (members) {
|
||||||
|
for (const [id, member] of Object.entries(members)) {
|
||||||
|
const user = users[id];
|
||||||
|
if (!user) {
|
||||||
|
this.client.emit(
|
||||||
|
Events.Debug,
|
||||||
|
`[MentionableSelectMenuInteraction] Received a member without a user, skipping ${id}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.members.set(id, this.guild?.members._add({ user, ...member }) ?? { user, ...member });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (users) {
|
||||||
|
for (const user of Object.values(users)) {
|
||||||
|
this.users.set(user.id, this.client.users._add(user));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roles) {
|
||||||
|
for (const role of Object.values(roles)) {
|
||||||
|
this.roles.set(role.id, this.guild?.roles._add(role) ?? role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = MentionableSelectMenuInteraction;
|
||||||
33
packages/discord.js/src/structures/RoleSelectMenuBuilder.js
Normal file
33
packages/discord.js/src/structures/RoleSelectMenuBuilder.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { RoleSelectMenuBuilder: BuildersRoleSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||||
|
const { toSnakeCase } = require('../util/Transformers');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to build select menu components to be sent through the API
|
||||||
|
* @extends {BuildersRoleSelectMenu}
|
||||||
|
*/
|
||||||
|
class RoleSelectMenuBuilder extends BuildersRoleSelectMenu {
|
||||||
|
constructor(data = {}) {
|
||||||
|
super(toSnakeCase(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu builder from json data
|
||||||
|
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||||
|
* @returns {RoleSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
static from(other) {
|
||||||
|
if (isJSONEncodable(other)) {
|
||||||
|
return new this(other.toJSON());
|
||||||
|
}
|
||||||
|
return new this(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RoleSelectMenuBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external BuildersRoleSelectMenu
|
||||||
|
* @see {@link https://discord.js.org/#/docs/builders/main/class/RoleSelectMenuBuilder}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a role select menu component
|
||||||
|
* @extends {BaseSelectMenuComponent}
|
||||||
|
*/
|
||||||
|
class RoleSelectMenuComponent extends BaseSelectMenuComponent {}
|
||||||
|
|
||||||
|
module.exports = RoleSelectMenuComponent;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a {@link ComponentType.RoleSelect} select menu interaction.
|
||||||
|
* @extends {MessageComponentInteraction}
|
||||||
|
*/
|
||||||
|
class RoleSelectMenuInteraction extends MessageComponentInteraction {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected roles
|
||||||
|
* @type {Collection<Snowflake, Role|APIRole>}
|
||||||
|
*/
|
||||||
|
this.roles = new Collection();
|
||||||
|
for (const role of Object.values(data.data.resolved.roles)) {
|
||||||
|
this.roles.set(role.id, this.guild?.roles._add(role) ?? role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RoleSelectMenuInteraction;
|
||||||
@@ -1,78 +1,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { SelectMenuBuilder: BuildersSelectMenu, isJSONEncodable, normalizeArray } = require('@discordjs/builders');
|
const process = require('node:process');
|
||||||
const { toSnakeCase } = require('../util/Transformers');
|
const StringSelectMenuBuilder = require('./StringSelectMenuBuilder');
|
||||||
const { resolvePartialEmoji } = require('../util/Util');
|
|
||||||
|
let deprecationEmitted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to build select menu components to be sent through the API
|
* @deprecated Use {@link StringSelectMenuBuilder} instead.
|
||||||
* @extends {BuildersSelectMenu}
|
|
||||||
*/
|
*/
|
||||||
class SelectMenuBuilder extends BuildersSelectMenu {
|
class SelectMenuBuilder extends StringSelectMenuBuilder {
|
||||||
constructor({ options, ...data } = {}) {
|
constructor(...params) {
|
||||||
super(
|
super(...params);
|
||||||
toSnakeCase({
|
|
||||||
...data,
|
|
||||||
options: options?.map(({ emoji, ...option }) => ({
|
|
||||||
...option,
|
|
||||||
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
|
||||||
})),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (!deprecationEmitted) {
|
||||||
* Normalizes a select menu option emoji
|
process.emitWarning(
|
||||||
* @param {SelectMenuOptionData|JSONEncodable<APISelectMenuOption>} selectMenuOption The option to normalize
|
'The SelectMenuBuilder class is deprecated, use StringSelectMenuBuilder instead.',
|
||||||
* @returns {Array<SelectMenuOptionBuilder|APISelectMenuOption>}
|
'DeprecationWarning',
|
||||||
* @private
|
);
|
||||||
*/
|
deprecationEmitted = true;
|
||||||
static normalizeEmoji(selectMenuOption) {
|
|
||||||
if (isJSONEncodable(selectMenuOption)) {
|
|
||||||
return selectMenuOption;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { emoji, ...option } = selectMenuOption;
|
|
||||||
return {
|
|
||||||
...option,
|
|
||||||
emoji: typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds options to this select menu
|
|
||||||
* @param {RestOrArray<APISelectMenuOption>} options The options to add to this select menu
|
|
||||||
* @returns {SelectMenuBuilder}
|
|
||||||
*/
|
|
||||||
addOptions(...options) {
|
|
||||||
return super.addOptions(normalizeArray(options).map(option => SelectMenuBuilder.normalizeEmoji(option)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the options on this select menu
|
|
||||||
* @param {RestOrArray<APISelectMenuOption>} options The options to set on this select menu
|
|
||||||
* @returns {SelectMenuBuilder}
|
|
||||||
*/
|
|
||||||
setOptions(...options) {
|
|
||||||
return super.setOptions(normalizeArray(options).map(option => SelectMenuBuilder.normalizeEmoji(option)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new select menu builder from json data
|
|
||||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
|
||||||
* @returns {SelectMenuBuilder}
|
|
||||||
*/
|
|
||||||
static from(other) {
|
|
||||||
if (isJSONEncodable(other)) {
|
|
||||||
return new this(other.toJSON());
|
|
||||||
}
|
|
||||||
return new this(other);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SelectMenuBuilder;
|
module.exports = SelectMenuBuilder;
|
||||||
|
|
||||||
/**
|
|
||||||
* @external BuildersSelectMenu
|
|
||||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuBuilder}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -1,64 +1,24 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Component = require('./Component');
|
const process = require('node:process');
|
||||||
|
const StringSelectMenuComponent = require('./StringSelectMenuComponent');
|
||||||
|
|
||||||
|
let deprecationEmitted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a select menu component
|
* @deprecated Use {@link StringSelectMenuComponent} instead.
|
||||||
* @extends {Component}
|
|
||||||
*/
|
*/
|
||||||
class SelectMenuComponent extends Component {
|
class SelectMenuComponent extends StringSelectMenuComponent {
|
||||||
/**
|
constructor(...params) {
|
||||||
* The placeholder for this select menu
|
super(...params);
|
||||||
* @type {?string}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get placeholder() {
|
|
||||||
return this.data.placeholder ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (!deprecationEmitted) {
|
||||||
* The maximum amount of options that can be selected
|
process.emitWarning(
|
||||||
* @type {?number}
|
'The SelectMenuComponent class is deprecated, use StringSelectMenuComponent instead.',
|
||||||
* @readonly
|
'DeprecationWarning',
|
||||||
*/
|
);
|
||||||
get maxValues() {
|
deprecationEmitted = true;
|
||||||
return this.data.max_values ?? null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The minimum amount of options that must be selected
|
|
||||||
* @type {?number}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get minValues() {
|
|
||||||
return this.data.min_values ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The custom id of this select menu
|
|
||||||
* @type {string}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get customId() {
|
|
||||||
return this.data.custom_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether this select menu is disabled
|
|
||||||
* @type {?boolean}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get disabled() {
|
|
||||||
return this.data.disabled ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The options in this select menu
|
|
||||||
* @type {APISelectMenuOption[]}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
get options() {
|
|
||||||
return this.data.options;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
const process = require('node:process');
|
||||||
|
const StringSelectMenuInteraction = require('./StringSelectMenuInteraction');
|
||||||
|
|
||||||
|
let deprecationEmitted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a select menu interaction.
|
* @deprecated Use {@link StringSelectMenuInteraction} instead.
|
||||||
* @extends {MessageComponentInteraction}
|
|
||||||
*/
|
*/
|
||||||
class SelectMenuInteraction extends MessageComponentInteraction {
|
class SelectMenuInteraction extends StringSelectMenuInteraction {
|
||||||
constructor(client, data) {
|
constructor(...params) {
|
||||||
super(client, data);
|
super(...params);
|
||||||
|
|
||||||
/**
|
if (!deprecationEmitted) {
|
||||||
* The values selected, if the component which was interacted with was a select menu
|
process.emitWarning(
|
||||||
* @type {string[]}
|
'The SelectMenuInteraction class is deprecated, use StringSelectMenuInteraction instead.',
|
||||||
*/
|
'DeprecationWarning',
|
||||||
this.values = data.data.values ?? [];
|
);
|
||||||
|
deprecationEmitted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,50 +1,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { SelectMenuOptionBuilder: BuildersSelectMenuOption, isJSONEncodable } = require('@discordjs/builders');
|
const process = require('node:process');
|
||||||
const { toSnakeCase } = require('../util/Transformers');
|
const StringSelectMenuOptionBuilder = require('./StringSelectMenuOptionBuilder');
|
||||||
const { resolvePartialEmoji } = require('../util/Util');
|
|
||||||
|
let deprecationEmitted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a select menu option builder.
|
* @deprecated Use {@link StringSelectMenuOptionBuilder} instead.
|
||||||
* @extends {BuildersSelectMenuOption}
|
|
||||||
*/
|
*/
|
||||||
class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
class SelectMenuOptionBuilder extends StringSelectMenuOptionBuilder {
|
||||||
constructor({ emoji, ...data } = {}) {
|
constructor(...params) {
|
||||||
super(
|
super(...params);
|
||||||
toSnakeCase({
|
|
||||||
...data,
|
|
||||||
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Sets the emoji to display on this option
|
|
||||||
* @param {ComponentEmojiResolvable} emoji The emoji to display on this option
|
|
||||||
* @returns {SelectMenuOptionBuilder}
|
|
||||||
*/
|
|
||||||
setEmoji(emoji) {
|
|
||||||
if (typeof emoji === 'string') {
|
|
||||||
return super.setEmoji(resolvePartialEmoji(emoji));
|
|
||||||
}
|
|
||||||
return super.setEmoji(emoji);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (!deprecationEmitted) {
|
||||||
* Creates a new select menu option builder from JSON data
|
process.emitWarning(
|
||||||
* @param {JSONEncodable<APISelectMenuOption>|APISelectMenuOption} other The other data
|
'The SelectMenuOptionBuilder class is deprecated, use StringSelectMenuOptionBuilder instead.',
|
||||||
* @returns {SelectMenuOptionBuilder}
|
'DeprecationWarning',
|
||||||
*/
|
);
|
||||||
static from(other) {
|
deprecationEmitted = true;
|
||||||
if (isJSONEncodable(other)) {
|
|
||||||
return new this(other.toJSON());
|
|
||||||
}
|
}
|
||||||
return new this(other);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SelectMenuOptionBuilder;
|
module.exports = SelectMenuOptionBuilder;
|
||||||
|
|
||||||
/**
|
|
||||||
* @external BuildersSelectMenuOption
|
|
||||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuOptionBuilder}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { SelectMenuBuilder: BuildersSelectMenu, isJSONEncodable, normalizeArray } = require('@discordjs/builders');
|
||||||
|
const { toSnakeCase } = require('../util/Transformers');
|
||||||
|
const { resolvePartialEmoji } = require('../util/Util');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to build select menu components to be sent through the API
|
||||||
|
* @extends {BuildersSelectMenu}
|
||||||
|
*/
|
||||||
|
class StringSelectMenuBuilder extends BuildersSelectMenu {
|
||||||
|
constructor({ options, ...data } = {}) {
|
||||||
|
super(
|
||||||
|
toSnakeCase({
|
||||||
|
...data,
|
||||||
|
options: options?.map(({ emoji, ...option }) => ({
|
||||||
|
...option,
|
||||||
|
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a select menu option emoji
|
||||||
|
* @param {SelectMenuOptionData|JSONEncodable<APISelectMenuOption>} selectMenuOption The option to normalize
|
||||||
|
* @returns {SelectMenuOptionBuilder|APISelectMenuOption}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static normalizeEmoji(selectMenuOption) {
|
||||||
|
if (isJSONEncodable(selectMenuOption)) {
|
||||||
|
return selectMenuOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { emoji, ...option } = selectMenuOption;
|
||||||
|
return {
|
||||||
|
...option,
|
||||||
|
emoji: typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds options to this select menu
|
||||||
|
* @param {RestOrArray<APISelectMenuOption>} options The options to add to this select menu
|
||||||
|
* @returns {StringSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
addOptions(...options) {
|
||||||
|
return super.addOptions(normalizeArray(options).map(option => StringSelectMenuBuilder.normalizeEmoji(option)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the options on this select menu
|
||||||
|
* @param {RestOrArray<APISelectMenuOption>} options The options to set on this select menu
|
||||||
|
* @returns {StringSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
setOptions(...options) {
|
||||||
|
return super.setOptions(normalizeArray(options).map(option => StringSelectMenuBuilder.normalizeEmoji(option)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu builder from json data
|
||||||
|
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||||
|
* @returns {StringSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
static from(other) {
|
||||||
|
if (isJSONEncodable(other)) {
|
||||||
|
return new this(other.toJSON());
|
||||||
|
}
|
||||||
|
return new this(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = StringSelectMenuBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external BuildersSelectMenu
|
||||||
|
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuBuilder}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a string select menu component
|
||||||
|
* @extends {BaseSelectMenuComponent}
|
||||||
|
*/
|
||||||
|
class StringSelectMenuComponent extends BaseSelectMenuComponent {
|
||||||
|
/**
|
||||||
|
* The options in this select menu
|
||||||
|
* @type {APISelectMenuOption[]}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get options() {
|
||||||
|
return this.data.options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = StringSelectMenuComponent;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a {@link ComponentType.StringSelect} select menu interaction.
|
||||||
|
* @extends {MessageComponentInteraction}
|
||||||
|
*/
|
||||||
|
class StringSelectMenuInteraction extends MessageComponentInteraction {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The values selected
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
this.values = data.data.values ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = StringSelectMenuInteraction;
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { SelectMenuOptionBuilder: BuildersSelectMenuOption, isJSONEncodable } = require('@discordjs/builders');
|
||||||
|
const { toSnakeCase } = require('../util/Transformers');
|
||||||
|
const { resolvePartialEmoji } = require('../util/Util');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a select menu option builder.
|
||||||
|
* @extends {BuildersSelectMenuOption}
|
||||||
|
*/
|
||||||
|
class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
||||||
|
constructor({ emoji, ...data } = {}) {
|
||||||
|
super(
|
||||||
|
toSnakeCase({
|
||||||
|
...data,
|
||||||
|
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the emoji to display on this option
|
||||||
|
* @param {ComponentEmojiResolvable} emoji The emoji to display on this option
|
||||||
|
* @returns {StringSelectMenuOptionBuilder}
|
||||||
|
*/
|
||||||
|
setEmoji(emoji) {
|
||||||
|
if (typeof emoji === 'string') {
|
||||||
|
return super.setEmoji(resolvePartialEmoji(emoji));
|
||||||
|
}
|
||||||
|
return super.setEmoji(emoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu option builder from JSON data
|
||||||
|
* @param {JSONEncodable<APISelectMenuOption>|APISelectMenuOption} other The other data
|
||||||
|
* @returns {StringSelectMenuOptionBuilder}
|
||||||
|
*/
|
||||||
|
static from(other) {
|
||||||
|
if (isJSONEncodable(other)) {
|
||||||
|
return new this(other.toJSON());
|
||||||
|
}
|
||||||
|
return new this(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = StringSelectMenuOptionBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external BuildersSelectMenuOption
|
||||||
|
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuOptionBuilder}
|
||||||
|
*/
|
||||||
33
packages/discord.js/src/structures/UserSelectMenuBuilder.js
Normal file
33
packages/discord.js/src/structures/UserSelectMenuBuilder.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { UserSelectMenuBuilder: BuildersUserSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||||
|
const { toSnakeCase } = require('../util/Transformers');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to build select menu components to be sent through the API
|
||||||
|
* @extends {BuildersUserSelectMenu}
|
||||||
|
*/
|
||||||
|
class UserSelectMenuBuilder extends BuildersUserSelectMenu {
|
||||||
|
constructor(data = {}) {
|
||||||
|
super(toSnakeCase(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select menu builder from json data
|
||||||
|
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||||
|
* @returns {UserSelectMenuBuilder}
|
||||||
|
*/
|
||||||
|
static from(other) {
|
||||||
|
if (isJSONEncodable(other)) {
|
||||||
|
return new this(other.toJSON());
|
||||||
|
}
|
||||||
|
return new this(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UserSelectMenuBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external BuildersUserSelectMenu
|
||||||
|
* @see {@link https://discord.js.org/#/docs/builders/main/class/UserSelectMenuBuilder}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a user select menu component
|
||||||
|
* @extends {BaseSelectMenuComponent}
|
||||||
|
*/
|
||||||
|
class UserSelectMenuComponent extends BaseSelectMenuComponent {}
|
||||||
|
|
||||||
|
module.exports = UserSelectMenuComponent;
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||||
|
const Events = require('../util/Events');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a {@link ComponentType.UserSelect} select menu interaction.
|
||||||
|
* @extends {MessageComponentInteraction}
|
||||||
|
*/
|
||||||
|
class UserSelectMenuInteraction extends MessageComponentInteraction {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected users
|
||||||
|
* @type {Collection<Snowflake, User>}
|
||||||
|
*/
|
||||||
|
this.users = new Collection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the selected members
|
||||||
|
* @type {Collection<Snowflake, GuildMember|APIGuildMember>}
|
||||||
|
*/
|
||||||
|
this.members = new Collection();
|
||||||
|
|
||||||
|
for (const user of Object.values(data.data.resolved.users)) {
|
||||||
|
this.users.set(user.id, this.client.users._add(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.data.resolved.members) {
|
||||||
|
for (const [id, member] of Object.entries(data.data.resolved.members)) {
|
||||||
|
const user = data.data.resolved.users[id];
|
||||||
|
if (!user) {
|
||||||
|
this.client.emit(
|
||||||
|
Events.Debug,
|
||||||
|
`[UserSelectMenuInteraction] Received a member without a user, skipping ${id}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.members.set(id, this.guild?.members._add({ user, ...member }) ?? { user, ...member });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UserSelectMenuInteraction;
|
||||||
@@ -82,10 +82,18 @@ function createComponent(data) {
|
|||||||
return new ActionRow(data);
|
return new ActionRow(data);
|
||||||
case ComponentType.Button:
|
case ComponentType.Button:
|
||||||
return new ButtonComponent(data);
|
return new ButtonComponent(data);
|
||||||
case ComponentType.SelectMenu:
|
case ComponentType.StringSelect:
|
||||||
return new SelectMenuComponent(data);
|
return new StringSelectMenuComponent(data);
|
||||||
case ComponentType.TextInput:
|
case ComponentType.TextInput:
|
||||||
return new TextInputComponent(data);
|
return new TextInputComponent(data);
|
||||||
|
case ComponentType.UserSelect:
|
||||||
|
return new UserSelectMenuComponent(data);
|
||||||
|
case ComponentType.RoleSelect:
|
||||||
|
return new RoleSelectMenuComponent(data);
|
||||||
|
case ComponentType.MentionableSelect:
|
||||||
|
return new MentionableSelectMenuComponent(data);
|
||||||
|
case ComponentType.ChannelSelect:
|
||||||
|
return new ChannelSelectMenuComponent(data);
|
||||||
default:
|
default:
|
||||||
return new Component(data);
|
return new Component(data);
|
||||||
}
|
}
|
||||||
@@ -106,10 +114,18 @@ function createComponentBuilder(data) {
|
|||||||
return new ActionRowBuilder(data);
|
return new ActionRowBuilder(data);
|
||||||
case ComponentType.Button:
|
case ComponentType.Button:
|
||||||
return new ButtonBuilder(data);
|
return new ButtonBuilder(data);
|
||||||
case ComponentType.SelectMenu:
|
case ComponentType.StringSelect:
|
||||||
return new SelectMenuBuilder(data);
|
return new StringSelectMenuBuilder(data);
|
||||||
case ComponentType.TextInput:
|
case ComponentType.TextInput:
|
||||||
return new TextInputBuilder(data);
|
return new TextInputBuilder(data);
|
||||||
|
case ComponentType.UserSelect:
|
||||||
|
return new UserSelectMenuBuilder(data);
|
||||||
|
case ComponentType.RoleSelect:
|
||||||
|
return new RoleSelectMenuBuilder(data);
|
||||||
|
case ComponentType.MentionableSelect:
|
||||||
|
return new MentionableSelectMenuBuilder(data);
|
||||||
|
case ComponentType.ChannelSelect:
|
||||||
|
return new ChannelSelectMenuBuilder(data);
|
||||||
default:
|
default:
|
||||||
return new ComponentBuilder(data);
|
return new ComponentBuilder(data);
|
||||||
}
|
}
|
||||||
@@ -121,11 +137,19 @@ const ActionRow = require('../structures/ActionRow');
|
|||||||
const ActionRowBuilder = require('../structures/ActionRowBuilder');
|
const ActionRowBuilder = require('../structures/ActionRowBuilder');
|
||||||
const ButtonBuilder = require('../structures/ButtonBuilder');
|
const ButtonBuilder = require('../structures/ButtonBuilder');
|
||||||
const ButtonComponent = require('../structures/ButtonComponent');
|
const ButtonComponent = require('../structures/ButtonComponent');
|
||||||
|
const ChannelSelectMenuBuilder = require('../structures/ChannelSelectMenuBuilder');
|
||||||
|
const ChannelSelectMenuComponent = require('../structures/ChannelSelectMenuComponent');
|
||||||
const Component = require('../structures/Component');
|
const Component = require('../structures/Component');
|
||||||
const SelectMenuBuilder = require('../structures/SelectMenuBuilder');
|
const MentionableSelectMenuBuilder = require('../structures/MentionableSelectMenuBuilder');
|
||||||
const SelectMenuComponent = require('../structures/SelectMenuComponent');
|
const MentionableSelectMenuComponent = require('../structures/MentionableSelectMenuComponent');
|
||||||
|
const RoleSelectMenuBuilder = require('../structures/RoleSelectMenuBuilder');
|
||||||
|
const RoleSelectMenuComponent = require('../structures/RoleSelectMenuComponent');
|
||||||
|
const StringSelectMenuBuilder = require('../structures/StringSelectMenuBuilder');
|
||||||
|
const StringSelectMenuComponent = require('../structures/StringSelectMenuComponent');
|
||||||
const TextInputBuilder = require('../structures/TextInputBuilder');
|
const TextInputBuilder = require('../structures/TextInputBuilder');
|
||||||
const TextInputComponent = require('../structures/TextInputComponent');
|
const TextInputComponent = require('../structures/TextInputComponent');
|
||||||
|
const UserSelectMenuBuilder = require('../structures/UserSelectMenuBuilder');
|
||||||
|
const UserSelectMenuComponent = require('../structures/UserSelectMenuComponent');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @external JSONEncodable
|
* @external JSONEncodable
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { ChannelType, MessageType } = require('discord-api-types/v10');
|
const { ChannelType, MessageType, ComponentType } = require('discord-api-types/v10');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of an item to be swept in Sweepers
|
* The name of an item to be swept in Sweepers
|
||||||
@@ -113,6 +113,23 @@ exports.ThreadChannelTypes = [ChannelType.AnnouncementThread, ChannelType.Public
|
|||||||
*/
|
*/
|
||||||
exports.VoiceBasedChannelTypes = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
|
exports.VoiceBasedChannelTypes = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The types of select menus. The available types are:
|
||||||
|
* * {@link ComponentType.StringSelect}
|
||||||
|
* * {@link ComponentType.UserSelect}
|
||||||
|
* * {@link ComponentType.RoleSelect}
|
||||||
|
* * {@link ComponentType.MentionableSelect}
|
||||||
|
* * {@link ComponentType.ChannelSelect}
|
||||||
|
* @typedef {ComponentType[]} SelectMenuTypes
|
||||||
|
*/
|
||||||
|
exports.SelectMenuTypes = [
|
||||||
|
ComponentType.StringSelect,
|
||||||
|
ComponentType.UserSelect,
|
||||||
|
ComponentType.RoleSelect,
|
||||||
|
ComponentType.MentionableSelect,
|
||||||
|
ComponentType.ChannelSelect,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Constants Constants that can be used in an enum or object-like way.
|
* @typedef {Object} Constants Constants that can be used in an enum or object-like way.
|
||||||
* @property {SweeperKey[]} SweeperKeys The possible names of items that can be swept in sweepers
|
* @property {SweeperKey[]} SweeperKeys The possible names of items that can be swept in sweepers
|
||||||
@@ -120,4 +137,5 @@ exports.VoiceBasedChannelTypes = [ChannelType.GuildVoice, ChannelType.GuildStage
|
|||||||
* @property {TextBasedChannelTypes} TextBasedChannelTypes The types of channels that are text-based
|
* @property {TextBasedChannelTypes} TextBasedChannelTypes The types of channels that are text-based
|
||||||
* @property {ThreadChannelTypes} ThreadChannelTypes The types of channels that are threads
|
* @property {ThreadChannelTypes} ThreadChannelTypes The types of channels that are threads
|
||||||
* @property {VoiceBasedChannelTypes} VoiceBasedChannelTypes The types of channels that are voice-based
|
* @property {VoiceBasedChannelTypes} VoiceBasedChannelTypes The types of channels that are voice-based
|
||||||
|
* @property {SelectMenuTypes} SelectMenuTypes The types of components that are select menus.
|
||||||
*/
|
*/
|
||||||
|
|||||||
286
packages/discord.js/typings/index.d.ts
vendored
286
packages/discord.js/typings/index.d.ts
vendored
@@ -14,14 +14,17 @@ import {
|
|||||||
italic,
|
italic,
|
||||||
quote,
|
quote,
|
||||||
roleMention,
|
roleMention,
|
||||||
SelectMenuBuilder as BuilderSelectMenuComponent,
|
ChannelSelectMenuBuilder as BuilderChannelSelectMenuComponent,
|
||||||
|
MentionableSelectMenuBuilder as BuilderMentionableSelectMenuComponent,
|
||||||
|
RoleSelectMenuBuilder as BuilderRoleSelectMenuComponent,
|
||||||
|
StringSelectMenuBuilder as BuilderStringSelectMenuComponent,
|
||||||
|
UserSelectMenuBuilder as BuilderUserSelectMenuComponent,
|
||||||
TextInputBuilder as BuilderTextInputComponent,
|
TextInputBuilder as BuilderTextInputComponent,
|
||||||
SelectMenuOptionBuilder as BuildersSelectMenuOption,
|
SelectMenuOptionBuilder as BuildersSelectMenuOption,
|
||||||
spoiler,
|
spoiler,
|
||||||
strikethrough,
|
strikethrough,
|
||||||
time,
|
time,
|
||||||
TimestampStyles,
|
TimestampStyles,
|
||||||
TimestampStylesString,
|
|
||||||
underscore,
|
underscore,
|
||||||
userMention,
|
userMention,
|
||||||
ModalActionRowComponentBuilder,
|
ModalActionRowComponentBuilder,
|
||||||
@@ -35,7 +38,6 @@ import { Collection } from '@discordjs/collection';
|
|||||||
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
||||||
import {
|
import {
|
||||||
APIActionRowComponent,
|
APIActionRowComponent,
|
||||||
APIApplicationCommand,
|
|
||||||
APIApplicationCommandInteractionData,
|
APIApplicationCommandInteractionData,
|
||||||
APIApplicationCommandOption,
|
APIApplicationCommandOption,
|
||||||
APIAuditLogChange,
|
APIAuditLogChange,
|
||||||
@@ -126,6 +128,17 @@ import {
|
|||||||
TextChannelType,
|
TextChannelType,
|
||||||
ChannelFlags,
|
ChannelFlags,
|
||||||
SortOrderType,
|
SortOrderType,
|
||||||
|
APIMessageStringSelectInteractionData,
|
||||||
|
APIMessageUserSelectInteractionData,
|
||||||
|
APIStringSelectComponent,
|
||||||
|
APIUserSelectComponent,
|
||||||
|
APIRoleSelectComponent,
|
||||||
|
APIMentionableSelectComponent,
|
||||||
|
APIChannelSelectComponent,
|
||||||
|
APIGuildMember,
|
||||||
|
APIMessageRoleSelectInteractionData,
|
||||||
|
APIMessageMentionableSelectInteractionData,
|
||||||
|
APIMessageChannelSelectInteractionData,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import { ChildProcess } from 'node:child_process';
|
import { ChildProcess } from 'node:child_process';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
@@ -158,13 +171,11 @@ import {
|
|||||||
RawInviteData,
|
RawInviteData,
|
||||||
RawInviteGuildData,
|
RawInviteGuildData,
|
||||||
RawInviteStageInstance,
|
RawInviteStageInstance,
|
||||||
RawAttachmentData,
|
|
||||||
RawMessageButtonInteractionData,
|
RawMessageButtonInteractionData,
|
||||||
RawMessageComponentInteractionData,
|
RawMessageComponentInteractionData,
|
||||||
RawMessageData,
|
RawMessageData,
|
||||||
RawMessagePayloadData,
|
RawMessagePayloadData,
|
||||||
RawMessageReactionData,
|
RawMessageReactionData,
|
||||||
RawMessageSelectMenuInteractionData,
|
|
||||||
RawOAuth2GuildData,
|
RawOAuth2GuildData,
|
||||||
RawPartialGroupDMChannelData,
|
RawPartialGroupDMChannelData,
|
||||||
RawPartialMessageData,
|
RawPartialMessageData,
|
||||||
@@ -242,7 +253,11 @@ export interface BaseComponentData {
|
|||||||
export type MessageActionRowComponentData =
|
export type MessageActionRowComponentData =
|
||||||
| JSONEncodable<APIMessageActionRowComponent>
|
| JSONEncodable<APIMessageActionRowComponent>
|
||||||
| ButtonComponentData
|
| ButtonComponentData
|
||||||
| SelectMenuComponentData;
|
| StringSelectMenuComponentData
|
||||||
|
| UserSelectMenuComponentData
|
||||||
|
| RoleSelectMenuComponentData
|
||||||
|
| MentionableSelectMenuComponentData
|
||||||
|
| ChannelSelectMenuComponentData;
|
||||||
|
|
||||||
export type ModalActionRowComponentData = JSONEncodable<APIModalActionRowComponent> | TextInputComponentData;
|
export type ModalActionRowComponentData = JSONEncodable<APIModalActionRowComponent> | TextInputComponentData;
|
||||||
|
|
||||||
@@ -269,7 +284,13 @@ export class ActionRowBuilder<T extends AnyComponentBuilder = AnyComponentBuilde
|
|||||||
): ActionRowBuilder;
|
): ActionRowBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageActionRowComponent = ButtonComponent | SelectMenuComponent;
|
export type MessageActionRowComponent =
|
||||||
|
| ButtonComponent
|
||||||
|
| StringSelectMenuComponent
|
||||||
|
| UserSelectMenuComponent
|
||||||
|
| RoleSelectMenuComponent
|
||||||
|
| MentionableSelectMenuComponent
|
||||||
|
| ChannelSelectMenuComponent;
|
||||||
export type ModalActionRowComponent = TextInputComponent;
|
export type ModalActionRowComponent = TextInputComponent;
|
||||||
|
|
||||||
export class ActionRow<T extends MessageActionRowComponent | ModalActionRowComponent> extends Component<
|
export class ActionRow<T extends MessageActionRowComponent | ModalActionRowComponent> extends Component<
|
||||||
@@ -604,8 +625,8 @@ export class ButtonBuilder extends BuilderButtonComponent {
|
|||||||
public override setEmoji(emoji: ComponentEmojiResolvable): this;
|
public override setEmoji(emoji: ComponentEmojiResolvable): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectMenuBuilder extends BuilderSelectMenuComponent {
|
export class StringSelectMenuBuilder extends BuilderStringSelectMenuComponent {
|
||||||
public constructor(data?: Partial<SelectMenuComponentData | APISelectMenuComponent>);
|
public constructor(data?: Partial<StringSelectMenuComponentData | APIStringSelectComponent>);
|
||||||
private static normalizeEmoji(
|
private static normalizeEmoji(
|
||||||
selectMenuOption: JSONEncodable<APISelectMenuOption> | SelectMenuComponentOptionData,
|
selectMenuOption: JSONEncodable<APISelectMenuOption> | SelectMenuComponentOptionData,
|
||||||
): (APISelectMenuOption | SelectMenuOptionBuilder)[];
|
): (APISelectMenuOption | SelectMenuOptionBuilder)[];
|
||||||
@@ -615,7 +636,34 @@ export class SelectMenuBuilder extends BuilderSelectMenuComponent {
|
|||||||
public override setOptions(
|
public override setOptions(
|
||||||
...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
|
...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
|
||||||
): this;
|
): this;
|
||||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): SelectMenuBuilder;
|
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): StringSelectMenuBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
/** @deprecated Use {@link StringSelectMenuBuilder} instead */
|
||||||
|
StringSelectMenuBuilder as SelectMenuBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class UserSelectMenuBuilder extends BuilderUserSelectMenuComponent {
|
||||||
|
public constructor(data?: Partial<UserSelectMenuComponentData | APIUserSelectComponent>);
|
||||||
|
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): UserSelectMenuBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RoleSelectMenuBuilder extends BuilderRoleSelectMenuComponent {
|
||||||
|
public constructor(data?: Partial<RoleSelectMenuComponentData | APIRoleSelectComponent>);
|
||||||
|
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): RoleSelectMenuBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MentionableSelectMenuBuilder extends BuilderMentionableSelectMenuComponent {
|
||||||
|
public constructor(data?: Partial<MentionableSelectMenuComponentData | APIMentionableSelectComponent>);
|
||||||
|
public static from(
|
||||||
|
other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent,
|
||||||
|
): MentionableSelectMenuBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ChannelSelectMenuBuilder extends BuilderChannelSelectMenuComponent {
|
||||||
|
public constructor(data?: Partial<ChannelSelectMenuComponentData | APIChannelSelectComponent>);
|
||||||
|
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): ChannelSelectMenuBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
export class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
||||||
@@ -639,16 +687,34 @@ export class TextInputComponent extends Component<APITextInputComponent> {
|
|||||||
public get value(): string;
|
public get value(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectMenuComponent extends Component<APISelectMenuComponent> {
|
export class BaseSelectMenuComponent<Data extends APISelectMenuComponent> extends Component<Data> {
|
||||||
private constructor(data: APISelectMenuComponent);
|
protected constructor(data: Data);
|
||||||
public get placeholder(): string | null;
|
public get placeholder(): string | null;
|
||||||
public get maxValues(): number | null;
|
public get maxValues(): number | null;
|
||||||
public get minValues(): number | null;
|
public get minValues(): number | null;
|
||||||
public get customId(): string;
|
public get customId(): string;
|
||||||
public get disabled(): boolean | null;
|
public get disabled(): boolean | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class StringSelectMenuComponent extends BaseSelectMenuComponent<APIStringSelectComponent> {
|
||||||
public get options(): APISelectMenuOption[];
|
public get options(): APISelectMenuOption[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
/** @deprecated Use {@link StringSelectMenuComponent} instead */
|
||||||
|
StringSelectMenuComponent as SelectMenuComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class UserSelectMenuComponent extends BaseSelectMenuComponent<APIUserSelectComponent> {}
|
||||||
|
|
||||||
|
export class RoleSelectMenuComponent extends BaseSelectMenuComponent<APIRoleSelectComponent> {}
|
||||||
|
|
||||||
|
export class MentionableSelectMenuComponent extends BaseSelectMenuComponent<APIMentionableSelectComponent> {}
|
||||||
|
|
||||||
|
export class ChannelSelectMenuComponent extends BaseSelectMenuComponent<APIChannelSelectComponent> {
|
||||||
|
public getChannelTypes(): ChannelType[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface EmbedData {
|
export interface EmbedData {
|
||||||
title?: string;
|
title?: string;
|
||||||
type?: EmbedType;
|
type?: EmbedType;
|
||||||
@@ -1501,7 +1567,7 @@ export type Interaction<Cached extends CacheType = CacheType> =
|
|||||||
| ChatInputCommandInteraction<Cached>
|
| ChatInputCommandInteraction<Cached>
|
||||||
| MessageContextMenuCommandInteraction<Cached>
|
| MessageContextMenuCommandInteraction<Cached>
|
||||||
| UserContextMenuCommandInteraction<Cached>
|
| UserContextMenuCommandInteraction<Cached>
|
||||||
| SelectMenuInteraction<Cached>
|
| AnySelectMenuInteraction<Cached>
|
||||||
| ButtonInteraction<Cached>
|
| ButtonInteraction<Cached>
|
||||||
| AutocompleteInteraction<Cached>
|
| AutocompleteInteraction<Cached>
|
||||||
| ModalSubmitInteraction<Cached>;
|
| ModalSubmitInteraction<Cached>;
|
||||||
@@ -1550,7 +1616,14 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
|
|||||||
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>;
|
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>;
|
||||||
public isModalSubmit(): this is ModalSubmitInteraction<Cached>;
|
public isModalSubmit(): this is ModalSubmitInteraction<Cached>;
|
||||||
public isUserContextMenuCommand(): this is UserContextMenuCommandInteraction<Cached>;
|
public isUserContextMenuCommand(): this is UserContextMenuCommandInteraction<Cached>;
|
||||||
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
|
/** @deprecated Use {@link BaseInteraction#isStringSelectMenu} instead */
|
||||||
|
public isSelectMenu(): this is StringSelectMenuInteraction<Cached>;
|
||||||
|
public isAnySelectMenu(): this is AnySelectMenuInteraction<Cached>;
|
||||||
|
public isStringSelectMenu(): this is StringSelectMenuInteraction<Cached>;
|
||||||
|
public isUserSelectMenu(): this is UserSelectMenuInteraction<Cached>;
|
||||||
|
public isRoleSelectMenu(): this is RoleSelectMenuInteraction<Cached>;
|
||||||
|
public isMentionableSelectMenu(): this is MentionableSelectMenuInteraction<Cached>;
|
||||||
|
public isChannelSelectMenu(): this is ChannelSelectMenuInteraction<Cached>;
|
||||||
public isRepliable(): this is RepliableInteraction<Cached>;
|
public isRepliable(): this is RepliableInteraction<Cached>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1673,7 +1746,11 @@ export type AwaitMessageCollectorOptionsParams<T extends MessageComponentType, C
|
|||||||
|
|
||||||
export interface StringMappedInteractionTypes<Cached extends CacheType = CacheType> {
|
export interface StringMappedInteractionTypes<Cached extends CacheType = CacheType> {
|
||||||
Button: ButtonInteraction<Cached>;
|
Button: ButtonInteraction<Cached>;
|
||||||
SelectMenu: SelectMenuInteraction<Cached>;
|
StringSelectMenu: StringSelectMenuInteraction<Cached>;
|
||||||
|
UserSelectMenu: UserSelectMenuInteraction<Cached>;
|
||||||
|
RoleSelectMenu: RoleSelectMenuInteraction<Cached>;
|
||||||
|
MentionableSelectMenu: MentionableSelectMenuInteraction<Cached>;
|
||||||
|
ChannelSelectMenu: ChannelSelectMenuInteraction<Cached>;
|
||||||
ActionRow: MessageComponentInteraction<Cached>;
|
ActionRow: MessageComponentInteraction<Cached>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1681,7 +1758,11 @@ export type WrapBooleanCache<T extends boolean> = If<T, 'cached', CacheType>;
|
|||||||
|
|
||||||
export interface MappedInteractionTypes<Cached extends boolean = boolean> {
|
export interface MappedInteractionTypes<Cached extends boolean = boolean> {
|
||||||
[ComponentType.Button]: ButtonInteraction<WrapBooleanCache<Cached>>;
|
[ComponentType.Button]: ButtonInteraction<WrapBooleanCache<Cached>>;
|
||||||
[ComponentType.SelectMenu]: SelectMenuInteraction<WrapBooleanCache<Cached>>;
|
[ComponentType.StringSelect]: StringSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
|
[ComponentType.UserSelect]: UserSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
|
[ComponentType.RoleSelect]: RoleSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
|
[ComponentType.MentionableSelect]: MentionableSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
|
[ComponentType.ChannelSelect]: ChannelSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Message<InGuild extends boolean = boolean> extends Base {
|
export class Message<InGuild extends boolean = boolean> extends Base {
|
||||||
@@ -2254,22 +2335,116 @@ export class Role extends Base {
|
|||||||
public toString(): RoleMention;
|
public toString(): RoleMention;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectMenuInteraction<Cached extends CacheType = CacheType> extends MessageComponentInteraction<Cached> {
|
export class StringSelectMenuInteraction<
|
||||||
public constructor(client: Client<true>, data: RawMessageSelectMenuInteractionData);
|
Cached extends CacheType = CacheType,
|
||||||
|
> extends MessageComponentInteraction<Cached> {
|
||||||
|
public constructor(client: Client<true>, data: APIMessageStringSelectInteractionData);
|
||||||
public get component(): CacheTypeReducer<
|
public get component(): CacheTypeReducer<
|
||||||
Cached,
|
Cached,
|
||||||
SelectMenuComponent,
|
StringSelectMenuComponent,
|
||||||
APISelectMenuComponent,
|
APIStringSelectComponent,
|
||||||
SelectMenuComponent | APISelectMenuComponent,
|
StringSelectMenuComponent | APIStringSelectComponent,
|
||||||
SelectMenuComponent | APISelectMenuComponent
|
StringSelectMenuComponent | APIStringSelectComponent
|
||||||
>;
|
>;
|
||||||
public componentType: ComponentType.SelectMenu;
|
public componentType: ComponentType.StringSelect;
|
||||||
public values: string[];
|
public values: string[];
|
||||||
public inGuild(): this is SelectMenuInteraction<'raw' | 'cached'>;
|
public inGuild(): this is StringSelectMenuInteraction<'raw' | 'cached'>;
|
||||||
public inCachedGuild(): this is SelectMenuInteraction<'cached'>;
|
public inCachedGuild(): this is StringSelectMenuInteraction<'cached'>;
|
||||||
public inRawGuild(): this is SelectMenuInteraction<'raw'>;
|
public inRawGuild(): this is StringSelectMenuInteraction<'raw'>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
/** @deprecated Use {@link StringSelectMenuInteraction} instead */
|
||||||
|
StringSelectMenuInteraction as SelectMenuInteraction,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class UserSelectMenuInteraction<
|
||||||
|
Cached extends CacheType = CacheType,
|
||||||
|
> extends MessageComponentInteraction<Cached> {
|
||||||
|
public constructor(client: Client<true>, data: APIMessageUserSelectInteractionData);
|
||||||
|
public get component(): CacheTypeReducer<
|
||||||
|
Cached,
|
||||||
|
UserSelectMenuComponent,
|
||||||
|
APIUserSelectComponent,
|
||||||
|
UserSelectMenuComponent | APIUserSelectComponent,
|
||||||
|
UserSelectMenuComponent | APIUserSelectComponent
|
||||||
|
>;
|
||||||
|
public componentType: ComponentType.UserSelect;
|
||||||
|
public users: Collection<Snowflake, User>;
|
||||||
|
public members: Collection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIGuildMember>>;
|
||||||
|
public inGuild(): this is UserSelectMenuInteraction<'raw' | 'cached'>;
|
||||||
|
public inCachedGuild(): this is UserSelectMenuInteraction<'cached'>;
|
||||||
|
public inRawGuild(): this is UserSelectMenuInteraction<'raw'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RoleSelectMenuInteraction<
|
||||||
|
Cached extends CacheType = CacheType,
|
||||||
|
> extends MessageComponentInteraction<Cached> {
|
||||||
|
public constructor(client: Client<true>, data: APIMessageRoleSelectInteractionData);
|
||||||
|
public get component(): CacheTypeReducer<
|
||||||
|
Cached,
|
||||||
|
RoleSelectMenuComponent,
|
||||||
|
APIRoleSelectComponent,
|
||||||
|
RoleSelectMenuComponent | APIRoleSelectComponent,
|
||||||
|
RoleSelectMenuComponent | APIRoleSelectComponent
|
||||||
|
>;
|
||||||
|
public componentType: ComponentType.RoleSelect;
|
||||||
|
public roles: Collection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||||
|
public inGuild(): this is RoleSelectMenuInteraction<'raw' | 'cached'>;
|
||||||
|
public inCachedGuild(): this is RoleSelectMenuInteraction<'cached'>;
|
||||||
|
public inRawGuild(): this is RoleSelectMenuInteraction<'raw'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MentionableSelectMenuInteraction<
|
||||||
|
Cached extends CacheType = CacheType,
|
||||||
|
> extends MessageComponentInteraction<Cached> {
|
||||||
|
public constructor(client: Client<true>, data: APIMessageMentionableSelectInteractionData);
|
||||||
|
public get component(): CacheTypeReducer<
|
||||||
|
Cached,
|
||||||
|
MentionableSelectMenuComponent,
|
||||||
|
APIMentionableSelectComponent,
|
||||||
|
MentionableSelectMenuComponent | APIMentionableSelectComponent,
|
||||||
|
MentionableSelectMenuComponent | APIMentionableSelectComponent
|
||||||
|
>;
|
||||||
|
public componentType: ComponentType.MentionableSelect;
|
||||||
|
public users: Collection<Snowflake, User>;
|
||||||
|
public members: Collection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIGuildMember>>;
|
||||||
|
public roles: Collection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||||
|
public inGuild(): this is MentionableSelectMenuInteraction<'raw' | 'cached'>;
|
||||||
|
public inCachedGuild(): this is MentionableSelectMenuInteraction<'cached'>;
|
||||||
|
public inRawGuild(): this is MentionableSelectMenuInteraction<'raw'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ChannelSelectMenuInteraction<
|
||||||
|
Cached extends CacheType = CacheType,
|
||||||
|
> extends MessageComponentInteraction<Cached> {
|
||||||
|
public constructor(client: Client<true>, data: APIMessageChannelSelectInteractionData);
|
||||||
|
public get component(): CacheTypeReducer<
|
||||||
|
Cached,
|
||||||
|
ChannelSelectMenuComponent,
|
||||||
|
APIChannelSelectComponent,
|
||||||
|
ChannelSelectMenuComponent | APIChannelSelectComponent,
|
||||||
|
ChannelSelectMenuComponent | APIChannelSelectComponent
|
||||||
|
>;
|
||||||
|
public componentType: ComponentType.ChannelSelect;
|
||||||
|
public channels: Collection<Snowflake, CacheTypeReducer<Cached, Channel, APIChannel>>;
|
||||||
|
public inGuild(): this is ChannelSelectMenuInteraction<'raw' | 'cached'>;
|
||||||
|
public inCachedGuild(): this is ChannelSelectMenuInteraction<'cached'>;
|
||||||
|
public inRawGuild(): this is ChannelSelectMenuInteraction<'raw'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideally this should be named SelectMenuInteraction, but that's the name of the "old" StringSelectMenuInteraction, meaning
|
||||||
|
// the type name is reserved as a re-export to prevent a breaking change from being made, as such:
|
||||||
|
// TODO: Rename this to SelectMenuInteraction in the next major
|
||||||
|
export type AnySelectMenuInteraction<Cached extends CacheType = CacheType> =
|
||||||
|
| StringSelectMenuInteraction<Cached>
|
||||||
|
| UserSelectMenuInteraction<Cached>
|
||||||
|
| RoleSelectMenuInteraction<Cached>
|
||||||
|
| MentionableSelectMenuInteraction<Cached>
|
||||||
|
| ChannelSelectMenuInteraction<Cached>;
|
||||||
|
|
||||||
|
export type SelectMenuType = APISelectMenuComponent['type'];
|
||||||
|
|
||||||
export interface ShardEventTypes {
|
export interface ShardEventTypes {
|
||||||
death: [process: ChildProcess | Worker];
|
death: [process: ChildProcess | Worker];
|
||||||
disconnect: [];
|
disconnect: [];
|
||||||
@@ -2770,14 +2945,22 @@ export function parseWebhookURL(url: string): WebhookClientDataIdWithToken | nul
|
|||||||
|
|
||||||
export interface MappedComponentBuilderTypes {
|
export interface MappedComponentBuilderTypes {
|
||||||
[ComponentType.Button]: ButtonBuilder;
|
[ComponentType.Button]: ButtonBuilder;
|
||||||
[ComponentType.SelectMenu]: SelectMenuBuilder;
|
[ComponentType.StringSelect]: StringSelectMenuBuilder;
|
||||||
|
[ComponentType.UserSelect]: UserSelectMenuBuilder;
|
||||||
|
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
|
||||||
|
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
|
||||||
|
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
|
||||||
[ComponentType.ActionRow]: ActionRowBuilder;
|
[ComponentType.ActionRow]: ActionRowBuilder;
|
||||||
[ComponentType.TextInput]: TextInputBuilder;
|
[ComponentType.TextInput]: TextInputBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MappedComponentTypes {
|
export interface MappedComponentTypes {
|
||||||
[ComponentType.Button]: ButtonComponent;
|
[ComponentType.Button]: ButtonComponent;
|
||||||
[ComponentType.SelectMenu]: SelectMenuComponent;
|
[ComponentType.StringSelect]: StringSelectMenuComponent;
|
||||||
|
[ComponentType.UserSelect]: UserSelectMenuComponent;
|
||||||
|
[ComponentType.RoleSelect]: RoleSelectMenuComponent;
|
||||||
|
[ComponentType.MentionableSelect]: MentionableSelectMenuComponent;
|
||||||
|
[ComponentType.ChannelSelect]: ChannelSelectMenuComponent;
|
||||||
[ComponentType.ActionRow]: ActionRowComponent;
|
[ComponentType.ActionRow]: ActionRowComponent;
|
||||||
[ComponentType.TextInput]: TextInputComponent;
|
[ComponentType.TextInput]: TextInputComponent;
|
||||||
}
|
}
|
||||||
@@ -3116,6 +3299,7 @@ export const Constants: {
|
|||||||
TextBasedChannelTypes: TextBasedChannelTypes[];
|
TextBasedChannelTypes: TextBasedChannelTypes[];
|
||||||
ThreadChannelTypes: ThreadChannelType[];
|
ThreadChannelTypes: ThreadChannelType[];
|
||||||
VoiceBasedChannelTypes: VoiceBasedChannelTypes[];
|
VoiceBasedChannelTypes: VoiceBasedChannelTypes[];
|
||||||
|
SelectMenuTypes: SelectMenuType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const version: string;
|
export const version: string;
|
||||||
@@ -5144,7 +5328,11 @@ export interface IntegrationAccount {
|
|||||||
export type IntegrationType = 'twitch' | 'youtube' | 'discord';
|
export type IntegrationType = 'twitch' | 'youtube' | 'discord';
|
||||||
|
|
||||||
export type CollectedInteraction<Cached extends CacheType = CacheType> =
|
export type CollectedInteraction<Cached extends CacheType = CacheType> =
|
||||||
| SelectMenuInteraction<Cached>
|
| StringSelectMenuInteraction<Cached>
|
||||||
|
| UserSelectMenuInteraction<Cached>
|
||||||
|
| RoleSelectMenuInteraction<Cached>
|
||||||
|
| MentionableSelectMenuInteraction<Cached>
|
||||||
|
| ChannelSelectMenuInteraction<Cached>
|
||||||
| ButtonInteraction<Cached>
|
| ButtonInteraction<Cached>
|
||||||
| ModalSubmitInteraction<Cached>;
|
| ModalSubmitInteraction<Cached>;
|
||||||
|
|
||||||
@@ -5216,7 +5404,13 @@ export interface MakeErrorOptions {
|
|||||||
stack: string;
|
stack: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ActionRowComponentOptions = ButtonComponentData | SelectMenuComponentData;
|
export type ActionRowComponentOptions =
|
||||||
|
| ButtonComponentData
|
||||||
|
| StringSelectMenuComponentData
|
||||||
|
| UserSelectMenuComponentData
|
||||||
|
| RoleSelectMenuComponentData
|
||||||
|
| MentionableSelectMenuComponentData
|
||||||
|
| ChannelSelectMenuComponentData;
|
||||||
|
|
||||||
export type MessageActionRowComponentResolvable = MessageActionRowComponent | ActionRowComponentOptions;
|
export type MessageActionRowComponentResolvable = MessageActionRowComponent | ActionRowComponentOptions;
|
||||||
|
|
||||||
@@ -5253,7 +5447,11 @@ export type MessageComponent =
|
|||||||
| Component
|
| Component
|
||||||
| ActionRowBuilder<MessageActionRowComponentBuilder | ModalActionRowComponentBuilder>
|
| ActionRowBuilder<MessageActionRowComponentBuilder | ModalActionRowComponentBuilder>
|
||||||
| ButtonComponent
|
| ButtonComponent
|
||||||
| SelectMenuComponent;
|
| StringSelectMenuComponent
|
||||||
|
| UserSelectMenuComponent
|
||||||
|
| RoleSelectMenuComponent
|
||||||
|
| MentionableSelectMenuComponent
|
||||||
|
| ChannelSelectMenuComponent;
|
||||||
|
|
||||||
export type CollectedMessageInteraction<Cached extends CacheType = CacheType> = Exclude<
|
export type CollectedMessageInteraction<Cached extends CacheType = CacheType> = Exclude<
|
||||||
CollectedInteraction<Cached>,
|
CollectedInteraction<Cached>,
|
||||||
@@ -5351,16 +5549,36 @@ export interface MessageReference {
|
|||||||
|
|
||||||
export type MessageResolvable = Message | Snowflake;
|
export type MessageResolvable = Message | Snowflake;
|
||||||
|
|
||||||
export interface SelectMenuComponentData extends BaseComponentData {
|
export interface BaseSelectMenuComponentData extends BaseComponentData {
|
||||||
type: ComponentType.SelectMenu;
|
|
||||||
customId: string;
|
customId: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
maxValues?: number;
|
maxValues?: number;
|
||||||
minValues?: number;
|
minValues?: number;
|
||||||
options?: SelectMenuComponentOptionData[];
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StringSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||||
|
type: ComponentType.StringSelect;
|
||||||
|
options?: SelectMenuComponentOptionData[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||||
|
type: ComponentType.UserSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoleSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||||
|
type: ComponentType.RoleSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MentionableSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||||
|
type: ComponentType.MentionableSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChannelSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||||
|
type: ComponentType.ChannelSelect;
|
||||||
|
channelTypes?: ChannelType[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface MessageSelectOption {
|
export interface MessageSelectOption {
|
||||||
default: boolean;
|
default: boolean;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
APIEmbed,
|
APIEmbed,
|
||||||
ApplicationCommandType,
|
ApplicationCommandType,
|
||||||
APIMessage,
|
APIMessage,
|
||||||
|
APIStringSelectComponent,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import {
|
import {
|
||||||
ApplicationCommand,
|
ApplicationCommand,
|
||||||
@@ -72,7 +73,6 @@ import {
|
|||||||
ReactionCollector,
|
ReactionCollector,
|
||||||
Role,
|
Role,
|
||||||
RoleManager,
|
RoleManager,
|
||||||
SelectMenuInteraction,
|
|
||||||
Serialized,
|
Serialized,
|
||||||
ShardClientUtil,
|
ShardClientUtil,
|
||||||
ShardingManager,
|
ShardingManager,
|
||||||
@@ -113,7 +113,7 @@ import {
|
|||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
MessageActionRowComponent,
|
MessageActionRowComponent,
|
||||||
SelectMenuBuilder,
|
StringSelectMenuBuilder,
|
||||||
TextInputBuilder,
|
TextInputBuilder,
|
||||||
TextInputComponent,
|
TextInputComponent,
|
||||||
Embed,
|
Embed,
|
||||||
@@ -141,6 +141,13 @@ import {
|
|||||||
ChannelFlagsBitField,
|
ChannelFlagsBitField,
|
||||||
GuildForumThreadManager,
|
GuildForumThreadManager,
|
||||||
GuildTextThreadManager,
|
GuildTextThreadManager,
|
||||||
|
AnySelectMenuInteraction,
|
||||||
|
StringSelectMenuInteraction,
|
||||||
|
StringSelectMenuComponent,
|
||||||
|
UserSelectMenuInteraction,
|
||||||
|
RoleSelectMenuInteraction,
|
||||||
|
ChannelSelectMenuInteraction,
|
||||||
|
MentionableSelectMenuInteraction,
|
||||||
} from '.';
|
} from '.';
|
||||||
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
||||||
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
||||||
@@ -361,14 +368,14 @@ client.on('messageCreate', async message => {
|
|||||||
expectAssignable<InteractionCollector<ButtonInteraction>>(buttonCollector);
|
expectAssignable<InteractionCollector<ButtonInteraction>>(buttonCollector);
|
||||||
|
|
||||||
// Verify that select menus interaction are inferred.
|
// Verify that select menus interaction are inferred.
|
||||||
const selectMenuCollector = message.createMessageComponentCollector({ componentType: ComponentType.SelectMenu });
|
const selectMenuCollector = message.createMessageComponentCollector({ componentType: ComponentType.StringSelect });
|
||||||
expectAssignable<Promise<SelectMenuInteraction>>(
|
expectAssignable<Promise<StringSelectMenuInteraction>>(
|
||||||
message.awaitMessageComponent({ componentType: ComponentType.SelectMenu }),
|
message.awaitMessageComponent({ componentType: ComponentType.StringSelect }),
|
||||||
);
|
);
|
||||||
expectAssignable<Promise<SelectMenuInteraction>>(
|
expectAssignable<Promise<StringSelectMenuInteraction>>(
|
||||||
channel.awaitMessageComponent({ componentType: ComponentType.SelectMenu }),
|
channel.awaitMessageComponent({ componentType: ComponentType.StringSelect }),
|
||||||
);
|
);
|
||||||
expectAssignable<InteractionCollector<SelectMenuInteraction>>(selectMenuCollector);
|
expectAssignable<InteractionCollector<StringSelectMenuInteraction>>(selectMenuCollector);
|
||||||
|
|
||||||
// Verify that message component interactions are default collected types.
|
// Verify that message component interactions are default collected types.
|
||||||
const defaultCollector = message.createMessageComponentCollector();
|
const defaultCollector = message.createMessageComponentCollector();
|
||||||
@@ -405,9 +412,9 @@ client.on('messageCreate', async message => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
message.createMessageComponentCollector({
|
message.createMessageComponentCollector({
|
||||||
componentType: ComponentType.SelectMenu,
|
componentType: ComponentType.StringSelect,
|
||||||
filter: i => {
|
filter: i => {
|
||||||
expectType<SelectMenuInteraction>(i);
|
expectType<StringSelectMenuInteraction>(i);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -428,9 +435,9 @@ client.on('messageCreate', async message => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
message.awaitMessageComponent({
|
message.awaitMessageComponent({
|
||||||
componentType: ComponentType.SelectMenu,
|
componentType: ComponentType.StringSelect,
|
||||||
filter: i => {
|
filter: i => {
|
||||||
expectType<SelectMenuInteraction>(i);
|
expectType<StringSelectMenuInteraction>(i);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -464,9 +471,9 @@ client.on('messageCreate', async message => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
channel.awaitMessageComponent({
|
channel.awaitMessageComponent({
|
||||||
componentType: ComponentType.SelectMenu,
|
componentType: ComponentType.StringSelect,
|
||||||
filter: i => {
|
filter: i => {
|
||||||
expectType<SelectMenuInteraction<'cached'>>(i);
|
expectType<StringSelectMenuInteraction<'cached'>>(i);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -489,9 +496,9 @@ client.on('messageCreate', async message => {
|
|||||||
const selectsRow: ActionRowData<MessageActionRowComponentData> = {
|
const selectsRow: ActionRowData<MessageActionRowComponentData> = {
|
||||||
type: ComponentType.ActionRow,
|
type: ComponentType.ActionRow,
|
||||||
components: [
|
components: [
|
||||||
new SelectMenuBuilder(),
|
new StringSelectMenuBuilder(),
|
||||||
{
|
{
|
||||||
type: ComponentType.SelectMenu,
|
type: ComponentType.StringSelect,
|
||||||
label: 'select menu',
|
label: 'select menu',
|
||||||
options: [{ label: 'test', value: 'test' }],
|
options: [{ label: 'test', value: 'test' }],
|
||||||
customId: 'test',
|
customId: 'test',
|
||||||
@@ -1122,8 +1129,8 @@ client.on('guildCreate', async g => {
|
|||||||
new ButtonBuilder(),
|
new ButtonBuilder(),
|
||||||
{ type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
|
{ type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
|
||||||
{ type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
|
{ type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
|
||||||
{ type: ComponentType.SelectMenu, customId: 'foo' },
|
{ type: ComponentType.StringSelect, customId: 'foo' },
|
||||||
new SelectMenuBuilder(),
|
new StringSelectMenuBuilder(),
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
{ type: ComponentType.TextInput, style: TextInputStyle.Paragraph, customId: 'foo', label: 'test' },
|
{ type: ComponentType.TextInput, style: TextInputStyle.Paragraph, customId: 'foo', label: 'test' },
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@@ -1136,7 +1143,7 @@ client.on('guildCreate', async g => {
|
|||||||
components: [
|
components: [
|
||||||
{ type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
|
{ type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
|
||||||
{ type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
|
{ type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
|
||||||
{ type: ComponentType.SelectMenu, customId: 'foo' },
|
{ type: ComponentType.StringSelect, customId: 'foo' },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1508,7 +1515,7 @@ if (interaction.inGuild()) {
|
|||||||
|
|
||||||
client.on('interactionCreate', async interaction => {
|
client.on('interactionCreate', async interaction => {
|
||||||
if (interaction.type === InteractionType.MessageComponent) {
|
if (interaction.type === InteractionType.MessageComponent) {
|
||||||
expectType<SelectMenuInteraction | ButtonInteraction>(interaction);
|
expectType<AnySelectMenuInteraction | ButtonInteraction>(interaction);
|
||||||
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
|
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
|
||||||
expectType<Message>(interaction.message);
|
expectType<Message>(interaction.message);
|
||||||
if (interaction.inCachedGuild()) {
|
if (interaction.inCachedGuild()) {
|
||||||
@@ -1640,25 +1647,28 @@ client.on('interactionCreate', async interaction => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interaction.type === InteractionType.MessageComponent && interaction.componentType === ComponentType.SelectMenu) {
|
if (
|
||||||
expectType<SelectMenuInteraction>(interaction);
|
interaction.type === InteractionType.MessageComponent &&
|
||||||
expectType<SelectMenuComponent | APISelectMenuComponent>(interaction.component);
|
interaction.componentType === ComponentType.StringSelect
|
||||||
|
) {
|
||||||
|
expectType<StringSelectMenuInteraction>(interaction);
|
||||||
|
expectType<StringSelectMenuComponent | APIStringSelectComponent>(interaction.component);
|
||||||
expectType<Message>(interaction.message);
|
expectType<Message>(interaction.message);
|
||||||
if (interaction.inCachedGuild()) {
|
if (interaction.inCachedGuild()) {
|
||||||
expectAssignable<SelectMenuInteraction>(interaction);
|
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||||
expectType<SelectMenuComponent>(interaction.component);
|
expectType<SelectMenuComponent>(interaction.component);
|
||||||
expectType<Message<true>>(interaction.message);
|
expectType<Message<true>>(interaction.message);
|
||||||
expectType<Guild>(interaction.guild);
|
expectType<Guild>(interaction.guild);
|
||||||
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
|
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
|
||||||
} else if (interaction.inRawGuild()) {
|
} else if (interaction.inRawGuild()) {
|
||||||
expectAssignable<SelectMenuInteraction>(interaction);
|
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||||
expectType<APISelectMenuComponent>(interaction.component);
|
expectType<APIStringSelectComponent>(interaction.component);
|
||||||
expectType<Message<false>>(interaction.message);
|
expectType<Message<false>>(interaction.message);
|
||||||
expectType<null>(interaction.guild);
|
expectType<null>(interaction.guild);
|
||||||
expectType<Promise<Message<false>>>(interaction.reply({ fetchReply: true }));
|
expectType<Promise<Message<false>>>(interaction.reply({ fetchReply: true }));
|
||||||
} else if (interaction.inGuild()) {
|
} else if (interaction.inGuild()) {
|
||||||
expectAssignable<SelectMenuInteraction>(interaction);
|
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||||
expectType<SelectMenuComponent | APISelectMenuComponent>(interaction.component);
|
expectType<SelectMenuComponent | APIStringSelectComponent>(interaction.component);
|
||||||
expectType<Message>(interaction.message);
|
expectType<Message>(interaction.message);
|
||||||
expectType<Guild | null>(interaction.guild);
|
expectType<Guild | null>(interaction.guild);
|
||||||
expectType<Promise<Message>>(interaction.reply({ fetchReply: true }));
|
expectType<Promise<Message>>(interaction.reply({ fetchReply: true }));
|
||||||
@@ -1882,7 +1892,7 @@ const button = new ButtonBuilder({
|
|||||||
customId: 'test',
|
customId: 'test',
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectMenu = new SelectMenuBuilder({
|
const selectMenu = new StringSelectMenuBuilder({
|
||||||
maxValues: 10,
|
maxValues: 10,
|
||||||
minValues: 2,
|
minValues: 2,
|
||||||
customId: 'test',
|
customId: 'test',
|
||||||
@@ -1892,7 +1902,7 @@ new ActionRowBuilder({
|
|||||||
components: [selectMenu.toJSON(), button.toJSON()],
|
components: [selectMenu.toJSON(), button.toJSON()],
|
||||||
});
|
});
|
||||||
|
|
||||||
new SelectMenuBuilder({
|
new StringSelectMenuBuilder({
|
||||||
customId: 'foo',
|
customId: 'foo',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1951,10 +1961,10 @@ chatInputInteraction.showModal({
|
|||||||
});
|
});
|
||||||
|
|
||||||
declare const selectMenuData: APISelectMenuComponent;
|
declare const selectMenuData: APISelectMenuComponent;
|
||||||
SelectMenuBuilder.from(selectMenuData);
|
StringSelectMenuBuilder.from(selectMenuData);
|
||||||
|
|
||||||
declare const selectMenuComp: SelectMenuComponent;
|
declare const selectMenuComp: SelectMenuComponent;
|
||||||
SelectMenuBuilder.from(selectMenuComp);
|
StringSelectMenuBuilder.from(selectMenuComp);
|
||||||
|
|
||||||
declare const buttonData: APIButtonComponent;
|
declare const buttonData: APIButtonComponent;
|
||||||
ButtonBuilder.from(buttonData);
|
ButtonBuilder.from(buttonData);
|
||||||
@@ -2025,3 +2035,22 @@ expectType<Readonly<ChannelFlagsBitField>>(categoryChannel.flags);
|
|||||||
expectType<Readonly<ChannelFlagsBitField>>(threadChannel.flags);
|
expectType<Readonly<ChannelFlagsBitField>>(threadChannel.flags);
|
||||||
|
|
||||||
expectType<null>(partialGroupDMChannel.flags);
|
expectType<null>(partialGroupDMChannel.flags);
|
||||||
|
|
||||||
|
// Select menu type narrowing
|
||||||
|
if (interaction.isAnySelectMenu()) {
|
||||||
|
expectType<AnySelectMenuInteraction>(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const anySelectMenu: AnySelectMenuInteraction;
|
||||||
|
|
||||||
|
if (anySelectMenu.isStringSelectMenu()) {
|
||||||
|
expectType<StringSelectMenuInteraction>(anySelectMenu);
|
||||||
|
} else if (anySelectMenu.isUserSelectMenu()) {
|
||||||
|
expectType<UserSelectMenuInteraction>(anySelectMenu);
|
||||||
|
} else if (anySelectMenu.isRoleSelectMenu()) {
|
||||||
|
expectType<RoleSelectMenuInteraction>(anySelectMenu);
|
||||||
|
} else if (anySelectMenu.isChannelSelectMenu()) {
|
||||||
|
expectType<ChannelSelectMenuInteraction>(anySelectMenu);
|
||||||
|
} else if (anySelectMenu.isMentionableSelectMenu()) {
|
||||||
|
expectType<MentionableSelectMenuInteraction>(anySelectMenu);
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
"@discordjs/util": "workspace:^",
|
"@discordjs/util": "workspace:^",
|
||||||
"@sapphire/async-queue": "^1.5.0",
|
"@sapphire/async-queue": "^1.5.0",
|
||||||
"@sapphire/snowflake": "^3.2.2",
|
"@sapphire/snowflake": "^3.2.2",
|
||||||
"discord-api-types": "^0.37.14",
|
"discord-api-types": "^0.37.15",
|
||||||
"file-type": "^18.0.0",
|
"file-type": "^18.0.0",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"undici": "^5.11.0"
|
"undici": "^5.11.0"
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
"homepage": "https://discord.js.org",
|
"homepage": "https://discord.js.org",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/ws": "^8.5.3",
|
"@types/ws": "^8.5.3",
|
||||||
"discord-api-types": "^0.37.14",
|
"discord-api-types": "^0.37.15",
|
||||||
"prism-media": "^1.3.4",
|
"prism-media": "^1.3.4",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"ws": "^8.9.0"
|
"ws": "^8.9.0"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
"@sapphire/async-queue": "^1.5.0",
|
"@sapphire/async-queue": "^1.5.0",
|
||||||
"@types/ws": "^8.5.3",
|
"@types/ws": "^8.5.3",
|
||||||
"@vladfrangu/async_event_emitter": "^2.1.2",
|
"@vladfrangu/async_event_emitter": "^2.1.2",
|
||||||
"discord-api-types": "^0.37.14",
|
"discord-api-types": "^0.37.15",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"ws": "^8.9.0"
|
"ws": "^8.9.0"
|
||||||
},
|
},
|
||||||
|
|||||||
18
yarn.lock
18
yarn.lock
@@ -2063,7 +2063,7 @@ __metadata:
|
|||||||
"@types/node": 16.11.68
|
"@types/node": 16.11.68
|
||||||
"@vitest/coverage-c8": ^0.24.3
|
"@vitest/coverage-c8": ^0.24.3
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
discord-api-types: ^0.37.14
|
discord-api-types: ^0.37.15
|
||||||
esbuild-plugin-version-injector: ^1.0.0
|
esbuild-plugin-version-injector: ^1.0.0
|
||||||
eslint: ^8.25.0
|
eslint: ^8.25.0
|
||||||
eslint-config-neon: ^0.1.39
|
eslint-config-neon: ^0.1.39
|
||||||
@@ -2250,7 +2250,7 @@ __metadata:
|
|||||||
"@types/node": 16.11.68
|
"@types/node": 16.11.68
|
||||||
"@vitest/coverage-c8": ^0.24.3
|
"@vitest/coverage-c8": ^0.24.3
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
discord-api-types: ^0.37.14
|
discord-api-types: ^0.37.15
|
||||||
esbuild-plugin-version-injector: ^1.0.0
|
esbuild-plugin-version-injector: ^1.0.0
|
||||||
eslint: ^8.25.0
|
eslint: ^8.25.0
|
||||||
eslint-config-neon: ^0.1.39
|
eslint-config-neon: ^0.1.39
|
||||||
@@ -2354,7 +2354,7 @@ __metadata:
|
|||||||
"@types/node": 16.11.68
|
"@types/node": 16.11.68
|
||||||
"@types/ws": ^8.5.3
|
"@types/ws": ^8.5.3
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
discord-api-types: ^0.37.14
|
discord-api-types: ^0.37.15
|
||||||
esbuild-plugin-version-injector: ^1.0.0
|
esbuild-plugin-version-injector: ^1.0.0
|
||||||
eslint: ^8.25.0
|
eslint: ^8.25.0
|
||||||
eslint-config-neon: ^0.1.39
|
eslint-config-neon: ^0.1.39
|
||||||
@@ -2444,7 +2444,7 @@ __metadata:
|
|||||||
"@vitest/coverage-c8": ^0.24.3
|
"@vitest/coverage-c8": ^0.24.3
|
||||||
"@vladfrangu/async_event_emitter": ^2.1.2
|
"@vladfrangu/async_event_emitter": ^2.1.2
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
discord-api-types: ^0.37.14
|
discord-api-types: ^0.37.15
|
||||||
esbuild-plugin-version-injector: ^1.0.0
|
esbuild-plugin-version-injector: ^1.0.0
|
||||||
eslint: ^8.25.0
|
eslint: ^8.25.0
|
||||||
eslint-config-neon: ^0.1.39
|
eslint-config-neon: ^0.1.39
|
||||||
@@ -8256,10 +8256,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"discord-api-types@npm:^0.37.14":
|
"discord-api-types@npm:^0.37.15":
|
||||||
version: 0.37.14
|
version: 0.37.15
|
||||||
resolution: "discord-api-types@npm:0.37.14"
|
resolution: "discord-api-types@npm:0.37.15"
|
||||||
checksum: 8f45f202e66acfd7b25624c8f4d225b363d9d8991d766959bcf246761548b99e21c12d9f7eafe00903913af66058595e5e56329dfb219eab8bb75a84f6413983
|
checksum: c54d2feeb8074509bdda430fb8ec0f6ff315512e7327d47399e0e7a78bbd0a6f0f0dcfc4b5e39825eb6141a13f33efa942711af89c9a5936a721cfc1e1d69d19
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -8276,7 +8276,7 @@ __metadata:
|
|||||||
"@sapphire/snowflake": ^3.2.2
|
"@sapphire/snowflake": ^3.2.2
|
||||||
"@types/node": 16.11.68
|
"@types/node": 16.11.68
|
||||||
"@types/ws": ^8.5.3
|
"@types/ws": ^8.5.3
|
||||||
discord-api-types: ^0.37.14
|
discord-api-types: ^0.37.15
|
||||||
dtslint: ^4.2.1
|
dtslint: ^4.2.1
|
||||||
eslint: ^8.25.0
|
eslint: ^8.25.0
|
||||||
eslint-formatter-pretty: ^4.1.0
|
eslint-formatter-pretty: ^4.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user