import type { Snowflake, APIChannelSelectComponent, ChannelType, } from "discord.js"; import { ChannelSelectMenuBuilder } from "discord.js"; export class V2ChannelSelectBuilder extends ChannelSelectMenuBuilder { setCustomId(custom_id: Snowflake) { if (custom_id.length > 100) throw new Error("Max length for custom ids is 100 characters."); super.setCustomId(custom_id); return this; } setPlaceholder(placeholder: Snowflake) { if (placeholder.length > 150) throw new Error("Max length for placeholders is 150 characters."); super.setPlaceholder(placeholder); return this; } setChannelTypes(...channel_types: ChannelType[]) { super.setChannelTypes(channel_types); return this; } setMinValues(min_values: number) { if (min_values < 0) throw new Error("Min values must be positive."); if (min_values > 25) throw new Error("Min values must be less than 25."); super.setMinValues(min_values); return this; } setMaxValues(max_values: number) { if (max_values < 1) throw new Error("Max values must be positive."); if (max_values > 25) throw new Error("Max values must be less than 25."); super.setMaxValues(max_values); return this; } setDisabled(disabled: boolean) { super.setDisabled(disabled); return this; } setDefaultChannels(default_channels: Snowflake[]) { if (default_channels.length > 25) throw new Error("Default channels must be less than 25."); super.setDefaultChannels(default_channels); return this; } toJSON(): APIChannelSelectComponent { const data = super.toJSON(); // Additional validation if (!data.custom_id) { throw new Error("Channel select menu must have a custom_id"); } return data; } } interface ChannelSelectOptions { custom_id: Snowflake; placeholder?: Snowflake; channel_types?: ChannelType[]; min_values?: number; max_values?: number; disabled?: boolean; default_channels?: Snowflake[]; } /** * Helper function to create a channel select menu component * @param options Configuration options for the channel select menu * @returns A configured channel select menu builder instance * * @example * ```typescript * // Create a basic channel select * const channelSelect = makeChannelSelect({ * customId: 'channel_select', * placeholder: 'Select a channel' * }); * * // Create a channel select with specific types * const textChannelSelect = makeChannelSelect({ * customId: 'text_channel_select', * placeholder: 'Select a text channel', * channelTypes: [ChannelType.GuildText], * minValues: 1, * maxValues: 3 * }); * ``` */ export function makeChannelSelect( options: ChannelSelectOptions, ): V2ChannelSelectBuilder { const select = new V2ChannelSelectBuilder(); // Required option select.setCustomId(options.custom_id); // Optional configurations if (options.placeholder) select.setPlaceholder(options.placeholder); if (options.channel_types) select.setChannelTypes(...options.channel_types); if (options.min_values !== undefined) select.setMinValues(options.min_values); if (options.max_values !== undefined) select.setMaxValues(options.max_values); if (options.disabled) select.setDisabled(options.disabled); if (options.default_channels) select.setDefaultChannels(options.default_channels); return select; }