@discordjs/builders 0.13.0-dev.1646870850.e787cd5 → 0.13.0-dev.1646913825.dcd4797

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/messages/embed/Assertions.ts","../src/messages/embed/UnsafeEmbed.ts","../src/messages/embed/Embed.ts","../src/messages/formatters.ts","../src/components/Assertions.ts","../src/components/ActionRow.ts","../src/components/Component.ts","../src/components/Components.ts","../src/components/button/UnsafeButton.ts","../src/components/button/Button.ts","../src/components/textInput/Assertions.ts","../src/components/textInput/UnsafeTextInput.ts","../src/components/textInput/TextInput.ts","../src/interactions/modals/UnsafeModal.ts","../src/interactions/modals/Assertions.ts","../src/interactions/modals/Modal.ts","../src/components/selectMenu/UnsafeSelectMenu.ts","../src/components/selectMenu/UnsafeSelectMenuOption.ts","../src/components/selectMenu/SelectMenu.ts","../src/components/selectMenu/SelectMenuOption.ts","../src/interactions/slashCommands/Assertions.ts","../src/interactions/slashCommands/SlashCommandBuilder.ts","../src/interactions/slashCommands/options/boolean.ts","../src/interactions/slashCommands/mixins/NameAndDescription.ts","../src/interactions/slashCommands/mixins/ApplicationCommandOptionBase.ts","../src/interactions/slashCommands/options/channel.ts","../src/interactions/slashCommands/mixins/ApplicationCommandOptionChannelTypesMixin.ts","../src/interactions/slashCommands/options/integer.ts","../src/interactions/slashCommands/mixins/ApplicationCommandNumericOptionMinMaxValueMixin.ts","../src/interactions/slashCommands/mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin.ts","../src/interactions/slashCommands/options/mentionable.ts","../src/interactions/slashCommands/options/number.ts","../src/interactions/slashCommands/options/role.ts","../src/interactions/slashCommands/options/attachment.ts","../src/interactions/slashCommands/options/string.ts","../src/interactions/slashCommands/options/user.ts","../src/interactions/slashCommands/mixins/SharedSlashCommandOptions.ts","../src/interactions/slashCommands/SlashCommandSubcommands.ts","../src/interactions/contextMenuCommands/Assertions.ts","../src/interactions/contextMenuCommands/ContextMenuCommandBuilder.ts","../src/util/jsonEncodable.ts"],"sourcesContent":["export * as EmbedAssertions from './messages/embed/Assertions';\nexport * from './messages/embed/Embed';\nexport * from './messages/formatters';\nexport * from './messages/embed/UnsafeEmbed';\n\nexport * as ComponentAssertions from './components/Assertions';\nexport * from './components/ActionRow';\nexport * from './components/button/Button';\nexport * from './components/Component';\nexport * from './components/Components';\nexport * from './components/textInput/TextInput';\nexport * as TextInputAssertions from './components/textInput/Assertions';\nexport * from './components/textInput/UnsafeTextInput';\nexport * from './interactions/modals/UnsafeModal';\nexport * from './interactions/modals/Modal';\nexport * as ModalAssertions from './interactions/modals/Assertions';\nexport * from './components/selectMenu/SelectMenu';\nexport * from './components/selectMenu/SelectMenuOption';\nexport * from './components/button/UnsafeButton';\nexport * from './components/selectMenu/UnsafeSelectMenu';\nexport * from './components/selectMenu/UnsafeSelectMenuOption';\n\nexport * as SlashCommandAssertions from './interactions/slashCommands/Assertions';\nexport * from './interactions/slashCommands/SlashCommandBuilder';\nexport * from './interactions/slashCommands/SlashCommandSubcommands';\nexport * from './interactions/slashCommands/options/boolean';\nexport * from './interactions/slashCommands/options/channel';\nexport * from './interactions/slashCommands/options/integer';\nexport * from './interactions/slashCommands/options/mentionable';\nexport * from './interactions/slashCommands/options/number';\nexport * from './interactions/slashCommands/options/role';\nexport * from './interactions/slashCommands/options/attachment';\nexport * from './interactions/slashCommands/options/string';\nexport * from './interactions/slashCommands/options/user';\n\nexport * as ContextMenuCommandAssertions from './interactions/contextMenuCommands/Assertions';\nexport * from './interactions/contextMenuCommands/ContextMenuCommandBuilder';\n\nexport * from './util/jsonEncodable';\n","import type { APIEmbedField } from 'discord-api-types/v9';\nimport { z } from 'zod';\n\nexport const fieldNamePredicate = z.string().min(1).max(256);\n\nexport const fieldValuePredicate = z.string().min(1).max(1024);\n\nexport const fieldInlinePredicate = z.boolean().optional();\n\nexport const embedFieldPredicate = z.object({\n\tname: fieldNamePredicate,\n\tvalue: fieldValuePredicate,\n\tinline: fieldInlinePredicate,\n});\n\nexport const embedFieldsArrayPredicate = embedFieldPredicate.array();\n\nexport const fieldLengthPredicate = z.number().lte(25);\n\nexport function validateFieldLength(amountAdding: number, fields?: APIEmbedField[]): void {\n\tfieldLengthPredicate.parse((fields?.length ?? 0) + amountAdding);\n}\n\nexport const authorNamePredicate = fieldNamePredicate.nullable();\n\nexport const urlPredicate = z.string().url().nullish();\n\nexport const RGBPredicate = z.number().int().gte(0).lte(255);\nexport const colorPredicate = z\n\t.number()\n\t.int()\n\t.gte(0)\n\t.lte(0xffffff)\n\t.nullable()\n\t.or(z.tuple([RGBPredicate, RGBPredicate, RGBPredicate]));\n\nexport const descriptionPredicate = z.string().min(1).max(4096).nullable();\n\nexport const footerTextPredicate = z.string().min(1).max(2048).nullable();\n\nexport const timestampPredicate = z.union([z.number(), z.date()]).nullable();\n\nexport const titlePredicate = fieldNamePredicate.nullable();\n","import type {\n\tAPIEmbed,\n\tAPIEmbedAuthor,\n\tAPIEmbedField,\n\tAPIEmbedFooter,\n\tAPIEmbedImage,\n\tAPIEmbedVideo,\n} from 'discord-api-types/v9';\nimport type { Equatable } from '../../util/equatable';\nimport isEqual from 'fast-deep-equal';\n\nexport type RGBTuple = [red: number, green: number, blue: number];\n\nexport interface IconData {\n\t/**\n\t * The URL of the icon\n\t */\n\ticonURL?: string;\n\t/**\n\t * The proxy URL of the icon\n\t */\n\tproxyIconURL?: string;\n}\n\nexport type EmbedAuthorData = Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'> & IconData;\n\nexport type EmbedAuthorOptions = Omit<EmbedAuthorData, 'proxyIconURL'>;\n\nexport type EmbedFooterData = Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'> & IconData;\n\nexport type EmbedFooterOptions = Omit<EmbedFooterData, 'proxyIconURL'>;\n\nexport interface EmbedImageData extends Omit<APIEmbedImage, 'proxy_url'> {\n\t/**\n\t * The proxy URL for the image\n\t */\n\tproxyURL?: string;\n}\n\n/**\n * Represents a non-validated embed in a message (image/video preview, rich embed, etc.)\n */\nexport class UnsafeEmbed implements Equatable<APIEmbed | UnsafeEmbed> {\n\tpublic readonly data: APIEmbed;\n\n\tpublic constructor(data: APIEmbed = {}) {\n\t\tthis.data = { ...data };\n\t\tif (data.timestamp) this.data.timestamp = new Date(data.timestamp).toISOString();\n\t}\n\n\t/**\n\t * An array of fields of this embed\n\t */\n\tpublic get fields() {\n\t\treturn this.data.fields;\n\t}\n\n\t/**\n\t * The embed title\n\t */\n\tpublic get title() {\n\t\treturn this.data.title;\n\t}\n\n\t/**\n\t * The embed description\n\t */\n\tpublic get description() {\n\t\treturn this.data.description;\n\t}\n\n\t/**\n\t * The embed URL\n\t */\n\tpublic get url() {\n\t\treturn this.data.url;\n\t}\n\n\t/**\n\t * The embed color\n\t */\n\tpublic get color() {\n\t\treturn this.data.color;\n\t}\n\n\t/**\n\t * The timestamp of the embed in an ISO 8601 format\n\t */\n\tpublic get timestamp() {\n\t\treturn this.data.timestamp;\n\t}\n\n\t/**\n\t * The embed thumbnail data\n\t */\n\tpublic get thumbnail(): EmbedImageData | undefined {\n\t\tif (!this.data.thumbnail) return undefined;\n\t\treturn {\n\t\t\turl: this.data.thumbnail.url,\n\t\t\tproxyURL: this.data.thumbnail.proxy_url,\n\t\t\theight: this.data.thumbnail.height,\n\t\t\twidth: this.data.thumbnail.width,\n\t\t};\n\t}\n\n\t/**\n\t * The embed image data\n\t */\n\tpublic get image(): EmbedImageData | undefined {\n\t\tif (!this.data.image) return undefined;\n\t\treturn {\n\t\t\turl: this.data.image.url,\n\t\t\tproxyURL: this.data.image.proxy_url,\n\t\t\theight: this.data.image.height,\n\t\t\twidth: this.data.image.width,\n\t\t};\n\t}\n\n\t/**\n\t * Received video data\n\t */\n\tpublic get video(): APIEmbedVideo | undefined {\n\t\treturn this.data.video;\n\t}\n\n\t/**\n\t * The embed author data\n\t */\n\tpublic get author(): EmbedAuthorData | undefined {\n\t\tif (!this.data.author) return undefined;\n\t\treturn {\n\t\t\tname: this.data.author.name,\n\t\t\turl: this.data.author.url,\n\t\t\ticonURL: this.data.author.icon_url,\n\t\t\tproxyIconURL: this.data.author.proxy_icon_url,\n\t\t};\n\t}\n\n\t/**\n\t * Received data about the embed provider\n\t */\n\tpublic get provider() {\n\t\treturn this.data.provider;\n\t}\n\n\t/**\n\t * The embed footer data\n\t */\n\tpublic get footer(): EmbedFooterData | undefined {\n\t\tif (!this.data.footer) return undefined;\n\t\treturn {\n\t\t\ttext: this.data.footer.text,\n\t\t\ticonURL: this.data.footer.icon_url,\n\t\t\tproxyIconURL: this.data.footer.proxy_icon_url,\n\t\t};\n\t}\n\n\t/**\n\t * The accumulated length for the embed title, description, fields, footer text, and author name\n\t */\n\tpublic get length(): number {\n\t\treturn (\n\t\t\t(this.data.title?.length ?? 0) +\n\t\t\t(this.data.description?.length ?? 0) +\n\t\t\t(this.data.fields?.reduce((prev, curr) => prev + curr.name.length + curr.value.length, 0) ?? 0) +\n\t\t\t(this.data.footer?.text.length ?? 0) +\n\t\t\t(this.data.author?.name.length ?? 0)\n\t\t);\n\t}\n\n\t/**\n\t * The hex color of the current color of the embed\n\t */\n\tpublic get hexColor() {\n\t\treturn typeof this.data.color === 'number' ? `#${this.data.color.toString(16).padStart(6, '0')}` : this.data.color;\n\t}\n\n\t/**\n\t * Adds fields to the embed (max 25)\n\t *\n\t * @param fields The fields to add\n\t */\n\tpublic addFields(...fields: APIEmbedField[]): this {\n\t\tif (this.data.fields) this.data.fields.push(...fields);\n\t\telse this.data.fields = fields;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes, replaces, or inserts fields in the embed (max 25)\n\t *\n\t * @param index The index to start at\n\t * @param deleteCount The number of fields to remove\n\t * @param fields The replacing field objects\n\t */\n\tpublic spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this {\n\t\tif (this.data.fields) this.data.fields.splice(index, deleteCount, ...fields);\n\t\telse this.data.fields = fields;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the embed's fields (max 25).\n\t * @param fields The fields to set\n\t */\n\tpublic setFields(...fields: APIEmbedField[]) {\n\t\tthis.spliceFields(0, this.fields?.length ?? 0, ...fields);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the author of this embed\n\t *\n\t * @param options The options for the author\n\t */\n\tpublic setAuthor(options: EmbedAuthorOptions | null): this {\n\t\tif (options === null) {\n\t\t\tthis.data.author = undefined;\n\t\t\treturn this;\n\t\t}\n\n\t\tthis.data.author = { name: options.name, url: options.url, icon_url: options.iconURL };\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the color of this embed\n\t *\n\t * @param color The color of the embed\n\t */\n\tpublic setColor(color: number | RGBTuple | null): this {\n\t\tif (Array.isArray(color)) {\n\t\t\tconst [red, green, blue] = color;\n\t\t\tthis.data.color = (red << 16) + (green << 8) + blue;\n\t\t\treturn this;\n\t\t}\n\t\tthis.data.color = color ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the description of this embed\n\t *\n\t * @param description The description\n\t */\n\tpublic setDescription(description: string | null): this {\n\t\tthis.data.description = description ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the footer of this embed\n\t *\n\t * @param options The options for the footer\n\t */\n\tpublic setFooter(options: EmbedFooterOptions | null): this {\n\t\tif (options === null) {\n\t\t\tthis.data.footer = undefined;\n\t\t\treturn this;\n\t\t}\n\n\t\tthis.data.footer = { text: options.text, icon_url: options.iconURL };\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the image of this embed\n\t *\n\t * @param url The URL of the image\n\t */\n\tpublic setImage(url: string | null): this {\n\t\tthis.data.image = url ? { url } : undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the thumbnail of this embed\n\t *\n\t * @param url The URL of the thumbnail\n\t */\n\tpublic setThumbnail(url: string | null): this {\n\t\tthis.data.thumbnail = url ? { url } : undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the timestamp of this embed\n\t *\n\t * @param timestamp The timestamp or date\n\t */\n\tpublic setTimestamp(timestamp: number | Date | null = Date.now()): this {\n\t\tthis.data.timestamp = timestamp ? new Date(timestamp).toISOString() : undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the title of this embed\n\t *\n\t * @param title The title\n\t */\n\tpublic setTitle(title: string | null): this {\n\t\tthis.data.title = title ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the URL of this embed\n\t *\n\t * @param url The URL\n\t */\n\tpublic setURL(url: string | null): this {\n\t\tthis.data.url = url ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Transforms the embed to a plain object\n\t */\n\tpublic toJSON(): APIEmbed {\n\t\treturn { ...this.data };\n\t}\n\n\tpublic equals(other: UnsafeEmbed | APIEmbed) {\n\t\tconst { image: thisImage, thumbnail: thisThumbnail, ...thisData } = this.data;\n\t\tconst data = other instanceof UnsafeEmbed ? other.data : other;\n\t\tconst { image, thumbnail, ...otherData } = data;\n\t\treturn isEqual(otherData, thisData) && image?.url === thisImage?.url && thumbnail?.url === thisThumbnail?.url;\n\t}\n}\n","import type { APIEmbedField } from 'discord-api-types/v9';\nimport {\n\tauthorNamePredicate,\n\tcolorPredicate,\n\tdescriptionPredicate,\n\tembedFieldsArrayPredicate,\n\tfooterTextPredicate,\n\ttimestampPredicate,\n\ttitlePredicate,\n\turlPredicate,\n\tvalidateFieldLength,\n} from './Assertions';\nimport { EmbedAuthorOptions, EmbedFooterOptions, RGBTuple, UnsafeEmbed } from './UnsafeEmbed';\n\n/**\n * Represents a validated embed in a message (image/video preview, rich embed, etc.)\n */\nexport class Embed extends UnsafeEmbed {\n\tpublic override addFields(...fields: APIEmbedField[]): this {\n\t\t// Ensure adding these fields won't exceed the 25 field limit\n\t\tvalidateFieldLength(fields.length, this.fields);\n\n\t\t// Data assertions\n\t\treturn super.addFields(...embedFieldsArrayPredicate.parse(fields));\n\t}\n\n\tpublic override spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this {\n\t\t// Ensure adding these fields won't exceed the 25 field limit\n\t\tvalidateFieldLength(fields.length - deleteCount, this.fields);\n\n\t\t// Data assertions\n\t\treturn super.spliceFields(index, deleteCount, ...embedFieldsArrayPredicate.parse(fields));\n\t}\n\n\tpublic override setAuthor(options: EmbedAuthorOptions | null): this {\n\t\tif (options === null) {\n\t\t\treturn super.setAuthor(null);\n\t\t}\n\n\t\t// Data assertions\n\t\tauthorNamePredicate.parse(options.name);\n\t\turlPredicate.parse(options.iconURL);\n\t\turlPredicate.parse(options.url);\n\n\t\treturn super.setAuthor(options);\n\t}\n\n\tpublic override setColor(color: number | RGBTuple | null): this {\n\t\t// Data assertions\n\t\treturn super.setColor(colorPredicate.parse(color));\n\t}\n\n\tpublic override setDescription(description: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setDescription(descriptionPredicate.parse(description));\n\t}\n\n\tpublic override setFooter(options: EmbedFooterOptions | null): this {\n\t\tif (options === null) {\n\t\t\treturn super.setFooter(null);\n\t\t}\n\n\t\t// Data assertions\n\t\tfooterTextPredicate.parse(options.text);\n\t\turlPredicate.parse(options.iconURL);\n\n\t\treturn super.setFooter(options);\n\t}\n\n\tpublic override setImage(url: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setImage(urlPredicate.parse(url)!);\n\t}\n\n\tpublic override setThumbnail(url: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setThumbnail(urlPredicate.parse(url)!);\n\t}\n\n\tpublic override setTimestamp(timestamp: number | Date | null = Date.now()): this {\n\t\t// Data assertions\n\t\treturn super.setTimestamp(timestampPredicate.parse(timestamp));\n\t}\n\n\tpublic override setTitle(title: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setTitle(titlePredicate.parse(title));\n\t}\n\n\tpublic override setURL(url: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setURL(urlPredicate.parse(url)!);\n\t}\n}\n","import type { Snowflake } from 'discord-api-types/globals';\nimport type { URL } from 'url';\n\n/**\n * Wraps the content inside a codeblock with no language\n *\n * @param content The content to wrap\n */\nexport function codeBlock<C extends string>(content: C): `\\`\\`\\`\\n${C}\\`\\`\\``;\n\n/**\n * Wraps the content inside a codeblock with the specified language\n *\n * @param language The language for the codeblock\n * @param content The content to wrap\n */\nexport function codeBlock<L extends string, C extends string>(language: L, content: C): `\\`\\`\\`${L}\\n${C}\\`\\`\\``;\nexport function codeBlock(language: string, content?: string): string {\n\treturn typeof content === 'undefined' ? `\\`\\`\\`\\n${language}\\`\\`\\`` : `\\`\\`\\`${language}\\n${content}\\`\\`\\``;\n}\n\n/**\n * Wraps the content inside \\`backticks\\`, which formats it as inline code\n *\n * @param content The content to wrap\n */\nexport function inlineCode<C extends string>(content: C): `\\`${C}\\`` {\n\treturn `\\`${content}\\``;\n}\n\n/**\n * Formats the content into italic text\n *\n * @param content The content to wrap\n */\nexport function italic<C extends string>(content: C): `_${C}_` {\n\treturn `_${content}_`;\n}\n\n/**\n * Formats the content into bold text\n *\n * @param content The content to wrap\n */\nexport function bold<C extends string>(content: C): `**${C}**` {\n\treturn `**${content}**`;\n}\n\n/**\n * Formats the content into underscored text\n *\n * @param content The content to wrap\n */\nexport function underscore<C extends string>(content: C): `__${C}__` {\n\treturn `__${content}__`;\n}\n\n/**\n * Formats the content into strike-through text\n *\n * @param content The content to wrap\n */\nexport function strikethrough<C extends string>(content: C): `~~${C}~~` {\n\treturn `~~${content}~~`;\n}\n\n/**\n * Formats the content into a quote. This needs to be at the start of the line for Discord to format it\n *\n * @param content The content to wrap\n */\nexport function quote<C extends string>(content: C): `> ${C}` {\n\treturn `> ${content}`;\n}\n\n/**\n * Formats the content into a block quote. This needs to be at the start of the line for Discord to format it\n *\n * @param content The content to wrap\n */\nexport function blockQuote<C extends string>(content: C): `>>> ${C}` {\n\treturn `>>> ${content}`;\n}\n\n/**\n * Wraps the URL into `<>`, which stops it from embedding\n *\n * @param url The URL to wrap\n */\nexport function hideLinkEmbed<C extends string>(url: C): `<${C}>`;\n\n/**\n * Wraps the URL into `<>`, which stops it from embedding\n *\n * @param url The URL to wrap\n */\nexport function hideLinkEmbed(url: URL): `<${string}>`;\nexport function hideLinkEmbed(url: string | URL) {\n\t// eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n\treturn `<${url}>`;\n}\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n */\nexport function hyperlink<C extends string>(content: C, url: URL): `[${C}](${string})`;\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n */\nexport function hyperlink<C extends string, U extends string>(content: C, url: U): `[${C}](${U})`;\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n * @param title The title shown when hovering on the masked link\n */\nexport function hyperlink<C extends string, T extends string>(\n\tcontent: C,\n\turl: URL,\n\ttitle: T,\n): `[${C}](${string} \"${T}\")`;\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n * @param title The title shown when hovering on the masked link\n */\nexport function hyperlink<C extends string, U extends string, T extends string>(\n\tcontent: C,\n\turl: U,\n\ttitle: T,\n): `[${C}](${U} \"${T}\")`;\nexport function hyperlink(content: string, url: string | URL, title?: string) {\n\t// eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n\treturn title ? `[${content}](${url} \"${title}\")` : `[${content}](${url})`;\n}\n\n/**\n * Wraps the content inside spoiler (hidden text)\n *\n * @param content The content to wrap\n */\nexport function spoiler<C extends string>(content: C): `||${C}||` {\n\treturn `||${content}||`;\n}\n\n/**\n * Formats a user ID into a user mention\n *\n * @param userId The user ID to format\n */\nexport function userMention<C extends Snowflake>(userId: C): `<@${C}>` {\n\treturn `<@${userId}>`;\n}\n\n/**\n * Formats a user ID into a member-nickname mention\n *\n * @param memberId The user ID to format\n */\nexport function memberNicknameMention<C extends Snowflake>(memberId: C): `<@!${C}>` {\n\treturn `<@!${memberId}>`;\n}\n\n/**\n * Formats a channel ID into a channel mention\n *\n * @param channelId The channel ID to format\n */\nexport function channelMention<C extends Snowflake>(channelId: C): `<#${C}>` {\n\treturn `<#${channelId}>`;\n}\n\n/**\n * Formats a role ID into a role mention\n *\n * @param roleId The role ID to format\n */\nexport function roleMention<C extends Snowflake>(roleId: C): `<@&${C}>` {\n\treturn `<@&${roleId}>`;\n}\n\n/**\n * Formats an emoji ID into a fully qualified emoji identifier\n *\n * @param emojiId The emoji ID to format\n */\nexport function formatEmoji<C extends Snowflake>(emojiId: C, animated?: false): `<:_:${C}>`;\n\n/**\n * Formats an emoji ID into a fully qualified emoji identifier\n *\n * @param emojiId The emoji ID to format\n * @param animated Whether the emoji is animated or not. Defaults to `false`\n */\nexport function formatEmoji<C extends Snowflake>(emojiId: C, animated?: true): `<a:_:${C}>`;\n\n/**\n * Formats an emoji ID into a fully qualified emoji identifier\n *\n * @param emojiId The emoji ID to format\n * @param animated Whether the emoji is animated or not. Defaults to `false`\n */\nexport function formatEmoji<C extends Snowflake>(emojiId: C, animated = false): `<a:_:${C}>` | `<:_:${C}>` {\n\treturn `<${animated ? 'a' : ''}:_:${emojiId}>`;\n}\n\n/**\n * Formats a date into a short date-time string\n *\n * @param date The date to format, defaults to the current time\n */\nexport function time(date?: Date): `<t:${bigint}>`;\n\n/**\n * Formats a date given a format style\n *\n * @param date The date to format\n * @param style The style to use\n */\nexport function time<S extends TimestampStylesString>(date: Date, style: S): `<t:${bigint}:${S}>`;\n\n/**\n * Formats the given timestamp into a short date-time string\n *\n * @param seconds The time to format, represents an UNIX timestamp in seconds\n */\nexport function time<C extends number>(seconds: C): `<t:${C}>`;\n\n/**\n * Formats the given timestamp into a short date-time string\n *\n * @param seconds The time to format, represents an UNIX timestamp in seconds\n * @param style The style to use\n */\nexport function time<C extends number, S extends TimestampStylesString>(seconds: C, style: S): `<t:${C}:${S}>`;\nexport function time(timeOrSeconds?: number | Date, style?: TimestampStylesString): string {\n\tif (typeof timeOrSeconds !== 'number') {\n\t\ttimeOrSeconds = Math.floor((timeOrSeconds?.getTime() ?? Date.now()) / 1000);\n\t}\n\n\treturn typeof style === 'string' ? `<t:${timeOrSeconds}:${style}>` : `<t:${timeOrSeconds}>`;\n}\n\n/**\n * The [message formatting timestamp styles](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles) supported by Discord\n */\nexport const TimestampStyles = {\n\t/**\n\t * Short time format, consisting of hours and minutes, e.g. 16:20\n\t */\n\tShortTime: 't',\n\n\t/**\n\t * Long time format, consisting of hours, minutes, and seconds, e.g. 16:20:30\n\t */\n\tLongTime: 'T',\n\n\t/**\n\t * Short date format, consisting of day, month, and year, e.g. 20/04/2021\n\t */\n\tShortDate: 'd',\n\n\t/**\n\t * Long date format, consisting of day, month, and year, e.g. 20 April 2021\n\t */\n\tLongDate: 'D',\n\n\t/**\n\t * Short date-time format, consisting of short date and short time formats, e.g. 20 April 2021 16:20\n\t */\n\tShortDateTime: 'f',\n\n\t/**\n\t * Long date-time format, consisting of long date and short time formats, e.g. Tuesday, 20 April 2021 16:20\n\t */\n\tLongDateTime: 'F',\n\n\t/**\n\t * Relative time format, consisting of a relative duration format, e.g. 2 months ago\n\t */\n\tRelativeTime: 'R',\n} as const;\n\n/**\n * The possible values, see {@link TimestampStyles} for more information\n */\nexport type TimestampStylesString = typeof TimestampStyles[keyof typeof TimestampStyles];\n\n/**\n * An enum with all the available faces from Discord's native slash commands\n */\nexport enum Faces {\n\t/**\n\t * ¯\\\\_(ツ)\\\\_/¯\n\t */\n\tShrug = '¯\\\\_(ツ)\\\\_/¯',\n\n\t/**\n\t * (╯°□°)╯︵ ┻━┻\n\t */\n\tTableflip = '(╯°□°)╯︵ ┻━┻',\n\n\t/**\n\t * ┬─┬ ノ( ゜-゜ノ)\n\t */\n\tUnflip = '┬─┬ ノ( ゜-゜ノ)',\n}\n","import { APIMessageComponentEmoji, ButtonStyle } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport type { SelectMenuOption } from './selectMenu/SelectMenuOption';\n\nexport const customIdValidator = z.string().min(1).max(100);\n\nexport const emojiValidator = z\n\t.object({\n\t\tid: z.string(),\n\t\tname: z.string(),\n\t\tanimated: z.boolean(),\n\t})\n\t.partial()\n\t.strict();\n\nexport const disabledValidator = z.boolean();\n\nexport const buttonLabelValidator = z.string().nonempty().max(80);\n\nexport const buttonStyleValidator = z.number().int().min(ButtonStyle.Primary).max(ButtonStyle.Link);\n\nexport const placeholderValidator = z.string().max(100);\nexport const minMaxValidator = z.number().int().min(0).max(25);\n\nexport const optionsValidator = z.object({}).array().nonempty();\n\nexport function validateRequiredSelectMenuParameters(options: SelectMenuOption[], customId?: string) {\n\tcustomIdValidator.parse(customId);\n\toptionsValidator.parse(options);\n}\n\nexport const labelValueValidator = z.string().min(1).max(100);\nexport const defaultValidator = z.boolean();\n\nexport function validateRequiredSelectMenuOptionParameters(label?: string, value?: string) {\n\tlabelValueValidator.parse(label);\n\tlabelValueValidator.parse(value);\n}\n\nexport const urlValidator = z.string().url();\n\nexport function validateRequiredButtonParameters(\n\tstyle?: ButtonStyle,\n\tlabel?: string,\n\temoji?: APIMessageComponentEmoji,\n\tcustomId?: string,\n\turl?: string,\n) {\n\tif (url && customId) {\n\t\tthrow new RangeError('URL and custom id are mutually exclusive');\n\t}\n\n\tif (!label && !emoji) {\n\t\tthrow new RangeError('Buttons must have a label and/or an emoji');\n\t}\n\n\tif (style === ButtonStyle.Link) {\n\t\tif (!url) {\n\t\t\tthrow new RangeError('Link buttons must have a url');\n\t\t}\n\t} else if (url) {\n\t\tthrow new RangeError('Non-link buttons cannot have a url');\n\t}\n}\n","import {\n\tAPIActionRowComponent,\n\tAPIMessageActionRowComponent,\n\tAPIModalActionRowComponent,\n\tComponentType,\n} from 'discord-api-types/v9';\nimport type { ButtonComponent, SelectMenuComponent, TextInputComponent } from '../index';\nimport { Component } from './Component';\nimport { createComponent } from './Components';\nimport isEqual from 'fast-deep-equal';\n\nexport type MessageComponent = MessageActionRowComponent | ActionRow<MessageActionRowComponent>;\nexport type ModalComponent = ModalActionRowComponent | ActionRow<ModalActionRowComponent>;\n\nexport type MessageActionRowComponent = ButtonComponent | SelectMenuComponent;\nexport type ModalActionRowComponent = TextInputComponent;\n\n/**\n * Represents an action row component\n */\nexport class ActionRow<\n\tT extends ModalActionRowComponent | MessageActionRowComponent = ModalActionRowComponent | MessageActionRowComponent,\n> extends Component<\n\tOmit<\n\t\tPartial<APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>> & {\n\t\t\ttype: ComponentType.ActionRow;\n\t\t},\n\t\t'components'\n\t>\n> {\n\t/**\n\t * The components within this action row\n\t */\n\tpublic readonly components: T[];\n\n\tpublic constructor({\n\t\tcomponents,\n\t\t...data\n\t}: Partial<APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>> = {}) {\n\t\tsuper({ type: ComponentType.ActionRow, ...data });\n\t\tthis.components = (components?.map((c) => createComponent(c)) ?? []) as T[];\n\t}\n\n\t/**\n\t * Adds components to this action row.\n\t * @param components The components to add to this action row.\n\t * @returns\n\t */\n\tpublic addComponents(...components: T[]) {\n\t\tthis.components.push(...components);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the components in this action row\n\t * @param components The components to set this row to\n\t */\n\tpublic setComponents(...components: T[]) {\n\t\tthis.components.splice(0, this.components.length, ...components);\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIActionRowComponent<ReturnType<T['toJSON']>> {\n\t\treturn {\n\t\t\t...this.data,\n\t\t\tcomponents: this.components.map((component) => component.toJSON()) as ReturnType<T['toJSON']>[],\n\t\t};\n\t}\n\n\tpublic equals(other: APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent> | ActionRow) {\n\t\tif (other instanceof ActionRow) {\n\t\t\treturn isEqual(other.data, this.data) && isEqual(other.components, this.components);\n\t\t}\n\t\treturn isEqual(other, {\n\t\t\t...this.data,\n\t\t\tcomponents: this.components.map((component) => component.toJSON()),\n\t\t});\n\t}\n}\n","import type { JSONEncodable } from '../util/jsonEncodable';\nimport type {\n\tAPIActionRowComponent,\n\tAPIActionRowComponentTypes,\n\tAPIBaseComponent,\n\tAPIMessageActionRowComponent,\n\tAPIModalActionRowComponent,\n\tAPIMessageComponent,\n\tComponentType,\n\tAPIModalComponent,\n} from 'discord-api-types/v9';\nimport type { Equatable } from '../util/equatable';\n\n/**\n * Represents a discord component\n */\nexport abstract class Component<\n\tDataType extends Partial<APIBaseComponent<ComponentType>> & {\n\t\ttype: ComponentType;\n\t} = APIBaseComponent<ComponentType>,\n> implements\n\t\tJSONEncodable<\n\t\t\t| APIModalComponent\n\t\t\t| APIMessageComponent\n\t\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>\n\t\t>,\n\t\tEquatable<\n\t\t\t| Component\n\t\t\t| APIActionRowComponentTypes\n\t\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>\n\t\t>\n{\n\t/**\n\t * The API data associated with this component\n\t */\n\tpublic readonly data: DataType;\n\n\tpublic abstract toJSON():\n\t\t| APIActionRowComponentTypes\n\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>;\n\n\tpublic abstract equals(\n\t\tother:\n\t\t\t| Component\n\t\t\t| APIActionRowComponentTypes\n\t\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>,\n\t): boolean;\n\n\tpublic constructor(data: DataType) {\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * The type of this component\n\t */\n\tpublic get type(): DataType['type'] {\n\t\treturn this.data.type;\n\t}\n}\n","import { APIBaseComponent, APIMessageComponent, APIModalComponent, ComponentType } from 'discord-api-types/v9';\nimport { ActionRow, ButtonComponent, Component, SelectMenuComponent, TextInputComponent } from '../index';\nimport type { MessageComponent, ModalActionRowComponent } from './ActionRow';\n\nexport interface MappedComponentTypes {\n\t[ComponentType.ActionRow]: ActionRow;\n\t[ComponentType.Button]: ButtonComponent;\n\t[ComponentType.SelectMenu]: SelectMenuComponent;\n\t[ComponentType.TextInput]: TextInputComponent;\n}\n\n/**\n * Factory for creating components from API data\n * @param data The api data to transform to a component class\n */\nexport function createComponent<T extends keyof MappedComponentTypes>(\n\tdata: (APIMessageComponent | APIModalComponent) & { type: T },\n): MappedComponentTypes[T];\nexport function createComponent<C extends MessageComponent | ModalActionRowComponent>(data: C): C;\nexport function createComponent(data: APIModalComponent | APIMessageComponent | Component): Component {\n\tif (data instanceof Component) {\n\t\treturn data;\n\t}\n\n\tswitch (data.type) {\n\t\tcase ComponentType.ActionRow:\n\t\t\treturn new ActionRow(data);\n\t\tcase ComponentType.Button:\n\t\t\treturn new ButtonComponent(data);\n\t\tcase ComponentType.SelectMenu:\n\t\t\treturn new SelectMenuComponent(data);\n\t\tcase ComponentType.TextInput:\n\t\t\treturn new TextInputComponent(data);\n\t\tdefault:\n\t\t\tthrow new Error(`Cannot serialize component type: ${(data as APIBaseComponent<ComponentType>).type}`);\n\t}\n}\n","import {\n\tComponentType,\n\tButtonStyle,\n\ttype APIMessageComponentEmoji,\n\ttype APIButtonComponent,\n\ttype APIButtonComponentWithURL,\n\ttype APIButtonComponentWithCustomId,\n} from 'discord-api-types/v9';\nimport { Component } from '../Component';\nimport isEqual from 'fast-deep-equal';\n\n/**\n * Represents a non-validated button component\n */\nexport class UnsafeButtonComponent extends Component<Partial<APIButtonComponent> & { type: ComponentType.Button }> {\n\tpublic constructor(data?: Partial<APIButtonComponent>) {\n\t\tsuper({ type: ComponentType.Button, ...data });\n\t}\n\n\t/**\n\t * The style of this button\n\t */\n\tpublic get style() {\n\t\treturn this.data.style;\n\t}\n\n\t/**\n\t * The label of this button\n\t */\n\tpublic get label() {\n\t\treturn this.data.label;\n\t}\n\n\t/**\n\t * The emoji used in this button\n\t */\n\tpublic get emoji() {\n\t\treturn this.data.emoji;\n\t}\n\n\t/**\n\t * Whether this button is disabled\n\t */\n\tpublic get disabled() {\n\t\treturn this.data.disabled;\n\t}\n\n\t/**\n\t * The custom id of this button (only defined on non-link buttons)\n\t */\n\tpublic get customId(): string | undefined {\n\t\treturn (this.data as APIButtonComponentWithCustomId).custom_id;\n\t}\n\n\t/**\n\t * The URL of this button (only defined on link buttons)\n\t */\n\tpublic get url(): string | undefined {\n\t\treturn (this.data as APIButtonComponentWithURL).url;\n\t}\n\n\t/**\n\t * Sets the style of this button\n\t * @param style The style of the button\n\t */\n\tpublic setStyle(style: ButtonStyle) {\n\t\tthis.data.style = style;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the URL for this button\n\t * @param url The URL to open when this button is clicked\n\t */\n\tpublic setURL(url: string) {\n\t\t(this.data as APIButtonComponentWithURL).url = url;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the custom Id for this button\n\t * @param customId The custom id to use for this button\n\t */\n\tpublic setCustomId(customId: string) {\n\t\t(this.data as APIButtonComponentWithCustomId).custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the emoji to display on this button\n\t * @param emoji The emoji to display on this button\n\t */\n\tpublic setEmoji(emoji: APIMessageComponentEmoji) {\n\t\tthis.data.emoji = emoji;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether this button is disable or not\n\t * @param disabled Whether or not to disable this button or not\n\t */\n\tpublic setDisabled(disabled = true) {\n\t\tthis.data.disabled = disabled;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the label for this button\n\t * @param label The label to display on this button\n\t */\n\tpublic setLabel(label: string) {\n\t\tthis.data.label = label;\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIButtonComponent {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t} as APIButtonComponent;\n\t}\n\n\tpublic equals(other: APIButtonComponent | UnsafeButtonComponent) {\n\t\tif (other instanceof UnsafeButtonComponent) {\n\t\t\treturn isEqual(other.data, this.data);\n\t\t}\n\t\treturn isEqual(other, this.data);\n\t}\n}\n","import type { ButtonStyle, APIMessageComponentEmoji, APIButtonComponent } from 'discord-api-types/v9';\nimport {\n\tbuttonLabelValidator,\n\tbuttonStyleValidator,\n\tcustomIdValidator,\n\tdisabledValidator,\n\temojiValidator,\n\turlValidator,\n\tvalidateRequiredButtonParameters,\n} from '../Assertions';\nimport { UnsafeButtonComponent } from './UnsafeButton';\n\n/**\n * Represents a validated button component\n */\nexport class ButtonComponent extends UnsafeButtonComponent {\n\tpublic override setStyle(style: ButtonStyle) {\n\t\treturn super.setStyle(buttonStyleValidator.parse(style));\n\t}\n\n\tpublic override setURL(url: string) {\n\t\treturn super.setURL(urlValidator.parse(url));\n\t}\n\n\tpublic override setCustomId(customId: string) {\n\t\treturn super.setCustomId(customIdValidator.parse(customId));\n\t}\n\n\tpublic override setEmoji(emoji: APIMessageComponentEmoji) {\n\t\treturn super.setEmoji(emojiValidator.parse(emoji));\n\t}\n\n\tpublic override setDisabled(disabled = true) {\n\t\treturn super.setDisabled(disabledValidator.parse(disabled));\n\t}\n\n\tpublic override setLabel(label: string) {\n\t\treturn super.setLabel(buttonLabelValidator.parse(label));\n\t}\n\n\tpublic override toJSON(): APIButtonComponent {\n\t\tvalidateRequiredButtonParameters(this.style, this.label, this.emoji, this.customId, this.url);\n\t\treturn super.toJSON();\n\t}\n}\n","import { TextInputStyle } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport { customIdValidator } from '../Assertions';\n\nexport const textInputStyleValidator = z.nativeEnum(TextInputStyle);\nexport const minLengthValidator = z.number().int().min(0).max(4000);\nexport const maxLengthValidator = z.number().int().min(1).max(4000);\nexport const requiredValidator = z.boolean();\nexport const valueValidator = z.string().max(4000);\nexport const placeholderValidator = z.string().max(100);\nexport const labelValidator = z.string().min(1).max(45);\n\nexport function validateRequiredParameters(customId?: string, style?: TextInputStyle, label?: string) {\n\tcustomIdValidator.parse(customId);\n\ttextInputStyleValidator.parse(style);\n\tlabelValidator.parse(label);\n}\n","import { ComponentType, type TextInputStyle, type APITextInputComponent } from 'discord-api-types/v9';\nimport { Component } from '../../index';\nimport isEqual from 'fast-deep-equal';\n\nexport class UnsafeTextInputComponent extends Component<\n\tPartial<APITextInputComponent> & { type: ComponentType.TextInput }\n> {\n\tpublic constructor(data?: APITextInputComponent & { type?: ComponentType.TextInput }) {\n\t\tsuper({ type: ComponentType.TextInput, ...data });\n\t}\n\n\t/**\n\t * The style of this text input\n\t */\n\tpublic get style() {\n\t\treturn this.data.style;\n\t}\n\n\t/**\n\t * The custom id of this text input\n\t */\n\tpublic get customId() {\n\t\treturn this.data.custom_id;\n\t}\n\n\t/**\n\t * The label for this text input\n\t */\n\tpublic get label() {\n\t\treturn this.data.label;\n\t}\n\n\t/**\n\t * The placeholder text for this text input\n\t */\n\tpublic get placeholder() {\n\t\treturn this.data.placeholder;\n\t}\n\n\t/**\n\t * The default value for this text input\n\t */\n\tpublic get value() {\n\t\treturn this.data.value;\n\t}\n\n\t/**\n\t * The minimum length of this text input\n\t */\n\tpublic get minLength() {\n\t\treturn this.data.min_length;\n\t}\n\n\t/**\n\t * The maximum length of this text input\n\t */\n\tpublic get maxLength() {\n\t\treturn this.data.max_length;\n\t}\n\n\t/**\n\t * Whether this text input is required\n\t */\n\tpublic get required() {\n\t\treturn this.data.required;\n\t}\n\n\t/**\n\t * Sets the custom id for this text input\n\t * @param customId The custom id of this text input\n\t */\n\tpublic setCustomId(customId: string) {\n\t\tthis.data.custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the label for this text input\n\t * @param label The label for this text input\n\t */\n\tpublic setLabel(label: string) {\n\t\tthis.data.label = label;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the style for this text input\n\t * @param style The style for this text input\n\t */\n\tpublic setStyle(style: TextInputStyle) {\n\t\tthis.data.style = style;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the minimum length of text for this text input\n\t * @param minLength The minimum length of text for this text input\n\t */\n\tpublic setMinLength(minLength: number) {\n\t\tthis.data.min_length = minLength;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum length of text for this text input\n\t * @param maxLength The maximum length of text for this text input\n\t */\n\tpublic setMaxLength(maxLength: number) {\n\t\tthis.data.max_length = maxLength;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the placeholder of this text input\n\t * @param placeholder The placeholder of this text input\n\t */\n\tpublic setPlaceholder(placeholder: string) {\n\t\tthis.data.placeholder = placeholder;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of this text input\n\t * @param value The value for this text input\n\t */\n\tpublic setValue(value: string) {\n\t\tthis.data.value = value;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether this text input is required or not\n\t * @param required Whether this text input is required or not\n\t */\n\tpublic setRequired(required = true) {\n\t\tthis.data.required = required;\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APITextInputComponent {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t} as APITextInputComponent;\n\t}\n\n\tpublic equals(other: UnsafeTextInputComponent | APITextInputComponent): boolean {\n\t\tif (other instanceof UnsafeTextInputComponent) {\n\t\t\treturn isEqual(other.data, this.data);\n\t\t}\n\n\t\treturn isEqual(other, this.data);\n\t}\n}\n","import type { APITextInputComponent } from 'discord-api-types/v9';\nimport {\n\tmaxLengthValidator,\n\tminLengthValidator,\n\tplaceholderValidator,\n\trequiredValidator,\n\tvalueValidator,\n\tvalidateRequiredParameters,\n} from './Assertions';\nimport { UnsafeTextInputComponent } from './UnsafeTextInput';\n\nexport class TextInputComponent extends UnsafeTextInputComponent {\n\tpublic override setMinLength(minLength: number) {\n\t\treturn super.setMinLength(minLengthValidator.parse(minLength));\n\t}\n\n\tpublic override setMaxLength(maxLength: number) {\n\t\treturn super.setMaxLength(maxLengthValidator.parse(maxLength));\n\t}\n\n\tpublic override setRequired(required = true) {\n\t\treturn super.setRequired(requiredValidator.parse(required));\n\t}\n\n\tpublic override setValue(value: string) {\n\t\treturn super.setValue(valueValidator.parse(value));\n\t}\n\n\tpublic override setPlaceholder(placeholder: string) {\n\t\treturn super.setPlaceholder(placeholderValidator.parse(placeholder));\n\t}\n\n\tpublic override toJSON(): APITextInputComponent {\n\t\tvalidateRequiredParameters(this.data.custom_id, this.data.style, this.data.label);\n\t\treturn super.toJSON();\n\t}\n}\n","import type {\n\tAPIActionRowComponent,\n\tAPIModalActionRowComponent,\n\tAPIModalInteractionResponseCallbackData,\n} from 'discord-api-types/v9';\nimport { ActionRow, createComponent, JSONEncodable, ModalActionRowComponent } from '../../index';\n\nexport class UnsafeModal implements JSONEncodable<APIModalInteractionResponseCallbackData> {\n\tprotected readonly data: Partial<Omit<APIModalInteractionResponseCallbackData, 'components'>>;\n\tpublic readonly components: ActionRow<ModalActionRowComponent>[] = [];\n\n\tpublic constructor({ components, ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) {\n\t\tthis.data = { ...data };\n\t\tthis.components = (components?.map((c) => createComponent(c)) ?? []) as ActionRow<ModalActionRowComponent>[];\n\t}\n\n\t/**\n\t * The custom id of this modal\n\t */\n\tpublic get customId() {\n\t\treturn this.data.custom_id;\n\t}\n\n\t/**\n\t * The title of this modal\n\t */\n\tpublic get title() {\n\t\treturn this.data.title;\n\t}\n\n\t/**\n\t * Sets the title of the modal\n\t * @param title The title of the modal\n\t */\n\tpublic setTitle(title: string) {\n\t\tthis.data.title = title;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the custom id of the modal\n\t * @param customId The custom id of this modal\n\t */\n\tpublic setCustomId(customId: string) {\n\t\tthis.data.custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds components to this modal\n\t * @param components The components to add to this modal\n\t */\n\tpublic addComponents(\n\t\t...components: (ActionRow<ModalActionRowComponent> | APIActionRowComponent<APIModalActionRowComponent>)[]\n\t) {\n\t\tthis.components.push(\n\t\t\t...components.map((component) =>\n\t\t\t\tcomponent instanceof ActionRow ? component : new ActionRow<ModalActionRowComponent>(component),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the components in this modal\n\t * @param components The components to set this modal to\n\t */\n\tpublic setComponents(...components: ActionRow<ModalActionRowComponent>[]) {\n\t\tthis.components.splice(0, this.components.length, ...components);\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIModalInteractionResponseCallbackData {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t\tcomponents: this.components.map((component) => component.toJSON()),\n\t\t} as APIModalInteractionResponseCallbackData;\n\t}\n}\n","import { z } from 'zod';\nimport { ActionRow, type ModalActionRowComponent } from '../..';\nimport { customIdValidator } from '../../components/Assertions';\n\nexport const titleValidator = z.string().min(1).max(45);\nexport const componentsValidator = z.array(z.instanceof(ActionRow)).min(1);\n\nexport function validateRequiredParameters(\n\tcustomId?: string,\n\ttitle?: string,\n\tcomponents?: ActionRow<ModalActionRowComponent>[],\n) {\n\tcustomIdValidator.parse(customId);\n\ttitleValidator.parse(title);\n\tcomponentsValidator.parse(components);\n}\n","import type { APIModalInteractionResponseCallbackData } from 'discord-api-types/v9';\nimport { customIdValidator } from '../../components/Assertions';\nimport { titleValidator, validateRequiredParameters } from './Assertions';\nimport { UnsafeModal } from './UnsafeModal';\n\nexport class Modal extends UnsafeModal {\n\tpublic override setCustomId(customId: string): this {\n\t\treturn super.setCustomId(customIdValidator.parse(customId));\n\t}\n\n\tpublic override setTitle(title: string) {\n\t\treturn super.setTitle(titleValidator.parse(title));\n\t}\n\n\tpublic override toJSON(): APIModalInteractionResponseCallbackData {\n\t\tvalidateRequiredParameters(this.data.custom_id, this.data.title, this.components);\n\t\treturn super.toJSON();\n\t}\n}\n","import { APISelectMenuOption, ComponentType, type APISelectMenuComponent } from 'discord-api-types/v9';\nimport { Component } from '../Component';\nimport { UnsafeSelectMenuOption } from './UnsafeSelectMenuOption';\nimport isEqual from 'fast-deep-equal';\n\n/**\n * Represents a non-validated select menu component\n */\nexport class UnsafeSelectMenuComponent extends Component<\n\tPartial<Omit<APISelectMenuComponent, 'options'>> & { type: ComponentType.SelectMenu }\n> {\n\t/**\n\t * The options within this select menu\n\t */\n\tpublic readonly options: UnsafeSelectMenuOption[];\n\n\tpublic constructor(data?: Partial<APISelectMenuComponent>) {\n\t\tconst { options, ...initData } = data ?? {};\n\t\tsuper({ type: ComponentType.SelectMenu, ...initData });\n\t\tthis.options = options?.map((o) => new UnsafeSelectMenuOption(o)) ?? [];\n\t}\n\n\t/**\n\t * The placeholder for this select menu\n\t */\n\tpublic get placeholder() {\n\t\treturn this.data.placeholder;\n\t}\n\n\t/**\n\t * The maximum amount of options that can be selected\n\t */\n\tpublic get maxValues() {\n\t\treturn this.data.max_values;\n\t}\n\n\t/**\n\t * The minimum amount of options that must be selected\n\t */\n\tpublic get minValues() {\n\t\treturn this.data.min_values;\n\t}\n\n\t/**\n\t * The custom id of this select menu\n\t */\n\tpublic get customId() {\n\t\treturn this.data.custom_id;\n\t}\n\n\t/**\n\t * Whether this select menu is disabled\n\t */\n\tpublic get disabled() {\n\t\treturn this.data.disabled;\n\t}\n\n\t/**\n\t * Sets the placeholder for this select menu\n\t * @param placeholder The placeholder to use for this select menu\n\t */\n\tpublic setPlaceholder(placeholder: string) {\n\t\tthis.data.placeholder = placeholder;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the minimum values that must be selected in the select menu\n\t * @param minValues The minimum values that must be selected\n\t */\n\tpublic setMinValues(minValues: number) {\n\t\tthis.data.min_values = minValues;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum values that must be selected in the select menu\n\t * @param minValues The maximum values that must be selected\n\t */\n\tpublic setMaxValues(maxValues: number) {\n\t\tthis.data.max_values = maxValues;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the custom Id for this select menu\n\t * @param customId The custom id to use for this select menu\n\t */\n\tpublic setCustomId(customId: string) {\n\t\tthis.data.custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether or not this select menu is disabled\n\t * @param disabled Whether or not this select menu is disabled\n\t */\n\tpublic setDisabled(disabled = true) {\n\t\tthis.data.disabled = disabled;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds options to this select menu\n\t * @param options The options to add to this select menu\n\t * @returns\n\t */\n\tpublic addOptions(...options: (UnsafeSelectMenuOption | APISelectMenuOption)[]) {\n\t\tthis.options.push(\n\t\t\t...options.map((option) =>\n\t\t\t\toption instanceof UnsafeSelectMenuOption ? option : new UnsafeSelectMenuOption(option),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the options on this select menu\n\t * @param options The options to set on this select menu\n\t */\n\tpublic setOptions(...options: (UnsafeSelectMenuOption | APISelectMenuOption)[]) {\n\t\tthis.options.splice(\n\t\t\t0,\n\t\t\tthis.options.length,\n\t\t\t...options.map((option) =>\n\t\t\t\toption instanceof UnsafeSelectMenuOption ? option : new UnsafeSelectMenuOption(option),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APISelectMenuComponent {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t\toptions: this.options.map((o) => o.toJSON()),\n\t\t} as APISelectMenuComponent;\n\t}\n\n\tpublic equals(other: APISelectMenuComponent | UnsafeSelectMenuComponent): boolean {\n\t\tif (other instanceof UnsafeSelectMenuComponent) {\n\t\t\treturn isEqual(other.data, this.data) && isEqual(other.options, this.options);\n\t\t}\n\t\treturn isEqual(other, {\n\t\t\t...this.data,\n\t\t\toptions: this.options.map((o) => o.toJSON()),\n\t\t});\n\t}\n}\n","import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v9';\n\n/**\n * Represents a non-validated option within a select menu component\n */\nexport class UnsafeSelectMenuOption {\n\tpublic constructor(protected data: Partial<APISelectMenuOption> = {}) {}\n\n\t/**\n\t * The label for this option\n\t */\n\tpublic get label() {\n\t\treturn this.data.label;\n\t}\n\n\t/**\n\t * The value for this option\n\t */\n\tpublic get value() {\n\t\treturn this.data.value;\n\t}\n\n\t/**\n\t * The description for this option\n\t */\n\tpublic get description() {\n\t\treturn this.data.description;\n\t}\n\n\t/**\n\t * The emoji for this option\n\t */\n\tpublic get emoji() {\n\t\treturn this.data.emoji;\n\t}\n\n\t/**\n\t * Whether this option is selected by default\n\t */\n\tpublic get default() {\n\t\treturn this.data.default;\n\t}\n\n\t/**\n\t * Sets the label of this option\n\t * @param label The label to show on this option\n\t */\n\tpublic setLabel(label: string) {\n\t\tthis.data.label = label;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of this option\n\t * @param value The value of this option\n\t */\n\tpublic setValue(value: string) {\n\t\tthis.data.value = value;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the description of this option.\n\t * @param description The description of this option\n\t */\n\tpublic setDescription(description: string) {\n\t\tthis.data.description = description;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether this option is selected by default\n\t * @param isDefault Whether this option is selected by default\n\t */\n\tpublic setDefault(isDefault = true) {\n\t\tthis.data.default = isDefault;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the emoji to display on this button\n\t * @param emoji The emoji to display on this button\n\t */\n\tpublic setEmoji(emoji: APIMessageComponentEmoji) {\n\t\tthis.data.emoji = emoji;\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APISelectMenuOption {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t} as APISelectMenuOption;\n\t}\n}\n","import type { APISelectMenuComponent } from 'discord-api-types/v9';\nimport {\n\tcustomIdValidator,\n\tdisabledValidator,\n\tminMaxValidator,\n\tplaceholderValidator,\n\tvalidateRequiredSelectMenuParameters,\n} from '../Assertions';\nimport { UnsafeSelectMenuComponent } from './UnsafeSelectMenu';\n\n/**\n * Represents a validated select menu component\n */\nexport class SelectMenuComponent extends UnsafeSelectMenuComponent {\n\tpublic override setPlaceholder(placeholder: string) {\n\t\treturn super.setPlaceholder(placeholderValidator.parse(placeholder));\n\t}\n\n\tpublic override setMinValues(minValues: number) {\n\t\treturn super.setMinValues(minMaxValidator.parse(minValues));\n\t}\n\n\tpublic override setMaxValues(maxValues: number) {\n\t\treturn super.setMaxValues(minMaxValidator.parse(maxValues));\n\t}\n\n\tpublic override setCustomId(customId: string) {\n\t\treturn super.setCustomId(customIdValidator.parse(customId));\n\t}\n\n\tpublic override setDisabled(disabled = true) {\n\t\treturn super.setDisabled(disabledValidator.parse(disabled));\n\t}\n\n\tpublic override toJSON(): APISelectMenuComponent {\n\t\tvalidateRequiredSelectMenuParameters(this.options, this.customId);\n\t\treturn super.toJSON();\n\t}\n}\n","import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v9';\nimport {\n\tdefaultValidator,\n\temojiValidator,\n\tlabelValueValidator,\n\tvalidateRequiredSelectMenuOptionParameters,\n} from '../Assertions';\nimport { UnsafeSelectMenuOption } from './UnsafeSelectMenuOption';\n\n/**\n * Represents a validated option within a select menu component\n */\nexport class SelectMenuOption extends UnsafeSelectMenuOption {\n\tpublic override setDescription(description: string) {\n\t\treturn super.setDescription(labelValueValidator.parse(description));\n\t}\n\n\tpublic override setDefault(isDefault = true) {\n\t\treturn super.setDefault(defaultValidator.parse(isDefault));\n\t}\n\n\tpublic override setEmoji(emoji: APIMessageComponentEmoji) {\n\t\treturn super.setEmoji(emojiValidator.parse(emoji));\n\t}\n\n\tpublic override toJSON(): APISelectMenuOption {\n\t\tvalidateRequiredSelectMenuOptionParameters(this.label, this.value);\n\t\treturn super.toJSON();\n\t}\n}\n","import is from '@sindresorhus/is';\nimport type { APIApplicationCommandOptionChoice } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase';\nimport type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder';\nimport type { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands';\n\nconst namePredicate = z\n\t.string()\n\t.min(1)\n\t.max(32)\n\t.regex(/^[\\P{Lu}\\p{N}_-]+$/u);\n\nexport function validateName(name: unknown): asserts name is string {\n\tnamePredicate.parse(name);\n}\n\nconst descriptionPredicate = z.string().min(1).max(100);\n\nexport function validateDescription(description: unknown): asserts description is string {\n\tdescriptionPredicate.parse(description);\n}\n\nconst maxArrayLengthPredicate = z.unknown().array().max(25);\n\nexport function validateMaxOptionsLength(options: unknown): asserts options is ToAPIApplicationCommandOptions[] {\n\tmaxArrayLengthPredicate.parse(options);\n}\n\nexport function validateRequiredParameters(\n\tname: string,\n\tdescription: string,\n\toptions: ToAPIApplicationCommandOptions[],\n) {\n\t// Assert name matches all conditions\n\tvalidateName(name);\n\n\t// Assert description conditions\n\tvalidateDescription(description);\n\n\t// Assert options conditions\n\tvalidateMaxOptionsLength(options);\n}\n\nconst booleanPredicate = z.boolean();\n\nexport function validateDefaultPermission(value: unknown): asserts value is boolean {\n\tbooleanPredicate.parse(value);\n}\n\nexport function validateRequired(required: unknown): asserts required is boolean {\n\tbooleanPredicate.parse(required);\n}\n\nconst choicesLengthPredicate = z.number().lte(25);\n\nexport function validateChoicesLength(amountAdding: number, choices?: APIApplicationCommandOptionChoice[]): void {\n\tchoicesLengthPredicate.parse((choices?.length ?? 0) + amountAdding);\n}\n\nexport function assertReturnOfBuilder<\n\tT extends ApplicationCommandOptionBase | SlashCommandSubcommandBuilder | SlashCommandSubcommandGroupBuilder,\n>(input: unknown, ExpectedInstanceOf: new () => T): asserts input is T {\n\tconst instanceName = ExpectedInstanceOf.name;\n\n\tif (is.nullOrUndefined(input)) {\n\t\tthrow new TypeError(\n\t\t\t`Expected to receive a ${instanceName} builder, got ${input === null ? 'null' : 'undefined'} instead.`,\n\t\t);\n\t}\n\n\tif (is.primitive(input)) {\n\t\tthrow new TypeError(`Expected to receive a ${instanceName} builder, got a primitive (${typeof input}) instead.`);\n\t}\n\n\tif (!(input instanceof ExpectedInstanceOf)) {\n\t\tconst casted = input as Record<PropertyKey, unknown>;\n\n\t\tconst constructorName = is.function_(input) ? input.name : casted.constructor.name;\n\t\tconst stringTag = Reflect.get(casted, Symbol.toStringTag) as string | undefined;\n\n\t\tconst fullResultName = stringTag ? `${constructorName} [${stringTag}]` : constructorName;\n\n\t\tthrow new TypeError(`Expected to receive a ${instanceName} builder, got ${fullResultName} instead.`);\n\t}\n}\n","import type { APIApplicationCommandOption, RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport {\n\tassertReturnOfBuilder,\n\tvalidateDefaultPermission,\n\tvalidateMaxOptionsLength,\n\tvalidateRequiredParameters,\n} from './Assertions';\nimport { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions';\nimport { SharedNameAndDescription } from './mixins/NameAndDescription';\nimport { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands';\n\n@mix(SharedSlashCommandOptions, SharedNameAndDescription)\nexport class SlashCommandBuilder {\n\t/**\n\t * The name of this slash command\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The description of this slash command\n\t */\n\tpublic readonly description: string = undefined!;\n\n\t/**\n\t * The options of this slash command\n\t */\n\tpublic readonly options: ToAPIApplicationCommandOptions[] = [];\n\n\t/**\n\t * Whether the command is enabled by default when the app is added to a guild\n\t *\n\t * @default true\n\t */\n\tpublic readonly defaultPermission: boolean | undefined = undefined;\n\n\t/**\n\t * Returns the final data that should be sent to Discord.\n\t *\n\t * **Note:** Calling this function will validate required properties based on their conditions.\n\t */\n\tpublic toJSON(): RESTPostAPIApplicationCommandsJSONBody {\n\t\tvalidateRequiredParameters(this.name, this.description, this.options);\n\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tdescription: this.description,\n\t\t\toptions: this.options.map((option) => option.toJSON()),\n\t\t\tdefault_permission: this.defaultPermission,\n\t\t};\n\t}\n\n\t/**\n\t * Sets whether the command is enabled by default when the application is added to a guild.\n\t *\n\t * **Note**: If set to `false`, you will have to later `PUT` the permissions for this command.\n\t *\n\t * @param value Whether or not to enable this command by default\n\t *\n\t * @see https://discord.com/developers/docs/interactions/application-commands#permissions\n\t */\n\tpublic setDefaultPermission(value: boolean) {\n\t\t// Assert the value matches the conditions\n\t\tvalidateDefaultPermission(value);\n\n\t\tReflect.set(this, 'defaultPermission', value);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a new subcommand group to this command\n\t *\n\t * @param input A function that returns a subcommand group builder, or an already built builder\n\t */\n\tpublic addSubcommandGroup(\n\t\tinput:\n\t\t\t| SlashCommandSubcommandGroupBuilder\n\t\t\t| ((subcommandGroup: SlashCommandSubcommandGroupBuilder) => SlashCommandSubcommandGroupBuilder),\n\t): SlashCommandSubcommandsOnlyBuilder {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\tconst result = typeof input === 'function' ? input(new SlashCommandSubcommandGroupBuilder()) : input;\n\n\t\tassertReturnOfBuilder(result, SlashCommandSubcommandGroupBuilder);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a new subcommand to this command\n\t *\n\t * @param input A function that returns a subcommand builder, or an already built builder\n\t */\n\tpublic addSubcommand(\n\t\tinput:\n\t\t\t| SlashCommandSubcommandBuilder\n\t\t\t| ((subcommandGroup: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder),\n\t): SlashCommandSubcommandsOnlyBuilder {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\tconst result = typeof input === 'function' ? input(new SlashCommandSubcommandBuilder()) : input;\n\n\t\tassertReturnOfBuilder(result, SlashCommandSubcommandBuilder);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n}\n\nexport interface SlashCommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions {}\n\nexport interface SlashCommandSubcommandsOnlyBuilder\n\textends SharedNameAndDescription,\n\t\tPick<SlashCommandBuilder, 'toJSON' | 'addSubcommand' | 'addSubcommandGroup'> {}\n\nexport interface SlashCommandOptionsOnlyBuilder\n\textends SharedNameAndDescription,\n\t\tSharedSlashCommandOptions,\n\t\tPick<SlashCommandBuilder, 'toJSON'> {}\n\nexport interface ToAPIApplicationCommandOptions {\n\ttoJSON: () => APIApplicationCommandOption;\n}\n","import { APIApplicationCommandBooleanOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandBooleanOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.Boolean as const;\n\n\tpublic toJSON(): APIApplicationCommandBooleanOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { validateDescription, validateName } from '../Assertions';\n\nexport class SharedNameAndDescription {\n\tpublic readonly name!: string;\n\tpublic readonly description!: string;\n\n\t/**\n\t * Sets the name\n\t *\n\t * @param name The name\n\t */\n\tpublic setName(name: string): this {\n\t\t// Assert the name matches the conditions\n\t\tvalidateName(name);\n\n\t\tReflect.set(this, 'name', name);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the description\n\t *\n\t * @param description The description\n\t */\n\tpublic setDescription(description: string) {\n\t\t// Assert the description matches the conditions\n\t\tvalidateDescription(description);\n\n\t\tReflect.set(this, 'description', description);\n\n\t\treturn this;\n\t}\n}\n","import type { APIApplicationCommandBasicOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { validateRequiredParameters, validateRequired } from '../Assertions';\nimport { SharedNameAndDescription } from './NameAndDescription';\n\nexport abstract class ApplicationCommandOptionBase extends SharedNameAndDescription {\n\tpublic abstract readonly type: ApplicationCommandOptionType;\n\n\tpublic readonly required: boolean = false;\n\n\t/**\n\t * Marks the option as required\n\t *\n\t * @param required If this option should be required\n\t */\n\tpublic setRequired(required: boolean) {\n\t\t// Assert that you actually passed a boolean\n\t\tvalidateRequired(required);\n\n\t\tReflect.set(this, 'required', required);\n\n\t\treturn this;\n\t}\n\n\tpublic abstract toJSON(): APIApplicationCommandBasicOption;\n\n\tprotected runRequiredValidations() {\n\t\tvalidateRequiredParameters(this.name, this.description, []);\n\n\t\t// Assert that you actually passed a boolean\n\t\tvalidateRequired(this.required);\n\t}\n}\n","import { APIApplicationCommandChannelOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionChannelTypesMixin } from '../mixins/ApplicationCommandOptionChannelTypesMixin';\n\n@mix(ApplicationCommandOptionChannelTypesMixin)\nexport class SlashCommandChannelOption extends ApplicationCommandOptionBase {\n\tpublic override readonly type = ApplicationCommandOptionType.Channel as const;\n\n\tpublic toJSON(): APIApplicationCommandChannelOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandChannelOption extends ApplicationCommandOptionChannelTypesMixin {}\n","import { ChannelType } from 'discord-api-types/v9';\nimport { z, ZodLiteral } from 'zod';\n\n// Only allow valid channel types to be used. (This can't be dynamic because const enums are erased at runtime)\nconst allowedChannelTypes = [\n\tChannelType.GuildText,\n\tChannelType.GuildVoice,\n\tChannelType.GuildCategory,\n\tChannelType.GuildNews,\n\tChannelType.GuildStore,\n\tChannelType.GuildNewsThread,\n\tChannelType.GuildPublicThread,\n\tChannelType.GuildPrivateThread,\n\tChannelType.GuildStageVoice,\n] as const;\n\nexport type ApplicationCommandOptionAllowedChannelTypes = typeof allowedChannelTypes[number];\n\nconst channelTypesPredicate = z.array(\n\tz.union(\n\t\tallowedChannelTypes.map((type) => z.literal(type)) as [\n\t\t\tZodLiteral<ChannelType>,\n\t\t\tZodLiteral<ChannelType>,\n\t\t\t...ZodLiteral<ChannelType>[]\n\t\t],\n\t),\n);\n\nexport class ApplicationCommandOptionChannelTypesMixin {\n\tpublic readonly channel_types?: ApplicationCommandOptionAllowedChannelTypes[];\n\n\t/**\n\t * Adds channel types to this option\n\t *\n\t * @param channelTypes The channel types to add\n\t */\n\tpublic addChannelTypes(...channelTypes: ApplicationCommandOptionAllowedChannelTypes[]) {\n\t\tif (this.channel_types === undefined) {\n\t\t\tReflect.set(this, 'channel_types', []);\n\t\t}\n\n\t\tchannelTypesPredicate.parse(channelTypes);\n\n\t\tthis.channel_types!.push(...channelTypes);\n\n\t\treturn this;\n\t}\n}\n","import { APIApplicationCommandIntegerOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { z } from 'zod';\nimport { ApplicationCommandNumericOptionMinMaxValueMixin } from '../mixins/ApplicationCommandNumericOptionMinMaxValueMixin';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin';\n\nconst numberValidator = z.number().int();\n\n@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)\nexport class SlashCommandIntegerOption\n\textends ApplicationCommandOptionBase\n\timplements ApplicationCommandNumericOptionMinMaxValueMixin\n{\n\tpublic readonly type = ApplicationCommandOptionType.Integer as const;\n\n\tpublic setMaxValue(max: number): this {\n\t\tnumberValidator.parse(max);\n\n\t\tReflect.set(this, 'max_value', max);\n\n\t\treturn this;\n\t}\n\n\tpublic setMinValue(min: number): this {\n\t\tnumberValidator.parse(min);\n\n\t\tReflect.set(this, 'min_value', min);\n\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIApplicationCommandIntegerOption {\n\t\tthis.runRequiredValidations();\n\n\t\tif (this.autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandIntegerOption\n\textends ApplicationCommandNumericOptionMinMaxValueMixin,\n\t\tApplicationCommandOptionWithChoicesAndAutocompleteMixin<number> {}\n","export abstract class ApplicationCommandNumericOptionMinMaxValueMixin {\n\tpublic readonly max_value?: number;\n\tpublic readonly min_value?: number;\n\n\t/**\n\t * Sets the maximum number value of this option\n\t * @param max The maximum value this option can be\n\t */\n\tpublic abstract setMaxValue(max: number): this;\n\n\t/**\n\t * Sets the minimum number value of this option\n\t * @param min The minimum value this option can be\n\t */\n\tpublic abstract setMinValue(min: number): this;\n}\n","import { APIApplicationCommandOptionChoice, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport { validateChoicesLength } from '../Assertions';\n\nconst stringPredicate = z.string().min(1).max(100);\nconst numberPredicate = z.number().gt(-Infinity).lt(Infinity);\nconst choicesPredicate = z\n\t.object({ name: stringPredicate, value: z.union([stringPredicate, numberPredicate]) })\n\t.array();\nconst booleanPredicate = z.boolean();\n\nexport class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends string | number> {\n\tpublic readonly choices?: APIApplicationCommandOptionChoice<T>[];\n\tpublic readonly autocomplete?: boolean;\n\n\t// Since this is present and this is a mixin, this is needed\n\tpublic readonly type!: ApplicationCommandOptionType;\n\n\t/**\n\t * Adds multiple choices for this option\n\t *\n\t * @param choices The choices to add\n\t */\n\tpublic addChoices(...choices: APIApplicationCommandOptionChoice<T>[]): this {\n\t\tif (choices.length > 0 && this.autocomplete) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tchoicesPredicate.parse(choices);\n\n\t\tif (this.choices === undefined) {\n\t\t\tReflect.set(this, 'choices', []);\n\t\t}\n\n\t\tvalidateChoicesLength(choices.length, this.choices);\n\n\t\tfor (const { name, value } of choices) {\n\t\t\t// Validate the value\n\t\t\tif (this.type === ApplicationCommandOptionType.String) {\n\t\t\t\tstringPredicate.parse(value);\n\t\t\t} else {\n\t\t\t\tnumberPredicate.parse(value);\n\t\t\t}\n\n\t\t\tthis.choices!.push({ name, value });\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tpublic setChoices<Input extends APIApplicationCommandOptionChoice<T>[]>(...choices: Input): this {\n\t\tif (choices.length > 0 && this.autocomplete) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tchoicesPredicate.parse(choices);\n\n\t\tReflect.set(this, 'choices', []);\n\t\tthis.addChoices(...choices);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Marks the option as autocompletable\n\t * @param autocomplete If this option should be autocompletable\n\t */\n\tpublic setAutocomplete(autocomplete: boolean): this {\n\t\t// Assert that you actually passed a boolean\n\t\tbooleanPredicate.parse(autocomplete);\n\n\t\tif (autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tReflect.set(this, 'autocomplete', autocomplete);\n\n\t\treturn this;\n\t}\n}\n","import { APIApplicationCommandMentionableOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandMentionableOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.Mentionable as const;\n\n\tpublic toJSON(): APIApplicationCommandMentionableOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { APIApplicationCommandNumberOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { z } from 'zod';\nimport { ApplicationCommandNumericOptionMinMaxValueMixin } from '../mixins/ApplicationCommandNumericOptionMinMaxValueMixin';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin';\n\nconst numberValidator = z.number();\n\n@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)\nexport class SlashCommandNumberOption\n\textends ApplicationCommandOptionBase\n\timplements ApplicationCommandNumericOptionMinMaxValueMixin\n{\n\tpublic readonly type = ApplicationCommandOptionType.Number as const;\n\n\tpublic setMaxValue(max: number): this {\n\t\tnumberValidator.parse(max);\n\n\t\tReflect.set(this, 'max_value', max);\n\n\t\treturn this;\n\t}\n\n\tpublic setMinValue(min: number): this {\n\t\tnumberValidator.parse(min);\n\n\t\tReflect.set(this, 'min_value', min);\n\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIApplicationCommandNumberOption {\n\t\tthis.runRequiredValidations();\n\n\t\tif (this.autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandNumberOption\n\textends ApplicationCommandNumericOptionMinMaxValueMixin,\n\t\tApplicationCommandOptionWithChoicesAndAutocompleteMixin<number> {}\n","import { APIApplicationCommandRoleOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandRoleOption extends ApplicationCommandOptionBase {\n\tpublic override readonly type = ApplicationCommandOptionType.Role as const;\n\n\tpublic toJSON(): APIApplicationCommandRoleOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { APIApplicationCommandAttachmentOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandAttachmentOption extends ApplicationCommandOptionBase {\n\tpublic override readonly type = ApplicationCommandOptionType.Attachment as const;\n\n\tpublic toJSON(): APIApplicationCommandAttachmentOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { APIApplicationCommandStringOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin';\n\n@mix(ApplicationCommandOptionWithChoicesAndAutocompleteMixin)\nexport class SlashCommandStringOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.String as const;\n\n\tpublic toJSON(): APIApplicationCommandStringOption {\n\t\tthis.runRequiredValidations();\n\n\t\tif (this.autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandStringOption extends ApplicationCommandOptionWithChoicesAndAutocompleteMixin<string> {}\n","import { APIApplicationCommandUserOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandUserOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.User as const;\n\n\tpublic toJSON(): APIApplicationCommandUserOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { assertReturnOfBuilder, validateMaxOptionsLength } from '../Assertions';\nimport type { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase';\nimport { SlashCommandBooleanOption } from '../options/boolean';\nimport { SlashCommandChannelOption } from '../options/channel';\nimport { SlashCommandIntegerOption } from '../options/integer';\nimport { SlashCommandMentionableOption } from '../options/mentionable';\nimport { SlashCommandNumberOption } from '../options/number';\nimport { SlashCommandRoleOption } from '../options/role';\nimport { SlashCommandAttachmentOption } from '../options/attachment';\nimport { SlashCommandStringOption } from '../options/string';\nimport { SlashCommandUserOption } from '../options/user';\nimport type { ToAPIApplicationCommandOptions } from '../SlashCommandBuilder';\n\nexport class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {\n\tpublic readonly options!: ToAPIApplicationCommandOptions[];\n\n\t/**\n\t * Adds a boolean option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addBooleanOption(\n\t\tinput: SlashCommandBooleanOption | ((builder: SlashCommandBooleanOption) => SlashCommandBooleanOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandBooleanOption);\n\t}\n\n\t/**\n\t * Adds a user option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addUserOption(input: SlashCommandUserOption | ((builder: SlashCommandUserOption) => SlashCommandUserOption)) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandUserOption);\n\t}\n\n\t/**\n\t * Adds a channel option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addChannelOption(\n\t\tinput: SlashCommandChannelOption | ((builder: SlashCommandChannelOption) => SlashCommandChannelOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandChannelOption);\n\t}\n\n\t/**\n\t * Adds a role option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addRoleOption(input: SlashCommandRoleOption | ((builder: SlashCommandRoleOption) => SlashCommandRoleOption)) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandRoleOption);\n\t}\n\n\t/**\n\t * Adds an attachment option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addAttachmentOption(\n\t\tinput: SlashCommandAttachmentOption | ((builder: SlashCommandAttachmentOption) => SlashCommandAttachmentOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandAttachmentOption);\n\t}\n\n\t/**\n\t * Adds a mentionable option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addMentionableOption(\n\t\tinput: SlashCommandMentionableOption | ((builder: SlashCommandMentionableOption) => SlashCommandMentionableOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandMentionableOption);\n\t}\n\n\t/**\n\t * Adds a string option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addStringOption(\n\t\tinput:\n\t\t\t| SlashCommandStringOption\n\t\t\t| Omit<SlashCommandStringOption, 'setAutocomplete'>\n\t\t\t| Omit<SlashCommandStringOption, 'addChoices'>\n\t\t\t| ((\n\t\t\t\t\tbuilder: SlashCommandStringOption,\n\t\t\t ) =>\n\t\t\t\t\t| SlashCommandStringOption\n\t\t\t\t\t| Omit<SlashCommandStringOption, 'setAutocomplete'>\n\t\t\t\t\t| Omit<SlashCommandStringOption, 'addChoices'>),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandStringOption);\n\t}\n\n\t/**\n\t * Adds an integer option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addIntegerOption(\n\t\tinput:\n\t\t\t| SlashCommandIntegerOption\n\t\t\t| Omit<SlashCommandIntegerOption, 'setAutocomplete'>\n\t\t\t| Omit<SlashCommandIntegerOption, 'addChoices'>\n\t\t\t| ((\n\t\t\t\t\tbuilder: SlashCommandIntegerOption,\n\t\t\t ) =>\n\t\t\t\t\t| SlashCommandIntegerOption\n\t\t\t\t\t| Omit<SlashCommandIntegerOption, 'setAutocomplete'>\n\t\t\t\t\t| Omit<SlashCommandIntegerOption, 'addChoices'>),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandIntegerOption);\n\t}\n\n\t/**\n\t * Adds a number option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addNumberOption(\n\t\tinput:\n\t\t\t| SlashCommandNumberOption\n\t\t\t| Omit<SlashCommandNumberOption, 'setAutocomplete'>\n\t\t\t| Omit<SlashCommandNumberOption, 'addChoices'>\n\t\t\t| ((\n\t\t\t\t\tbuilder: SlashCommandNumberOption,\n\t\t\t ) =>\n\t\t\t\t\t| SlashCommandNumberOption\n\t\t\t\t\t| Omit<SlashCommandNumberOption, 'setAutocomplete'>\n\t\t\t\t\t| Omit<SlashCommandNumberOption, 'addChoices'>),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandNumberOption);\n\t}\n\n\tprivate _sharedAddOptionMethod<T extends ApplicationCommandOptionBase>(\n\t\tinput:\n\t\t\t| T\n\t\t\t| Omit<T, 'setAutocomplete'>\n\t\t\t| Omit<T, 'addChoices'>\n\t\t\t| ((builder: T) => T | Omit<T, 'setAutocomplete'> | Omit<T, 'addChoices'>),\n\t\tInstance: new () => T,\n\t): ShouldOmitSubcommandFunctions extends true ? Omit<this, 'addSubcommand' | 'addSubcommandGroup'> : this {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\tconst result = typeof input === 'function' ? input(new Instance()) : input;\n\n\t\tassertReturnOfBuilder(result, Instance);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n}\n","import {\n\tAPIApplicationCommandSubcommandGroupOption,\n\tAPIApplicationCommandSubcommandOption,\n\tApplicationCommandOptionType,\n} from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { assertReturnOfBuilder, validateMaxOptionsLength, validateRequiredParameters } from './Assertions';\nimport type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase';\nimport { SharedNameAndDescription } from './mixins/NameAndDescription';\nimport { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions';\nimport type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder';\n\n/**\n * Represents a folder for subcommands\n *\n * For more information, go to https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups\n */\n@mix(SharedNameAndDescription)\nexport class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationCommandOptions {\n\t/**\n\t * The name of this subcommand group\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The description of this subcommand group\n\t */\n\tpublic readonly description: string = undefined!;\n\n\t/**\n\t * The subcommands part of this subcommand group\n\t */\n\tpublic readonly options: SlashCommandSubcommandBuilder[] = [];\n\n\t/**\n\t * Adds a new subcommand to this group\n\t *\n\t * @param input A function that returns a subcommand builder, or an already built builder\n\t */\n\tpublic addSubcommand(\n\t\tinput:\n\t\t\t| SlashCommandSubcommandBuilder\n\t\t\t| ((subcommandGroup: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder),\n\t) {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\tconst result = typeof input === 'function' ? input(new SlashCommandSubcommandBuilder()) : input;\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\tassertReturnOfBuilder(result, SlashCommandSubcommandBuilder);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIApplicationCommandSubcommandGroupOption {\n\t\tvalidateRequiredParameters(this.name, this.description, this.options);\n\n\t\treturn {\n\t\t\ttype: ApplicationCommandOptionType.SubcommandGroup,\n\t\t\tname: this.name,\n\t\t\tdescription: this.description,\n\t\t\toptions: this.options.map((option) => option.toJSON()),\n\t\t};\n\t}\n}\n\nexport interface SlashCommandSubcommandGroupBuilder extends SharedNameAndDescription {}\n\n/**\n * Represents a subcommand\n *\n * For more information, go to https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups\n */\n@mix(SharedNameAndDescription, SharedSlashCommandOptions)\nexport class SlashCommandSubcommandBuilder implements ToAPIApplicationCommandOptions {\n\t/**\n\t * The name of this subcommand\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The description of this subcommand\n\t */\n\tpublic readonly description: string = undefined!;\n\n\t/**\n\t * The options of this subcommand\n\t */\n\tpublic readonly options: ApplicationCommandOptionBase[] = [];\n\n\tpublic toJSON(): APIApplicationCommandSubcommandOption {\n\t\tvalidateRequiredParameters(this.name, this.description, this.options);\n\n\t\treturn {\n\t\t\ttype: ApplicationCommandOptionType.Subcommand,\n\t\t\tname: this.name,\n\t\t\tdescription: this.description,\n\t\t\toptions: this.options.map((option) => option.toJSON()),\n\t\t};\n\t}\n}\n\nexport interface SlashCommandSubcommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions<false> {}\n","import { z } from 'zod';\nimport { ApplicationCommandType } from 'discord-api-types/v9';\nimport type { ContextMenuCommandType } from './ContextMenuCommandBuilder';\n\nconst namePredicate = z\n\t.string()\n\t.min(1)\n\t.max(32)\n\t.regex(/^( *[\\p{L}\\p{N}_-]+ *)+$/u);\n\nconst typePredicate = z.union([z.literal(ApplicationCommandType.User), z.literal(ApplicationCommandType.Message)]);\n\nconst booleanPredicate = z.boolean();\n\nexport function validateDefaultPermission(value: unknown): asserts value is boolean {\n\tbooleanPredicate.parse(value);\n}\n\nexport function validateName(name: unknown): asserts name is string {\n\tnamePredicate.parse(name);\n}\n\nexport function validateType(type: unknown): asserts type is ContextMenuCommandType {\n\ttypePredicate.parse(type);\n}\n\nexport function validateRequiredParameters(name: string, type: number) {\n\t// Assert name matches all conditions\n\tvalidateName(name);\n\n\t// Assert type is valid\n\tvalidateType(type);\n}\n","import { validateRequiredParameters, validateName, validateType, validateDefaultPermission } from './Assertions';\nimport type { ApplicationCommandType, RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v9';\n\nexport class ContextMenuCommandBuilder {\n\t/**\n\t * The name of this context menu command\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The type of this context menu command\n\t */\n\tpublic readonly type: ContextMenuCommandType = undefined!;\n\n\t/**\n\t * Whether the command is enabled by default when the app is added to a guild\n\t *\n\t * @default true\n\t */\n\tpublic readonly defaultPermission: boolean | undefined = undefined;\n\n\t/**\n\t * Sets the name\n\t *\n\t * @param name The name\n\t */\n\tpublic setName(name: string) {\n\t\t// Assert the name matches the conditions\n\t\tvalidateName(name);\n\n\t\tReflect.set(this, 'name', name);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the type\n\t *\n\t * @param type The type\n\t */\n\tpublic setType(type: ContextMenuCommandType) {\n\t\t// Assert the type is valid\n\t\tvalidateType(type);\n\n\t\tReflect.set(this, 'type', type);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether the command is enabled by default when the application is added to a guild.\n\t *\n\t * **Note**: If set to `false`, you will have to later `PUT` the permissions for this command.\n\t *\n\t * @param value Whether or not to enable this command by default\n\t *\n\t * @see https://discord.com/developers/docs/interactions/application-commands#permissions\n\t */\n\tpublic setDefaultPermission(value: boolean) {\n\t\t// Assert the value matches the conditions\n\t\tvalidateDefaultPermission(value);\n\n\t\tReflect.set(this, 'defaultPermission', value);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns the final data that should be sent to Discord.\n\t *\n\t * **Note:** Calling this function will validate required properties based on their conditions.\n\t */\n\tpublic toJSON(): RESTPostAPIApplicationCommandsJSONBody {\n\t\tvalidateRequiredParameters(this.name, this.type);\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\ttype: this.type,\n\t\t\tdefault_permission: this.defaultPermission,\n\t\t};\n\t}\n}\n\nexport type ContextMenuCommandType = ApplicationCommandType.User | ApplicationCommandType.Message;\n","export interface JSONEncodable<T> {\n\t/**\n\t * Transforms this object to its JSON format\n\t */\n\ttoJSON: () => T;\n}\n\n/**\n * Indicates if an object is encodable or not.\n * @param maybeEncodable The object to check against\n */\nexport function isJSONEncodable(maybeEncodable: unknown): maybeEncodable is JSONEncodable<unknown> {\n\treturn maybeEncodable !== null && typeof maybeEncodable === 'object' && 'toJSON' in maybeEncodable;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/messages/embed/Assertions.ts","../src/messages/embed/UnsafeEmbed.ts","../src/messages/embed/Embed.ts","../src/messages/formatters.ts","../src/components/Assertions.ts","../src/components/ActionRow.ts","../src/components/Component.ts","../src/components/Components.ts","../src/components/button/UnsafeButton.ts","../src/components/button/Button.ts","../src/components/textInput/Assertions.ts","../src/components/textInput/UnsafeTextInput.ts","../src/components/textInput/TextInput.ts","../src/interactions/modals/UnsafeModal.ts","../src/interactions/modals/Assertions.ts","../src/interactions/modals/Modal.ts","../src/components/selectMenu/UnsafeSelectMenu.ts","../src/components/selectMenu/UnsafeSelectMenuOption.ts","../src/components/selectMenu/SelectMenu.ts","../src/components/selectMenu/SelectMenuOption.ts","../src/interactions/slashCommands/Assertions.ts","../src/interactions/slashCommands/SlashCommandBuilder.ts","../src/interactions/slashCommands/options/boolean.ts","../src/interactions/slashCommands/mixins/NameAndDescription.ts","../src/interactions/slashCommands/mixins/ApplicationCommandOptionBase.ts","../src/interactions/slashCommands/options/channel.ts","../src/interactions/slashCommands/mixins/ApplicationCommandOptionChannelTypesMixin.ts","../src/interactions/slashCommands/options/integer.ts","../src/interactions/slashCommands/mixins/ApplicationCommandNumericOptionMinMaxValueMixin.ts","../src/interactions/slashCommands/mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin.ts","../src/interactions/slashCommands/options/mentionable.ts","../src/interactions/slashCommands/options/number.ts","../src/interactions/slashCommands/options/role.ts","../src/interactions/slashCommands/options/attachment.ts","../src/interactions/slashCommands/options/string.ts","../src/interactions/slashCommands/options/user.ts","../src/interactions/slashCommands/mixins/SharedSlashCommandOptions.ts","../src/interactions/slashCommands/SlashCommandSubcommands.ts","../src/interactions/contextMenuCommands/Assertions.ts","../src/interactions/contextMenuCommands/ContextMenuCommandBuilder.ts","../src/util/jsonEncodable.ts"],"sourcesContent":["export * as EmbedAssertions from './messages/embed/Assertions';\nexport * from './messages/embed/Embed';\nexport * from './messages/formatters';\nexport * from './messages/embed/UnsafeEmbed';\n\nexport * as ComponentAssertions from './components/Assertions';\nexport * from './components/ActionRow';\nexport * from './components/button/Button';\nexport * from './components/Component';\nexport * from './components/Components';\nexport * from './components/textInput/TextInput';\nexport * as TextInputAssertions from './components/textInput/Assertions';\nexport * from './components/textInput/UnsafeTextInput';\nexport * from './interactions/modals/UnsafeModal';\nexport * from './interactions/modals/Modal';\nexport * as ModalAssertions from './interactions/modals/Assertions';\nexport * from './components/selectMenu/SelectMenu';\nexport * from './components/selectMenu/SelectMenuOption';\nexport * from './components/button/UnsafeButton';\nexport * from './components/selectMenu/UnsafeSelectMenu';\nexport * from './components/selectMenu/UnsafeSelectMenuOption';\n\nexport * as SlashCommandAssertions from './interactions/slashCommands/Assertions';\nexport * from './interactions/slashCommands/SlashCommandBuilder';\nexport * from './interactions/slashCommands/SlashCommandSubcommands';\nexport * from './interactions/slashCommands/options/boolean';\nexport * from './interactions/slashCommands/options/channel';\nexport * from './interactions/slashCommands/options/integer';\nexport * from './interactions/slashCommands/options/mentionable';\nexport * from './interactions/slashCommands/options/number';\nexport * from './interactions/slashCommands/options/role';\nexport * from './interactions/slashCommands/options/attachment';\nexport * from './interactions/slashCommands/options/string';\nexport * from './interactions/slashCommands/options/user';\n\nexport * as ContextMenuCommandAssertions from './interactions/contextMenuCommands/Assertions';\nexport * from './interactions/contextMenuCommands/ContextMenuCommandBuilder';\n\nexport * from './util/jsonEncodable';\n","import type { APIEmbedField } from 'discord-api-types/v9';\nimport { z } from 'zod';\n\nexport const fieldNamePredicate = z.string().min(1).max(256);\n\nexport const fieldValuePredicate = z.string().min(1).max(1024);\n\nexport const fieldInlinePredicate = z.boolean().optional();\n\nexport const embedFieldPredicate = z.object({\n\tname: fieldNamePredicate,\n\tvalue: fieldValuePredicate,\n\tinline: fieldInlinePredicate,\n});\n\nexport const embedFieldsArrayPredicate = embedFieldPredicate.array();\n\nexport const fieldLengthPredicate = z.number().lte(25);\n\nexport function validateFieldLength(amountAdding: number, fields?: APIEmbedField[]): void {\n\tfieldLengthPredicate.parse((fields?.length ?? 0) + amountAdding);\n}\n\nexport const authorNamePredicate = fieldNamePredicate.nullable();\n\nexport const urlPredicate = z.string().url().nullish();\n\nexport const RGBPredicate = z.number().int().gte(0).lte(255);\nexport const colorPredicate = z\n\t.number()\n\t.int()\n\t.gte(0)\n\t.lte(0xffffff)\n\t.nullable()\n\t.or(z.tuple([RGBPredicate, RGBPredicate, RGBPredicate]));\n\nexport const descriptionPredicate = z.string().min(1).max(4096).nullable();\n\nexport const footerTextPredicate = z.string().min(1).max(2048).nullable();\n\nexport const timestampPredicate = z.union([z.number(), z.date()]).nullable();\n\nexport const titlePredicate = fieldNamePredicate.nullable();\n","import type {\n\tAPIEmbed,\n\tAPIEmbedAuthor,\n\tAPIEmbedField,\n\tAPIEmbedFooter,\n\tAPIEmbedImage,\n\tAPIEmbedVideo,\n} from 'discord-api-types/v9';\nimport type { Equatable } from '../../util/equatable';\nimport isEqual from 'fast-deep-equal';\n\nexport type RGBTuple = [red: number, green: number, blue: number];\n\nexport interface IconData {\n\t/**\n\t * The URL of the icon\n\t */\n\ticonURL?: string;\n\t/**\n\t * The proxy URL of the icon\n\t */\n\tproxyIconURL?: string;\n}\n\nexport type EmbedAuthorData = Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'> & IconData;\n\nexport type EmbedAuthorOptions = Omit<EmbedAuthorData, 'proxyIconURL'>;\n\nexport type EmbedFooterData = Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'> & IconData;\n\nexport type EmbedFooterOptions = Omit<EmbedFooterData, 'proxyIconURL'>;\n\nexport interface EmbedImageData extends Omit<APIEmbedImage, 'proxy_url'> {\n\t/**\n\t * The proxy URL for the image\n\t */\n\tproxyURL?: string;\n}\n\n/**\n * Represents a non-validated embed in a message (image/video preview, rich embed, etc.)\n */\nexport class UnsafeEmbed implements Equatable<APIEmbed | UnsafeEmbed> {\n\tpublic readonly data: APIEmbed;\n\n\tpublic constructor(data: APIEmbed = {}) {\n\t\tthis.data = { ...data };\n\t\tif (data.timestamp) this.data.timestamp = new Date(data.timestamp).toISOString();\n\t}\n\n\t/**\n\t * An array of fields of this embed\n\t */\n\tpublic get fields() {\n\t\treturn this.data.fields;\n\t}\n\n\t/**\n\t * The embed title\n\t */\n\tpublic get title() {\n\t\treturn this.data.title;\n\t}\n\n\t/**\n\t * The embed description\n\t */\n\tpublic get description() {\n\t\treturn this.data.description;\n\t}\n\n\t/**\n\t * The embed URL\n\t */\n\tpublic get url() {\n\t\treturn this.data.url;\n\t}\n\n\t/**\n\t * The embed color\n\t */\n\tpublic get color() {\n\t\treturn this.data.color;\n\t}\n\n\t/**\n\t * The timestamp of the embed in an ISO 8601 format\n\t */\n\tpublic get timestamp() {\n\t\treturn this.data.timestamp;\n\t}\n\n\t/**\n\t * The embed thumbnail data\n\t */\n\tpublic get thumbnail(): EmbedImageData | undefined {\n\t\tif (!this.data.thumbnail) return undefined;\n\t\treturn {\n\t\t\turl: this.data.thumbnail.url,\n\t\t\tproxyURL: this.data.thumbnail.proxy_url,\n\t\t\theight: this.data.thumbnail.height,\n\t\t\twidth: this.data.thumbnail.width,\n\t\t};\n\t}\n\n\t/**\n\t * The embed image data\n\t */\n\tpublic get image(): EmbedImageData | undefined {\n\t\tif (!this.data.image) return undefined;\n\t\treturn {\n\t\t\turl: this.data.image.url,\n\t\t\tproxyURL: this.data.image.proxy_url,\n\t\t\theight: this.data.image.height,\n\t\t\twidth: this.data.image.width,\n\t\t};\n\t}\n\n\t/**\n\t * Received video data\n\t */\n\tpublic get video(): APIEmbedVideo | undefined {\n\t\treturn this.data.video;\n\t}\n\n\t/**\n\t * The embed author data\n\t */\n\tpublic get author(): EmbedAuthorData | undefined {\n\t\tif (!this.data.author) return undefined;\n\t\treturn {\n\t\t\tname: this.data.author.name,\n\t\t\turl: this.data.author.url,\n\t\t\ticonURL: this.data.author.icon_url,\n\t\t\tproxyIconURL: this.data.author.proxy_icon_url,\n\t\t};\n\t}\n\n\t/**\n\t * Received data about the embed provider\n\t */\n\tpublic get provider() {\n\t\treturn this.data.provider;\n\t}\n\n\t/**\n\t * The embed footer data\n\t */\n\tpublic get footer(): EmbedFooterData | undefined {\n\t\tif (!this.data.footer) return undefined;\n\t\treturn {\n\t\t\ttext: this.data.footer.text,\n\t\t\ticonURL: this.data.footer.icon_url,\n\t\t\tproxyIconURL: this.data.footer.proxy_icon_url,\n\t\t};\n\t}\n\n\t/**\n\t * The accumulated length for the embed title, description, fields, footer text, and author name\n\t */\n\tpublic get length(): number {\n\t\treturn (\n\t\t\t(this.data.title?.length ?? 0) +\n\t\t\t(this.data.description?.length ?? 0) +\n\t\t\t(this.data.fields?.reduce((prev, curr) => prev + curr.name.length + curr.value.length, 0) ?? 0) +\n\t\t\t(this.data.footer?.text.length ?? 0) +\n\t\t\t(this.data.author?.name.length ?? 0)\n\t\t);\n\t}\n\n\t/**\n\t * The hex color of the current color of the embed\n\t */\n\tpublic get hexColor() {\n\t\treturn typeof this.data.color === 'number' ? `#${this.data.color.toString(16).padStart(6, '0')}` : this.data.color;\n\t}\n\n\t/**\n\t * Adds fields to the embed (max 25)\n\t *\n\t * @param fields The fields to add\n\t */\n\tpublic addFields(...fields: APIEmbedField[]): this {\n\t\tif (this.data.fields) this.data.fields.push(...fields);\n\t\telse this.data.fields = fields;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes, replaces, or inserts fields in the embed (max 25)\n\t *\n\t * @param index The index to start at\n\t * @param deleteCount The number of fields to remove\n\t * @param fields The replacing field objects\n\t */\n\tpublic spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this {\n\t\tif (this.data.fields) this.data.fields.splice(index, deleteCount, ...fields);\n\t\telse this.data.fields = fields;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the embed's fields (max 25).\n\t * @param fields The fields to set\n\t */\n\tpublic setFields(...fields: APIEmbedField[]) {\n\t\tthis.spliceFields(0, this.fields?.length ?? 0, ...fields);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the author of this embed\n\t *\n\t * @param options The options for the author\n\t */\n\tpublic setAuthor(options: EmbedAuthorOptions | null): this {\n\t\tif (options === null) {\n\t\t\tthis.data.author = undefined;\n\t\t\treturn this;\n\t\t}\n\n\t\tthis.data.author = { name: options.name, url: options.url, icon_url: options.iconURL };\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the color of this embed\n\t *\n\t * @param color The color of the embed\n\t */\n\tpublic setColor(color: number | RGBTuple | null): this {\n\t\tif (Array.isArray(color)) {\n\t\t\tconst [red, green, blue] = color;\n\t\t\tthis.data.color = (red << 16) + (green << 8) + blue;\n\t\t\treturn this;\n\t\t}\n\t\tthis.data.color = color ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the description of this embed\n\t *\n\t * @param description The description\n\t */\n\tpublic setDescription(description: string | null): this {\n\t\tthis.data.description = description ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the footer of this embed\n\t *\n\t * @param options The options for the footer\n\t */\n\tpublic setFooter(options: EmbedFooterOptions | null): this {\n\t\tif (options === null) {\n\t\t\tthis.data.footer = undefined;\n\t\t\treturn this;\n\t\t}\n\n\t\tthis.data.footer = { text: options.text, icon_url: options.iconURL };\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the image of this embed\n\t *\n\t * @param url The URL of the image\n\t */\n\tpublic setImage(url: string | null): this {\n\t\tthis.data.image = url ? { url } : undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the thumbnail of this embed\n\t *\n\t * @param url The URL of the thumbnail\n\t */\n\tpublic setThumbnail(url: string | null): this {\n\t\tthis.data.thumbnail = url ? { url } : undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the timestamp of this embed\n\t *\n\t * @param timestamp The timestamp or date\n\t */\n\tpublic setTimestamp(timestamp: number | Date | null = Date.now()): this {\n\t\tthis.data.timestamp = timestamp ? new Date(timestamp).toISOString() : undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the title of this embed\n\t *\n\t * @param title The title\n\t */\n\tpublic setTitle(title: string | null): this {\n\t\tthis.data.title = title ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the URL of this embed\n\t *\n\t * @param url The URL\n\t */\n\tpublic setURL(url: string | null): this {\n\t\tthis.data.url = url ?? undefined;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Transforms the embed to a plain object\n\t */\n\tpublic toJSON(): APIEmbed {\n\t\treturn { ...this.data };\n\t}\n\n\tpublic equals(other: UnsafeEmbed | APIEmbed) {\n\t\tconst { image: thisImage, thumbnail: thisThumbnail, ...thisData } = this.data;\n\t\tconst data = other instanceof UnsafeEmbed ? other.data : other;\n\t\tconst { image, thumbnail, ...otherData } = data;\n\t\treturn isEqual(otherData, thisData) && image?.url === thisImage?.url && thumbnail?.url === thisThumbnail?.url;\n\t}\n}\n","import type { APIEmbedField } from 'discord-api-types/v9';\nimport {\n\tauthorNamePredicate,\n\tcolorPredicate,\n\tdescriptionPredicate,\n\tembedFieldsArrayPredicate,\n\tfooterTextPredicate,\n\ttimestampPredicate,\n\ttitlePredicate,\n\turlPredicate,\n\tvalidateFieldLength,\n} from './Assertions';\nimport { EmbedAuthorOptions, EmbedFooterOptions, RGBTuple, UnsafeEmbed } from './UnsafeEmbed';\n\n/**\n * Represents a validated embed in a message (image/video preview, rich embed, etc.)\n */\nexport class Embed extends UnsafeEmbed {\n\tpublic override addFields(...fields: APIEmbedField[]): this {\n\t\t// Ensure adding these fields won't exceed the 25 field limit\n\t\tvalidateFieldLength(fields.length, this.fields);\n\n\t\t// Data assertions\n\t\treturn super.addFields(...embedFieldsArrayPredicate.parse(fields));\n\t}\n\n\tpublic override spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this {\n\t\t// Ensure adding these fields won't exceed the 25 field limit\n\t\tvalidateFieldLength(fields.length - deleteCount, this.fields);\n\n\t\t// Data assertions\n\t\treturn super.spliceFields(index, deleteCount, ...embedFieldsArrayPredicate.parse(fields));\n\t}\n\n\tpublic override setAuthor(options: EmbedAuthorOptions | null): this {\n\t\tif (options === null) {\n\t\t\treturn super.setAuthor(null);\n\t\t}\n\n\t\t// Data assertions\n\t\tauthorNamePredicate.parse(options.name);\n\t\turlPredicate.parse(options.iconURL);\n\t\turlPredicate.parse(options.url);\n\n\t\treturn super.setAuthor(options);\n\t}\n\n\tpublic override setColor(color: number | RGBTuple | null): this {\n\t\t// Data assertions\n\t\treturn super.setColor(colorPredicate.parse(color));\n\t}\n\n\tpublic override setDescription(description: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setDescription(descriptionPredicate.parse(description));\n\t}\n\n\tpublic override setFooter(options: EmbedFooterOptions | null): this {\n\t\tif (options === null) {\n\t\t\treturn super.setFooter(null);\n\t\t}\n\n\t\t// Data assertions\n\t\tfooterTextPredicate.parse(options.text);\n\t\turlPredicate.parse(options.iconURL);\n\n\t\treturn super.setFooter(options);\n\t}\n\n\tpublic override setImage(url: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setImage(urlPredicate.parse(url)!);\n\t}\n\n\tpublic override setThumbnail(url: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setThumbnail(urlPredicate.parse(url)!);\n\t}\n\n\tpublic override setTimestamp(timestamp: number | Date | null = Date.now()): this {\n\t\t// Data assertions\n\t\treturn super.setTimestamp(timestampPredicate.parse(timestamp));\n\t}\n\n\tpublic override setTitle(title: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setTitle(titlePredicate.parse(title));\n\t}\n\n\tpublic override setURL(url: string | null): this {\n\t\t// Data assertions\n\t\treturn super.setURL(urlPredicate.parse(url)!);\n\t}\n}\n","import type { Snowflake } from 'discord-api-types/globals';\nimport type { URL } from 'url';\n\n/**\n * Wraps the content inside a codeblock with no language\n *\n * @param content The content to wrap\n */\nexport function codeBlock<C extends string>(content: C): `\\`\\`\\`\\n${C}\\`\\`\\``;\n\n/**\n * Wraps the content inside a codeblock with the specified language\n *\n * @param language The language for the codeblock\n * @param content The content to wrap\n */\nexport function codeBlock<L extends string, C extends string>(language: L, content: C): `\\`\\`\\`${L}\\n${C}\\`\\`\\``;\nexport function codeBlock(language: string, content?: string): string {\n\treturn typeof content === 'undefined' ? `\\`\\`\\`\\n${language}\\`\\`\\`` : `\\`\\`\\`${language}\\n${content}\\`\\`\\``;\n}\n\n/**\n * Wraps the content inside \\`backticks\\`, which formats it as inline code\n *\n * @param content The content to wrap\n */\nexport function inlineCode<C extends string>(content: C): `\\`${C}\\`` {\n\treturn `\\`${content}\\``;\n}\n\n/**\n * Formats the content into italic text\n *\n * @param content The content to wrap\n */\nexport function italic<C extends string>(content: C): `_${C}_` {\n\treturn `_${content}_`;\n}\n\n/**\n * Formats the content into bold text\n *\n * @param content The content to wrap\n */\nexport function bold<C extends string>(content: C): `**${C}**` {\n\treturn `**${content}**`;\n}\n\n/**\n * Formats the content into underscored text\n *\n * @param content The content to wrap\n */\nexport function underscore<C extends string>(content: C): `__${C}__` {\n\treturn `__${content}__`;\n}\n\n/**\n * Formats the content into strike-through text\n *\n * @param content The content to wrap\n */\nexport function strikethrough<C extends string>(content: C): `~~${C}~~` {\n\treturn `~~${content}~~`;\n}\n\n/**\n * Formats the content into a quote. This needs to be at the start of the line for Discord to format it\n *\n * @param content The content to wrap\n */\nexport function quote<C extends string>(content: C): `> ${C}` {\n\treturn `> ${content}`;\n}\n\n/**\n * Formats the content into a block quote. This needs to be at the start of the line for Discord to format it\n *\n * @param content The content to wrap\n */\nexport function blockQuote<C extends string>(content: C): `>>> ${C}` {\n\treturn `>>> ${content}`;\n}\n\n/**\n * Wraps the URL into `<>`, which stops it from embedding\n *\n * @param url The URL to wrap\n */\nexport function hideLinkEmbed<C extends string>(url: C): `<${C}>`;\n\n/**\n * Wraps the URL into `<>`, which stops it from embedding\n *\n * @param url The URL to wrap\n */\nexport function hideLinkEmbed(url: URL): `<${string}>`;\nexport function hideLinkEmbed(url: string | URL) {\n\t// eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n\treturn `<${url}>`;\n}\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n */\nexport function hyperlink<C extends string>(content: C, url: URL): `[${C}](${string})`;\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n */\nexport function hyperlink<C extends string, U extends string>(content: C, url: U): `[${C}](${U})`;\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n * @param title The title shown when hovering on the masked link\n */\nexport function hyperlink<C extends string, T extends string>(\n\tcontent: C,\n\turl: URL,\n\ttitle: T,\n): `[${C}](${string} \"${T}\")`;\n\n/**\n * Formats the content and the URL into a masked URL\n *\n * @param content The content to display\n * @param url The URL the content links to\n * @param title The title shown when hovering on the masked link\n */\nexport function hyperlink<C extends string, U extends string, T extends string>(\n\tcontent: C,\n\turl: U,\n\ttitle: T,\n): `[${C}](${U} \"${T}\")`;\nexport function hyperlink(content: string, url: string | URL, title?: string) {\n\t// eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n\treturn title ? `[${content}](${url} \"${title}\")` : `[${content}](${url})`;\n}\n\n/**\n * Wraps the content inside spoiler (hidden text)\n *\n * @param content The content to wrap\n */\nexport function spoiler<C extends string>(content: C): `||${C}||` {\n\treturn `||${content}||`;\n}\n\n/**\n * Formats a user ID into a user mention\n *\n * @param userId The user ID to format\n */\nexport function userMention<C extends Snowflake>(userId: C): `<@${C}>` {\n\treturn `<@${userId}>`;\n}\n\n/**\n * Formats a user ID into a member-nickname mention\n *\n * @param memberId The user ID to format\n */\nexport function memberNicknameMention<C extends Snowflake>(memberId: C): `<@!${C}>` {\n\treturn `<@!${memberId}>`;\n}\n\n/**\n * Formats a channel ID into a channel mention\n *\n * @param channelId The channel ID to format\n */\nexport function channelMention<C extends Snowflake>(channelId: C): `<#${C}>` {\n\treturn `<#${channelId}>`;\n}\n\n/**\n * Formats a role ID into a role mention\n *\n * @param roleId The role ID to format\n */\nexport function roleMention<C extends Snowflake>(roleId: C): `<@&${C}>` {\n\treturn `<@&${roleId}>`;\n}\n\n/**\n * Formats an emoji ID into a fully qualified emoji identifier\n *\n * @param emojiId The emoji ID to format\n */\nexport function formatEmoji<C extends Snowflake>(emojiId: C, animated?: false): `<:_:${C}>`;\n\n/**\n * Formats an emoji ID into a fully qualified emoji identifier\n *\n * @param emojiId The emoji ID to format\n * @param animated Whether the emoji is animated or not. Defaults to `false`\n */\nexport function formatEmoji<C extends Snowflake>(emojiId: C, animated?: true): `<a:_:${C}>`;\n\n/**\n * Formats an emoji ID into a fully qualified emoji identifier\n *\n * @param emojiId The emoji ID to format\n * @param animated Whether the emoji is animated or not. Defaults to `false`\n */\nexport function formatEmoji<C extends Snowflake>(emojiId: C, animated = false): `<a:_:${C}>` | `<:_:${C}>` {\n\treturn `<${animated ? 'a' : ''}:_:${emojiId}>`;\n}\n\n/**\n * Formats a date into a short date-time string\n *\n * @param date The date to format, defaults to the current time\n */\nexport function time(date?: Date): `<t:${bigint}>`;\n\n/**\n * Formats a date given a format style\n *\n * @param date The date to format\n * @param style The style to use\n */\nexport function time<S extends TimestampStylesString>(date: Date, style: S): `<t:${bigint}:${S}>`;\n\n/**\n * Formats the given timestamp into a short date-time string\n *\n * @param seconds The time to format, represents an UNIX timestamp in seconds\n */\nexport function time<C extends number>(seconds: C): `<t:${C}>`;\n\n/**\n * Formats the given timestamp into a short date-time string\n *\n * @param seconds The time to format, represents an UNIX timestamp in seconds\n * @param style The style to use\n */\nexport function time<C extends number, S extends TimestampStylesString>(seconds: C, style: S): `<t:${C}:${S}>`;\nexport function time(timeOrSeconds?: number | Date, style?: TimestampStylesString): string {\n\tif (typeof timeOrSeconds !== 'number') {\n\t\ttimeOrSeconds = Math.floor((timeOrSeconds?.getTime() ?? Date.now()) / 1000);\n\t}\n\n\treturn typeof style === 'string' ? `<t:${timeOrSeconds}:${style}>` : `<t:${timeOrSeconds}>`;\n}\n\n/**\n * The [message formatting timestamp styles](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles) supported by Discord\n */\nexport const TimestampStyles = {\n\t/**\n\t * Short time format, consisting of hours and minutes, e.g. 16:20\n\t */\n\tShortTime: 't',\n\n\t/**\n\t * Long time format, consisting of hours, minutes, and seconds, e.g. 16:20:30\n\t */\n\tLongTime: 'T',\n\n\t/**\n\t * Short date format, consisting of day, month, and year, e.g. 20/04/2021\n\t */\n\tShortDate: 'd',\n\n\t/**\n\t * Long date format, consisting of day, month, and year, e.g. 20 April 2021\n\t */\n\tLongDate: 'D',\n\n\t/**\n\t * Short date-time format, consisting of short date and short time formats, e.g. 20 April 2021 16:20\n\t */\n\tShortDateTime: 'f',\n\n\t/**\n\t * Long date-time format, consisting of long date and short time formats, e.g. Tuesday, 20 April 2021 16:20\n\t */\n\tLongDateTime: 'F',\n\n\t/**\n\t * Relative time format, consisting of a relative duration format, e.g. 2 months ago\n\t */\n\tRelativeTime: 'R',\n} as const;\n\n/**\n * The possible values, see {@link TimestampStyles} for more information\n */\nexport type TimestampStylesString = typeof TimestampStyles[keyof typeof TimestampStyles];\n\n/**\n * An enum with all the available faces from Discord's native slash commands\n */\nexport enum Faces {\n\t/**\n\t * ¯\\\\_(ツ)\\\\_/¯\n\t */\n\tShrug = '¯\\\\_(ツ)\\\\_/¯',\n\n\t/**\n\t * (╯°□°)╯︵ ┻━┻\n\t */\n\tTableflip = '(╯°□°)╯︵ ┻━┻',\n\n\t/**\n\t * ┬─┬ ノ( ゜-゜ノ)\n\t */\n\tUnflip = '┬─┬ ノ( ゜-゜ノ)',\n}\n","import { APIMessageComponentEmoji, ButtonStyle } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport type { SelectMenuOption } from './selectMenu/SelectMenuOption';\n\nexport const customIdValidator = z.string().min(1).max(100);\n\nexport const emojiValidator = z\n\t.object({\n\t\tid: z.string(),\n\t\tname: z.string(),\n\t\tanimated: z.boolean(),\n\t})\n\t.partial()\n\t.strict();\n\nexport const disabledValidator = z.boolean();\n\nexport const buttonLabelValidator = z.string().nonempty().max(80);\n\nexport const buttonStyleValidator = z.number().int().min(ButtonStyle.Primary).max(ButtonStyle.Link);\n\nexport const placeholderValidator = z.string().max(150);\nexport const minMaxValidator = z.number().int().min(0).max(25);\n\nexport const optionsValidator = z.object({}).array().nonempty();\n\nexport function validateRequiredSelectMenuParameters(options: SelectMenuOption[], customId?: string) {\n\tcustomIdValidator.parse(customId);\n\toptionsValidator.parse(options);\n}\n\nexport const labelValueValidator = z.string().min(1).max(100);\nexport const defaultValidator = z.boolean();\n\nexport function validateRequiredSelectMenuOptionParameters(label?: string, value?: string) {\n\tlabelValueValidator.parse(label);\n\tlabelValueValidator.parse(value);\n}\n\nexport const urlValidator = z.string().url();\n\nexport function validateRequiredButtonParameters(\n\tstyle?: ButtonStyle,\n\tlabel?: string,\n\temoji?: APIMessageComponentEmoji,\n\tcustomId?: string,\n\turl?: string,\n) {\n\tif (url && customId) {\n\t\tthrow new RangeError('URL and custom id are mutually exclusive');\n\t}\n\n\tif (!label && !emoji) {\n\t\tthrow new RangeError('Buttons must have a label and/or an emoji');\n\t}\n\n\tif (style === ButtonStyle.Link) {\n\t\tif (!url) {\n\t\t\tthrow new RangeError('Link buttons must have a url');\n\t\t}\n\t} else if (url) {\n\t\tthrow new RangeError('Non-link buttons cannot have a url');\n\t}\n}\n","import {\n\tAPIActionRowComponent,\n\tAPIMessageActionRowComponent,\n\tAPIModalActionRowComponent,\n\tComponentType,\n} from 'discord-api-types/v9';\nimport type { ButtonComponent, SelectMenuComponent, TextInputComponent } from '../index';\nimport { Component } from './Component';\nimport { createComponent } from './Components';\nimport isEqual from 'fast-deep-equal';\n\nexport type MessageComponent = MessageActionRowComponent | ActionRow<MessageActionRowComponent>;\nexport type ModalComponent = ModalActionRowComponent | ActionRow<ModalActionRowComponent>;\n\nexport type MessageActionRowComponent = ButtonComponent | SelectMenuComponent;\nexport type ModalActionRowComponent = TextInputComponent;\n\n/**\n * Represents an action row component\n */\nexport class ActionRow<\n\tT extends ModalActionRowComponent | MessageActionRowComponent = ModalActionRowComponent | MessageActionRowComponent,\n> extends Component<\n\tOmit<\n\t\tPartial<APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>> & {\n\t\t\ttype: ComponentType.ActionRow;\n\t\t},\n\t\t'components'\n\t>\n> {\n\t/**\n\t * The components within this action row\n\t */\n\tpublic readonly components: T[];\n\n\tpublic constructor({\n\t\tcomponents,\n\t\t...data\n\t}: Partial<APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>> = {}) {\n\t\tsuper({ type: ComponentType.ActionRow, ...data });\n\t\tthis.components = (components?.map((c) => createComponent(c)) ?? []) as T[];\n\t}\n\n\t/**\n\t * Adds components to this action row.\n\t * @param components The components to add to this action row.\n\t * @returns\n\t */\n\tpublic addComponents(...components: T[]) {\n\t\tthis.components.push(...components);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the components in this action row\n\t * @param components The components to set this row to\n\t */\n\tpublic setComponents(...components: T[]) {\n\t\tthis.components.splice(0, this.components.length, ...components);\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIActionRowComponent<ReturnType<T['toJSON']>> {\n\t\treturn {\n\t\t\t...this.data,\n\t\t\tcomponents: this.components.map((component) => component.toJSON()) as ReturnType<T['toJSON']>[],\n\t\t};\n\t}\n\n\tpublic equals(other: APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent> | ActionRow) {\n\t\tif (other instanceof ActionRow) {\n\t\t\treturn isEqual(other.data, this.data) && isEqual(other.components, this.components);\n\t\t}\n\t\treturn isEqual(other, {\n\t\t\t...this.data,\n\t\t\tcomponents: this.components.map((component) => component.toJSON()),\n\t\t});\n\t}\n}\n","import type { JSONEncodable } from '../util/jsonEncodable';\nimport type {\n\tAPIActionRowComponent,\n\tAPIActionRowComponentTypes,\n\tAPIBaseComponent,\n\tAPIMessageActionRowComponent,\n\tAPIModalActionRowComponent,\n\tAPIMessageComponent,\n\tComponentType,\n\tAPIModalComponent,\n} from 'discord-api-types/v9';\nimport type { Equatable } from '../util/equatable';\n\n/**\n * Represents a discord component\n */\nexport abstract class Component<\n\tDataType extends Partial<APIBaseComponent<ComponentType>> & {\n\t\ttype: ComponentType;\n\t} = APIBaseComponent<ComponentType>,\n> implements\n\t\tJSONEncodable<\n\t\t\t| APIModalComponent\n\t\t\t| APIMessageComponent\n\t\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>\n\t\t>,\n\t\tEquatable<\n\t\t\t| Component\n\t\t\t| APIActionRowComponentTypes\n\t\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>\n\t\t>\n{\n\t/**\n\t * The API data associated with this component\n\t */\n\tpublic readonly data: DataType;\n\n\tpublic abstract toJSON():\n\t\t| APIActionRowComponentTypes\n\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>;\n\n\tpublic abstract equals(\n\t\tother:\n\t\t\t| Component\n\t\t\t| APIActionRowComponentTypes\n\t\t\t| APIActionRowComponent<APIModalActionRowComponent | APIMessageActionRowComponent>,\n\t): boolean;\n\n\tpublic constructor(data: DataType) {\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * The type of this component\n\t */\n\tpublic get type(): DataType['type'] {\n\t\treturn this.data.type;\n\t}\n}\n","import { APIBaseComponent, APIMessageComponent, APIModalComponent, ComponentType } from 'discord-api-types/v9';\nimport { ActionRow, ButtonComponent, Component, SelectMenuComponent, TextInputComponent } from '../index';\nimport type { MessageComponent, ModalActionRowComponent } from './ActionRow';\n\nexport interface MappedComponentTypes {\n\t[ComponentType.ActionRow]: ActionRow;\n\t[ComponentType.Button]: ButtonComponent;\n\t[ComponentType.SelectMenu]: SelectMenuComponent;\n\t[ComponentType.TextInput]: TextInputComponent;\n}\n\n/**\n * Factory for creating components from API data\n * @param data The api data to transform to a component class\n */\nexport function createComponent<T extends keyof MappedComponentTypes>(\n\tdata: (APIMessageComponent | APIModalComponent) & { type: T },\n): MappedComponentTypes[T];\nexport function createComponent<C extends MessageComponent | ModalActionRowComponent>(data: C): C;\nexport function createComponent(data: APIModalComponent | APIMessageComponent | Component): Component {\n\tif (data instanceof Component) {\n\t\treturn data;\n\t}\n\n\tswitch (data.type) {\n\t\tcase ComponentType.ActionRow:\n\t\t\treturn new ActionRow(data);\n\t\tcase ComponentType.Button:\n\t\t\treturn new ButtonComponent(data);\n\t\tcase ComponentType.SelectMenu:\n\t\t\treturn new SelectMenuComponent(data);\n\t\tcase ComponentType.TextInput:\n\t\t\treturn new TextInputComponent(data);\n\t\tdefault:\n\t\t\tthrow new Error(`Cannot serialize component type: ${(data as APIBaseComponent<ComponentType>).type}`);\n\t}\n}\n","import {\n\tComponentType,\n\tButtonStyle,\n\ttype APIMessageComponentEmoji,\n\ttype APIButtonComponent,\n\ttype APIButtonComponentWithURL,\n\ttype APIButtonComponentWithCustomId,\n} from 'discord-api-types/v9';\nimport { Component } from '../Component';\nimport isEqual from 'fast-deep-equal';\n\n/**\n * Represents a non-validated button component\n */\nexport class UnsafeButtonComponent extends Component<Partial<APIButtonComponent> & { type: ComponentType.Button }> {\n\tpublic constructor(data?: Partial<APIButtonComponent>) {\n\t\tsuper({ type: ComponentType.Button, ...data });\n\t}\n\n\t/**\n\t * The style of this button\n\t */\n\tpublic get style() {\n\t\treturn this.data.style;\n\t}\n\n\t/**\n\t * The label of this button\n\t */\n\tpublic get label() {\n\t\treturn this.data.label;\n\t}\n\n\t/**\n\t * The emoji used in this button\n\t */\n\tpublic get emoji() {\n\t\treturn this.data.emoji;\n\t}\n\n\t/**\n\t * Whether this button is disabled\n\t */\n\tpublic get disabled() {\n\t\treturn this.data.disabled;\n\t}\n\n\t/**\n\t * The custom id of this button (only defined on non-link buttons)\n\t */\n\tpublic get customId(): string | undefined {\n\t\treturn (this.data as APIButtonComponentWithCustomId).custom_id;\n\t}\n\n\t/**\n\t * The URL of this button (only defined on link buttons)\n\t */\n\tpublic get url(): string | undefined {\n\t\treturn (this.data as APIButtonComponentWithURL).url;\n\t}\n\n\t/**\n\t * Sets the style of this button\n\t * @param style The style of the button\n\t */\n\tpublic setStyle(style: ButtonStyle) {\n\t\tthis.data.style = style;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the URL for this button\n\t * @param url The URL to open when this button is clicked\n\t */\n\tpublic setURL(url: string) {\n\t\t(this.data as APIButtonComponentWithURL).url = url;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the custom Id for this button\n\t * @param customId The custom id to use for this button\n\t */\n\tpublic setCustomId(customId: string) {\n\t\t(this.data as APIButtonComponentWithCustomId).custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the emoji to display on this button\n\t * @param emoji The emoji to display on this button\n\t */\n\tpublic setEmoji(emoji: APIMessageComponentEmoji) {\n\t\tthis.data.emoji = emoji;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether this button is disable or not\n\t * @param disabled Whether or not to disable this button or not\n\t */\n\tpublic setDisabled(disabled = true) {\n\t\tthis.data.disabled = disabled;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the label for this button\n\t * @param label The label to display on this button\n\t */\n\tpublic setLabel(label: string) {\n\t\tthis.data.label = label;\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIButtonComponent {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t} as APIButtonComponent;\n\t}\n\n\tpublic equals(other: APIButtonComponent | UnsafeButtonComponent) {\n\t\tif (other instanceof UnsafeButtonComponent) {\n\t\t\treturn isEqual(other.data, this.data);\n\t\t}\n\t\treturn isEqual(other, this.data);\n\t}\n}\n","import type { ButtonStyle, APIMessageComponentEmoji, APIButtonComponent } from 'discord-api-types/v9';\nimport {\n\tbuttonLabelValidator,\n\tbuttonStyleValidator,\n\tcustomIdValidator,\n\tdisabledValidator,\n\temojiValidator,\n\turlValidator,\n\tvalidateRequiredButtonParameters,\n} from '../Assertions';\nimport { UnsafeButtonComponent } from './UnsafeButton';\n\n/**\n * Represents a validated button component\n */\nexport class ButtonComponent extends UnsafeButtonComponent {\n\tpublic override setStyle(style: ButtonStyle) {\n\t\treturn super.setStyle(buttonStyleValidator.parse(style));\n\t}\n\n\tpublic override setURL(url: string) {\n\t\treturn super.setURL(urlValidator.parse(url));\n\t}\n\n\tpublic override setCustomId(customId: string) {\n\t\treturn super.setCustomId(customIdValidator.parse(customId));\n\t}\n\n\tpublic override setEmoji(emoji: APIMessageComponentEmoji) {\n\t\treturn super.setEmoji(emojiValidator.parse(emoji));\n\t}\n\n\tpublic override setDisabled(disabled = true) {\n\t\treturn super.setDisabled(disabledValidator.parse(disabled));\n\t}\n\n\tpublic override setLabel(label: string) {\n\t\treturn super.setLabel(buttonLabelValidator.parse(label));\n\t}\n\n\tpublic override toJSON(): APIButtonComponent {\n\t\tvalidateRequiredButtonParameters(this.style, this.label, this.emoji, this.customId, this.url);\n\t\treturn super.toJSON();\n\t}\n}\n","import { TextInputStyle } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport { customIdValidator } from '../Assertions';\n\nexport const textInputStyleValidator = z.nativeEnum(TextInputStyle);\nexport const minLengthValidator = z.number().int().min(0).max(4000);\nexport const maxLengthValidator = z.number().int().min(1).max(4000);\nexport const requiredValidator = z.boolean();\nexport const valueValidator = z.string().max(4000);\nexport const placeholderValidator = z.string().max(100);\nexport const labelValidator = z.string().min(1).max(45);\n\nexport function validateRequiredParameters(customId?: string, style?: TextInputStyle, label?: string) {\n\tcustomIdValidator.parse(customId);\n\ttextInputStyleValidator.parse(style);\n\tlabelValidator.parse(label);\n}\n","import { ComponentType, type TextInputStyle, type APITextInputComponent } from 'discord-api-types/v9';\nimport { Component } from '../../index';\nimport isEqual from 'fast-deep-equal';\n\nexport class UnsafeTextInputComponent extends Component<\n\tPartial<APITextInputComponent> & { type: ComponentType.TextInput }\n> {\n\tpublic constructor(data?: APITextInputComponent & { type?: ComponentType.TextInput }) {\n\t\tsuper({ type: ComponentType.TextInput, ...data });\n\t}\n\n\t/**\n\t * The style of this text input\n\t */\n\tpublic get style() {\n\t\treturn this.data.style;\n\t}\n\n\t/**\n\t * The custom id of this text input\n\t */\n\tpublic get customId() {\n\t\treturn this.data.custom_id;\n\t}\n\n\t/**\n\t * The label for this text input\n\t */\n\tpublic get label() {\n\t\treturn this.data.label;\n\t}\n\n\t/**\n\t * The placeholder text for this text input\n\t */\n\tpublic get placeholder() {\n\t\treturn this.data.placeholder;\n\t}\n\n\t/**\n\t * The default value for this text input\n\t */\n\tpublic get value() {\n\t\treturn this.data.value;\n\t}\n\n\t/**\n\t * The minimum length of this text input\n\t */\n\tpublic get minLength() {\n\t\treturn this.data.min_length;\n\t}\n\n\t/**\n\t * The maximum length of this text input\n\t */\n\tpublic get maxLength() {\n\t\treturn this.data.max_length;\n\t}\n\n\t/**\n\t * Whether this text input is required\n\t */\n\tpublic get required() {\n\t\treturn this.data.required;\n\t}\n\n\t/**\n\t * Sets the custom id for this text input\n\t * @param customId The custom id of this text input\n\t */\n\tpublic setCustomId(customId: string) {\n\t\tthis.data.custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the label for this text input\n\t * @param label The label for this text input\n\t */\n\tpublic setLabel(label: string) {\n\t\tthis.data.label = label;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the style for this text input\n\t * @param style The style for this text input\n\t */\n\tpublic setStyle(style: TextInputStyle) {\n\t\tthis.data.style = style;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the minimum length of text for this text input\n\t * @param minLength The minimum length of text for this text input\n\t */\n\tpublic setMinLength(minLength: number) {\n\t\tthis.data.min_length = minLength;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum length of text for this text input\n\t * @param maxLength The maximum length of text for this text input\n\t */\n\tpublic setMaxLength(maxLength: number) {\n\t\tthis.data.max_length = maxLength;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the placeholder of this text input\n\t * @param placeholder The placeholder of this text input\n\t */\n\tpublic setPlaceholder(placeholder: string) {\n\t\tthis.data.placeholder = placeholder;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of this text input\n\t * @param value The value for this text input\n\t */\n\tpublic setValue(value: string) {\n\t\tthis.data.value = value;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether this text input is required or not\n\t * @param required Whether this text input is required or not\n\t */\n\tpublic setRequired(required = true) {\n\t\tthis.data.required = required;\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APITextInputComponent {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t} as APITextInputComponent;\n\t}\n\n\tpublic equals(other: UnsafeTextInputComponent | APITextInputComponent): boolean {\n\t\tif (other instanceof UnsafeTextInputComponent) {\n\t\t\treturn isEqual(other.data, this.data);\n\t\t}\n\n\t\treturn isEqual(other, this.data);\n\t}\n}\n","import type { APITextInputComponent } from 'discord-api-types/v9';\nimport {\n\tmaxLengthValidator,\n\tminLengthValidator,\n\tplaceholderValidator,\n\trequiredValidator,\n\tvalueValidator,\n\tvalidateRequiredParameters,\n} from './Assertions';\nimport { UnsafeTextInputComponent } from './UnsafeTextInput';\n\nexport class TextInputComponent extends UnsafeTextInputComponent {\n\tpublic override setMinLength(minLength: number) {\n\t\treturn super.setMinLength(minLengthValidator.parse(minLength));\n\t}\n\n\tpublic override setMaxLength(maxLength: number) {\n\t\treturn super.setMaxLength(maxLengthValidator.parse(maxLength));\n\t}\n\n\tpublic override setRequired(required = true) {\n\t\treturn super.setRequired(requiredValidator.parse(required));\n\t}\n\n\tpublic override setValue(value: string) {\n\t\treturn super.setValue(valueValidator.parse(value));\n\t}\n\n\tpublic override setPlaceholder(placeholder: string) {\n\t\treturn super.setPlaceholder(placeholderValidator.parse(placeholder));\n\t}\n\n\tpublic override toJSON(): APITextInputComponent {\n\t\tvalidateRequiredParameters(this.data.custom_id, this.data.style, this.data.label);\n\t\treturn super.toJSON();\n\t}\n}\n","import type {\n\tAPIActionRowComponent,\n\tAPIModalActionRowComponent,\n\tAPIModalInteractionResponseCallbackData,\n} from 'discord-api-types/v9';\nimport { ActionRow, createComponent, JSONEncodable, ModalActionRowComponent } from '../../index';\n\nexport class UnsafeModal implements JSONEncodable<APIModalInteractionResponseCallbackData> {\n\tprotected readonly data: Partial<Omit<APIModalInteractionResponseCallbackData, 'components'>>;\n\tpublic readonly components: ActionRow<ModalActionRowComponent>[] = [];\n\n\tpublic constructor({ components, ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) {\n\t\tthis.data = { ...data };\n\t\tthis.components = (components?.map((c) => createComponent(c)) ?? []) as ActionRow<ModalActionRowComponent>[];\n\t}\n\n\t/**\n\t * The custom id of this modal\n\t */\n\tpublic get customId() {\n\t\treturn this.data.custom_id;\n\t}\n\n\t/**\n\t * The title of this modal\n\t */\n\tpublic get title() {\n\t\treturn this.data.title;\n\t}\n\n\t/**\n\t * Sets the title of the modal\n\t * @param title The title of the modal\n\t */\n\tpublic setTitle(title: string) {\n\t\tthis.data.title = title;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the custom id of the modal\n\t * @param customId The custom id of this modal\n\t */\n\tpublic setCustomId(customId: string) {\n\t\tthis.data.custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds components to this modal\n\t * @param components The components to add to this modal\n\t */\n\tpublic addComponents(\n\t\t...components: (ActionRow<ModalActionRowComponent> | APIActionRowComponent<APIModalActionRowComponent>)[]\n\t) {\n\t\tthis.components.push(\n\t\t\t...components.map((component) =>\n\t\t\t\tcomponent instanceof ActionRow ? component : new ActionRow<ModalActionRowComponent>(component),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the components in this modal\n\t * @param components The components to set this modal to\n\t */\n\tpublic setComponents(...components: ActionRow<ModalActionRowComponent>[]) {\n\t\tthis.components.splice(0, this.components.length, ...components);\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIModalInteractionResponseCallbackData {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t\tcomponents: this.components.map((component) => component.toJSON()),\n\t\t} as APIModalInteractionResponseCallbackData;\n\t}\n}\n","import { z } from 'zod';\nimport { ActionRow, type ModalActionRowComponent } from '../..';\nimport { customIdValidator } from '../../components/Assertions';\n\nexport const titleValidator = z.string().min(1).max(45);\nexport const componentsValidator = z.array(z.instanceof(ActionRow)).min(1);\n\nexport function validateRequiredParameters(\n\tcustomId?: string,\n\ttitle?: string,\n\tcomponents?: ActionRow<ModalActionRowComponent>[],\n) {\n\tcustomIdValidator.parse(customId);\n\ttitleValidator.parse(title);\n\tcomponentsValidator.parse(components);\n}\n","import type { APIModalInteractionResponseCallbackData } from 'discord-api-types/v9';\nimport { customIdValidator } from '../../components/Assertions';\nimport { titleValidator, validateRequiredParameters } from './Assertions';\nimport { UnsafeModal } from './UnsafeModal';\n\nexport class Modal extends UnsafeModal {\n\tpublic override setCustomId(customId: string): this {\n\t\treturn super.setCustomId(customIdValidator.parse(customId));\n\t}\n\n\tpublic override setTitle(title: string) {\n\t\treturn super.setTitle(titleValidator.parse(title));\n\t}\n\n\tpublic override toJSON(): APIModalInteractionResponseCallbackData {\n\t\tvalidateRequiredParameters(this.data.custom_id, this.data.title, this.components);\n\t\treturn super.toJSON();\n\t}\n}\n","import { APISelectMenuOption, ComponentType, type APISelectMenuComponent } from 'discord-api-types/v9';\nimport { Component } from '../Component';\nimport { UnsafeSelectMenuOption } from './UnsafeSelectMenuOption';\nimport isEqual from 'fast-deep-equal';\n\n/**\n * Represents a non-validated select menu component\n */\nexport class UnsafeSelectMenuComponent extends Component<\n\tPartial<Omit<APISelectMenuComponent, 'options'>> & { type: ComponentType.SelectMenu }\n> {\n\t/**\n\t * The options within this select menu\n\t */\n\tpublic readonly options: UnsafeSelectMenuOption[];\n\n\tpublic constructor(data?: Partial<APISelectMenuComponent>) {\n\t\tconst { options, ...initData } = data ?? {};\n\t\tsuper({ type: ComponentType.SelectMenu, ...initData });\n\t\tthis.options = options?.map((o) => new UnsafeSelectMenuOption(o)) ?? [];\n\t}\n\n\t/**\n\t * The placeholder for this select menu\n\t */\n\tpublic get placeholder() {\n\t\treturn this.data.placeholder;\n\t}\n\n\t/**\n\t * The maximum amount of options that can be selected\n\t */\n\tpublic get maxValues() {\n\t\treturn this.data.max_values;\n\t}\n\n\t/**\n\t * The minimum amount of options that must be selected\n\t */\n\tpublic get minValues() {\n\t\treturn this.data.min_values;\n\t}\n\n\t/**\n\t * The custom id of this select menu\n\t */\n\tpublic get customId() {\n\t\treturn this.data.custom_id;\n\t}\n\n\t/**\n\t * Whether this select menu is disabled\n\t */\n\tpublic get disabled() {\n\t\treturn this.data.disabled;\n\t}\n\n\t/**\n\t * Sets the placeholder for this select menu\n\t * @param placeholder The placeholder to use for this select menu\n\t */\n\tpublic setPlaceholder(placeholder: string) {\n\t\tthis.data.placeholder = placeholder;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the minimum values that must be selected in the select menu\n\t * @param minValues The minimum values that must be selected\n\t */\n\tpublic setMinValues(minValues: number) {\n\t\tthis.data.min_values = minValues;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum values that must be selected in the select menu\n\t * @param minValues The maximum values that must be selected\n\t */\n\tpublic setMaxValues(maxValues: number) {\n\t\tthis.data.max_values = maxValues;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the custom Id for this select menu\n\t * @param customId The custom id to use for this select menu\n\t */\n\tpublic setCustomId(customId: string) {\n\t\tthis.data.custom_id = customId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether or not this select menu is disabled\n\t * @param disabled Whether or not this select menu is disabled\n\t */\n\tpublic setDisabled(disabled = true) {\n\t\tthis.data.disabled = disabled;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds options to this select menu\n\t * @param options The options to add to this select menu\n\t * @returns\n\t */\n\tpublic addOptions(...options: (UnsafeSelectMenuOption | APISelectMenuOption)[]) {\n\t\tthis.options.push(\n\t\t\t...options.map((option) =>\n\t\t\t\toption instanceof UnsafeSelectMenuOption ? option : new UnsafeSelectMenuOption(option),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the options on this select menu\n\t * @param options The options to set on this select menu\n\t */\n\tpublic setOptions(...options: (UnsafeSelectMenuOption | APISelectMenuOption)[]) {\n\t\tthis.options.splice(\n\t\t\t0,\n\t\t\tthis.options.length,\n\t\t\t...options.map((option) =>\n\t\t\t\toption instanceof UnsafeSelectMenuOption ? option : new UnsafeSelectMenuOption(option),\n\t\t\t),\n\t\t);\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APISelectMenuComponent {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t\toptions: this.options.map((o) => o.toJSON()),\n\t\t} as APISelectMenuComponent;\n\t}\n\n\tpublic equals(other: APISelectMenuComponent | UnsafeSelectMenuComponent): boolean {\n\t\tif (other instanceof UnsafeSelectMenuComponent) {\n\t\t\treturn isEqual(other.data, this.data) && isEqual(other.options, this.options);\n\t\t}\n\t\treturn isEqual(other, {\n\t\t\t...this.data,\n\t\t\toptions: this.options.map((o) => o.toJSON()),\n\t\t});\n\t}\n}\n","import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v9';\n\n/**\n * Represents a non-validated option within a select menu component\n */\nexport class UnsafeSelectMenuOption {\n\tpublic constructor(protected data: Partial<APISelectMenuOption> = {}) {}\n\n\t/**\n\t * The label for this option\n\t */\n\tpublic get label() {\n\t\treturn this.data.label;\n\t}\n\n\t/**\n\t * The value for this option\n\t */\n\tpublic get value() {\n\t\treturn this.data.value;\n\t}\n\n\t/**\n\t * The description for this option\n\t */\n\tpublic get description() {\n\t\treturn this.data.description;\n\t}\n\n\t/**\n\t * The emoji for this option\n\t */\n\tpublic get emoji() {\n\t\treturn this.data.emoji;\n\t}\n\n\t/**\n\t * Whether this option is selected by default\n\t */\n\tpublic get default() {\n\t\treturn this.data.default;\n\t}\n\n\t/**\n\t * Sets the label of this option\n\t * @param label The label to show on this option\n\t */\n\tpublic setLabel(label: string) {\n\t\tthis.data.label = label;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of this option\n\t * @param value The value of this option\n\t */\n\tpublic setValue(value: string) {\n\t\tthis.data.value = value;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the description of this option.\n\t * @param description The description of this option\n\t */\n\tpublic setDescription(description: string) {\n\t\tthis.data.description = description;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether this option is selected by default\n\t * @param isDefault Whether this option is selected by default\n\t */\n\tpublic setDefault(isDefault = true) {\n\t\tthis.data.default = isDefault;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the emoji to display on this button\n\t * @param emoji The emoji to display on this button\n\t */\n\tpublic setEmoji(emoji: APIMessageComponentEmoji) {\n\t\tthis.data.emoji = emoji;\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APISelectMenuOption {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\t...this.data,\n\t\t} as APISelectMenuOption;\n\t}\n}\n","import type { APISelectMenuComponent } from 'discord-api-types/v9';\nimport {\n\tcustomIdValidator,\n\tdisabledValidator,\n\tminMaxValidator,\n\tplaceholderValidator,\n\tvalidateRequiredSelectMenuParameters,\n} from '../Assertions';\nimport { UnsafeSelectMenuComponent } from './UnsafeSelectMenu';\n\n/**\n * Represents a validated select menu component\n */\nexport class SelectMenuComponent extends UnsafeSelectMenuComponent {\n\tpublic override setPlaceholder(placeholder: string) {\n\t\treturn super.setPlaceholder(placeholderValidator.parse(placeholder));\n\t}\n\n\tpublic override setMinValues(minValues: number) {\n\t\treturn super.setMinValues(minMaxValidator.parse(minValues));\n\t}\n\n\tpublic override setMaxValues(maxValues: number) {\n\t\treturn super.setMaxValues(minMaxValidator.parse(maxValues));\n\t}\n\n\tpublic override setCustomId(customId: string) {\n\t\treturn super.setCustomId(customIdValidator.parse(customId));\n\t}\n\n\tpublic override setDisabled(disabled = true) {\n\t\treturn super.setDisabled(disabledValidator.parse(disabled));\n\t}\n\n\tpublic override toJSON(): APISelectMenuComponent {\n\t\tvalidateRequiredSelectMenuParameters(this.options, this.customId);\n\t\treturn super.toJSON();\n\t}\n}\n","import type { APIMessageComponentEmoji, APISelectMenuOption } from 'discord-api-types/v9';\nimport {\n\tdefaultValidator,\n\temojiValidator,\n\tlabelValueValidator,\n\tvalidateRequiredSelectMenuOptionParameters,\n} from '../Assertions';\nimport { UnsafeSelectMenuOption } from './UnsafeSelectMenuOption';\n\n/**\n * Represents a validated option within a select menu component\n */\nexport class SelectMenuOption extends UnsafeSelectMenuOption {\n\tpublic override setDescription(description: string) {\n\t\treturn super.setDescription(labelValueValidator.parse(description));\n\t}\n\n\tpublic override setDefault(isDefault = true) {\n\t\treturn super.setDefault(defaultValidator.parse(isDefault));\n\t}\n\n\tpublic override setEmoji(emoji: APIMessageComponentEmoji) {\n\t\treturn super.setEmoji(emojiValidator.parse(emoji));\n\t}\n\n\tpublic override toJSON(): APISelectMenuOption {\n\t\tvalidateRequiredSelectMenuOptionParameters(this.label, this.value);\n\t\treturn super.toJSON();\n\t}\n}\n","import is from '@sindresorhus/is';\nimport type { APIApplicationCommandOptionChoice } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase';\nimport type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder';\nimport type { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands';\n\nconst namePredicate = z\n\t.string()\n\t.min(1)\n\t.max(32)\n\t.regex(/^[\\P{Lu}\\p{N}_-]+$/u);\n\nexport function validateName(name: unknown): asserts name is string {\n\tnamePredicate.parse(name);\n}\n\nconst descriptionPredicate = z.string().min(1).max(100);\n\nexport function validateDescription(description: unknown): asserts description is string {\n\tdescriptionPredicate.parse(description);\n}\n\nconst maxArrayLengthPredicate = z.unknown().array().max(25);\n\nexport function validateMaxOptionsLength(options: unknown): asserts options is ToAPIApplicationCommandOptions[] {\n\tmaxArrayLengthPredicate.parse(options);\n}\n\nexport function validateRequiredParameters(\n\tname: string,\n\tdescription: string,\n\toptions: ToAPIApplicationCommandOptions[],\n) {\n\t// Assert name matches all conditions\n\tvalidateName(name);\n\n\t// Assert description conditions\n\tvalidateDescription(description);\n\n\t// Assert options conditions\n\tvalidateMaxOptionsLength(options);\n}\n\nconst booleanPredicate = z.boolean();\n\nexport function validateDefaultPermission(value: unknown): asserts value is boolean {\n\tbooleanPredicate.parse(value);\n}\n\nexport function validateRequired(required: unknown): asserts required is boolean {\n\tbooleanPredicate.parse(required);\n}\n\nconst choicesLengthPredicate = z.number().lte(25);\n\nexport function validateChoicesLength(amountAdding: number, choices?: APIApplicationCommandOptionChoice[]): void {\n\tchoicesLengthPredicate.parse((choices?.length ?? 0) + amountAdding);\n}\n\nexport function assertReturnOfBuilder<\n\tT extends ApplicationCommandOptionBase | SlashCommandSubcommandBuilder | SlashCommandSubcommandGroupBuilder,\n>(input: unknown, ExpectedInstanceOf: new () => T): asserts input is T {\n\tconst instanceName = ExpectedInstanceOf.name;\n\n\tif (is.nullOrUndefined(input)) {\n\t\tthrow new TypeError(\n\t\t\t`Expected to receive a ${instanceName} builder, got ${input === null ? 'null' : 'undefined'} instead.`,\n\t\t);\n\t}\n\n\tif (is.primitive(input)) {\n\t\tthrow new TypeError(`Expected to receive a ${instanceName} builder, got a primitive (${typeof input}) instead.`);\n\t}\n\n\tif (!(input instanceof ExpectedInstanceOf)) {\n\t\tconst casted = input as Record<PropertyKey, unknown>;\n\n\t\tconst constructorName = is.function_(input) ? input.name : casted.constructor.name;\n\t\tconst stringTag = Reflect.get(casted, Symbol.toStringTag) as string | undefined;\n\n\t\tconst fullResultName = stringTag ? `${constructorName} [${stringTag}]` : constructorName;\n\n\t\tthrow new TypeError(`Expected to receive a ${instanceName} builder, got ${fullResultName} instead.`);\n\t}\n}\n","import type { APIApplicationCommandOption, RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport {\n\tassertReturnOfBuilder,\n\tvalidateDefaultPermission,\n\tvalidateMaxOptionsLength,\n\tvalidateRequiredParameters,\n} from './Assertions';\nimport { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions';\nimport { SharedNameAndDescription } from './mixins/NameAndDescription';\nimport { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands';\n\n@mix(SharedSlashCommandOptions, SharedNameAndDescription)\nexport class SlashCommandBuilder {\n\t/**\n\t * The name of this slash command\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The description of this slash command\n\t */\n\tpublic readonly description: string = undefined!;\n\n\t/**\n\t * The options of this slash command\n\t */\n\tpublic readonly options: ToAPIApplicationCommandOptions[] = [];\n\n\t/**\n\t * Whether the command is enabled by default when the app is added to a guild\n\t *\n\t * @default true\n\t */\n\tpublic readonly defaultPermission: boolean | undefined = undefined;\n\n\t/**\n\t * Returns the final data that should be sent to Discord.\n\t *\n\t * **Note:** Calling this function will validate required properties based on their conditions.\n\t */\n\tpublic toJSON(): RESTPostAPIApplicationCommandsJSONBody {\n\t\tvalidateRequiredParameters(this.name, this.description, this.options);\n\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tdescription: this.description,\n\t\t\toptions: this.options.map((option) => option.toJSON()),\n\t\t\tdefault_permission: this.defaultPermission,\n\t\t};\n\t}\n\n\t/**\n\t * Sets whether the command is enabled by default when the application is added to a guild.\n\t *\n\t * **Note**: If set to `false`, you will have to later `PUT` the permissions for this command.\n\t *\n\t * @param value Whether or not to enable this command by default\n\t *\n\t * @see https://discord.com/developers/docs/interactions/application-commands#permissions\n\t */\n\tpublic setDefaultPermission(value: boolean) {\n\t\t// Assert the value matches the conditions\n\t\tvalidateDefaultPermission(value);\n\n\t\tReflect.set(this, 'defaultPermission', value);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a new subcommand group to this command\n\t *\n\t * @param input A function that returns a subcommand group builder, or an already built builder\n\t */\n\tpublic addSubcommandGroup(\n\t\tinput:\n\t\t\t| SlashCommandSubcommandGroupBuilder\n\t\t\t| ((subcommandGroup: SlashCommandSubcommandGroupBuilder) => SlashCommandSubcommandGroupBuilder),\n\t): SlashCommandSubcommandsOnlyBuilder {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\tconst result = typeof input === 'function' ? input(new SlashCommandSubcommandGroupBuilder()) : input;\n\n\t\tassertReturnOfBuilder(result, SlashCommandSubcommandGroupBuilder);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a new subcommand to this command\n\t *\n\t * @param input A function that returns a subcommand builder, or an already built builder\n\t */\n\tpublic addSubcommand(\n\t\tinput:\n\t\t\t| SlashCommandSubcommandBuilder\n\t\t\t| ((subcommandGroup: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder),\n\t): SlashCommandSubcommandsOnlyBuilder {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\tconst result = typeof input === 'function' ? input(new SlashCommandSubcommandBuilder()) : input;\n\n\t\tassertReturnOfBuilder(result, SlashCommandSubcommandBuilder);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n}\n\nexport interface SlashCommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions {}\n\nexport interface SlashCommandSubcommandsOnlyBuilder\n\textends SharedNameAndDescription,\n\t\tPick<SlashCommandBuilder, 'toJSON' | 'addSubcommand' | 'addSubcommandGroup'> {}\n\nexport interface SlashCommandOptionsOnlyBuilder\n\textends SharedNameAndDescription,\n\t\tSharedSlashCommandOptions,\n\t\tPick<SlashCommandBuilder, 'toJSON'> {}\n\nexport interface ToAPIApplicationCommandOptions {\n\ttoJSON: () => APIApplicationCommandOption;\n}\n","import { APIApplicationCommandBooleanOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandBooleanOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.Boolean as const;\n\n\tpublic toJSON(): APIApplicationCommandBooleanOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { validateDescription, validateName } from '../Assertions';\n\nexport class SharedNameAndDescription {\n\tpublic readonly name!: string;\n\tpublic readonly description!: string;\n\n\t/**\n\t * Sets the name\n\t *\n\t * @param name The name\n\t */\n\tpublic setName(name: string): this {\n\t\t// Assert the name matches the conditions\n\t\tvalidateName(name);\n\n\t\tReflect.set(this, 'name', name);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the description\n\t *\n\t * @param description The description\n\t */\n\tpublic setDescription(description: string) {\n\t\t// Assert the description matches the conditions\n\t\tvalidateDescription(description);\n\n\t\tReflect.set(this, 'description', description);\n\n\t\treturn this;\n\t}\n}\n","import type { APIApplicationCommandBasicOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { validateRequiredParameters, validateRequired } from '../Assertions';\nimport { SharedNameAndDescription } from './NameAndDescription';\n\nexport abstract class ApplicationCommandOptionBase extends SharedNameAndDescription {\n\tpublic abstract readonly type: ApplicationCommandOptionType;\n\n\tpublic readonly required: boolean = false;\n\n\t/**\n\t * Marks the option as required\n\t *\n\t * @param required If this option should be required\n\t */\n\tpublic setRequired(required: boolean) {\n\t\t// Assert that you actually passed a boolean\n\t\tvalidateRequired(required);\n\n\t\tReflect.set(this, 'required', required);\n\n\t\treturn this;\n\t}\n\n\tpublic abstract toJSON(): APIApplicationCommandBasicOption;\n\n\tprotected runRequiredValidations() {\n\t\tvalidateRequiredParameters(this.name, this.description, []);\n\n\t\t// Assert that you actually passed a boolean\n\t\tvalidateRequired(this.required);\n\t}\n}\n","import { APIApplicationCommandChannelOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionChannelTypesMixin } from '../mixins/ApplicationCommandOptionChannelTypesMixin';\n\n@mix(ApplicationCommandOptionChannelTypesMixin)\nexport class SlashCommandChannelOption extends ApplicationCommandOptionBase {\n\tpublic override readonly type = ApplicationCommandOptionType.Channel as const;\n\n\tpublic toJSON(): APIApplicationCommandChannelOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandChannelOption extends ApplicationCommandOptionChannelTypesMixin {}\n","import { ChannelType } from 'discord-api-types/v9';\nimport { z, ZodLiteral } from 'zod';\n\n// Only allow valid channel types to be used. (This can't be dynamic because const enums are erased at runtime)\nconst allowedChannelTypes = [\n\tChannelType.GuildText,\n\tChannelType.GuildVoice,\n\tChannelType.GuildCategory,\n\tChannelType.GuildNews,\n\tChannelType.GuildStore,\n\tChannelType.GuildNewsThread,\n\tChannelType.GuildPublicThread,\n\tChannelType.GuildPrivateThread,\n\tChannelType.GuildStageVoice,\n] as const;\n\nexport type ApplicationCommandOptionAllowedChannelTypes = typeof allowedChannelTypes[number];\n\nconst channelTypesPredicate = z.array(\n\tz.union(\n\t\tallowedChannelTypes.map((type) => z.literal(type)) as [\n\t\t\tZodLiteral<ChannelType>,\n\t\t\tZodLiteral<ChannelType>,\n\t\t\t...ZodLiteral<ChannelType>[]\n\t\t],\n\t),\n);\n\nexport class ApplicationCommandOptionChannelTypesMixin {\n\tpublic readonly channel_types?: ApplicationCommandOptionAllowedChannelTypes[];\n\n\t/**\n\t * Adds channel types to this option\n\t *\n\t * @param channelTypes The channel types to add\n\t */\n\tpublic addChannelTypes(...channelTypes: ApplicationCommandOptionAllowedChannelTypes[]) {\n\t\tif (this.channel_types === undefined) {\n\t\t\tReflect.set(this, 'channel_types', []);\n\t\t}\n\n\t\tchannelTypesPredicate.parse(channelTypes);\n\n\t\tthis.channel_types!.push(...channelTypes);\n\n\t\treturn this;\n\t}\n}\n","import { APIApplicationCommandIntegerOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { z } from 'zod';\nimport { ApplicationCommandNumericOptionMinMaxValueMixin } from '../mixins/ApplicationCommandNumericOptionMinMaxValueMixin';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin';\n\nconst numberValidator = z.number().int();\n\n@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)\nexport class SlashCommandIntegerOption\n\textends ApplicationCommandOptionBase\n\timplements ApplicationCommandNumericOptionMinMaxValueMixin\n{\n\tpublic readonly type = ApplicationCommandOptionType.Integer as const;\n\n\tpublic setMaxValue(max: number): this {\n\t\tnumberValidator.parse(max);\n\n\t\tReflect.set(this, 'max_value', max);\n\n\t\treturn this;\n\t}\n\n\tpublic setMinValue(min: number): this {\n\t\tnumberValidator.parse(min);\n\n\t\tReflect.set(this, 'min_value', min);\n\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIApplicationCommandIntegerOption {\n\t\tthis.runRequiredValidations();\n\n\t\tif (this.autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandIntegerOption\n\textends ApplicationCommandNumericOptionMinMaxValueMixin,\n\t\tApplicationCommandOptionWithChoicesAndAutocompleteMixin<number> {}\n","export abstract class ApplicationCommandNumericOptionMinMaxValueMixin {\n\tpublic readonly max_value?: number;\n\tpublic readonly min_value?: number;\n\n\t/**\n\t * Sets the maximum number value of this option\n\t * @param max The maximum value this option can be\n\t */\n\tpublic abstract setMaxValue(max: number): this;\n\n\t/**\n\t * Sets the minimum number value of this option\n\t * @param min The minimum value this option can be\n\t */\n\tpublic abstract setMinValue(min: number): this;\n}\n","import { APIApplicationCommandOptionChoice, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { z } from 'zod';\nimport { validateChoicesLength } from '../Assertions';\n\nconst stringPredicate = z.string().min(1).max(100);\nconst numberPredicate = z.number().gt(-Infinity).lt(Infinity);\nconst choicesPredicate = z\n\t.object({ name: stringPredicate, value: z.union([stringPredicate, numberPredicate]) })\n\t.array();\nconst booleanPredicate = z.boolean();\n\nexport class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends string | number> {\n\tpublic readonly choices?: APIApplicationCommandOptionChoice<T>[];\n\tpublic readonly autocomplete?: boolean;\n\n\t// Since this is present and this is a mixin, this is needed\n\tpublic readonly type!: ApplicationCommandOptionType;\n\n\t/**\n\t * Adds multiple choices for this option\n\t *\n\t * @param choices The choices to add\n\t */\n\tpublic addChoices(...choices: APIApplicationCommandOptionChoice<T>[]): this {\n\t\tif (choices.length > 0 && this.autocomplete) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tchoicesPredicate.parse(choices);\n\n\t\tif (this.choices === undefined) {\n\t\t\tReflect.set(this, 'choices', []);\n\t\t}\n\n\t\tvalidateChoicesLength(choices.length, this.choices);\n\n\t\tfor (const { name, value } of choices) {\n\t\t\t// Validate the value\n\t\t\tif (this.type === ApplicationCommandOptionType.String) {\n\t\t\t\tstringPredicate.parse(value);\n\t\t\t} else {\n\t\t\t\tnumberPredicate.parse(value);\n\t\t\t}\n\n\t\t\tthis.choices!.push({ name, value });\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tpublic setChoices<Input extends APIApplicationCommandOptionChoice<T>[]>(...choices: Input): this {\n\t\tif (choices.length > 0 && this.autocomplete) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tchoicesPredicate.parse(choices);\n\n\t\tReflect.set(this, 'choices', []);\n\t\tthis.addChoices(...choices);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Marks the option as autocompletable\n\t * @param autocomplete If this option should be autocompletable\n\t */\n\tpublic setAutocomplete(autocomplete: boolean): this {\n\t\t// Assert that you actually passed a boolean\n\t\tbooleanPredicate.parse(autocomplete);\n\n\t\tif (autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tReflect.set(this, 'autocomplete', autocomplete);\n\n\t\treturn this;\n\t}\n}\n","import { APIApplicationCommandMentionableOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandMentionableOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.Mentionable as const;\n\n\tpublic toJSON(): APIApplicationCommandMentionableOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { APIApplicationCommandNumberOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { z } from 'zod';\nimport { ApplicationCommandNumericOptionMinMaxValueMixin } from '../mixins/ApplicationCommandNumericOptionMinMaxValueMixin';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin';\n\nconst numberValidator = z.number();\n\n@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)\nexport class SlashCommandNumberOption\n\textends ApplicationCommandOptionBase\n\timplements ApplicationCommandNumericOptionMinMaxValueMixin\n{\n\tpublic readonly type = ApplicationCommandOptionType.Number as const;\n\n\tpublic setMaxValue(max: number): this {\n\t\tnumberValidator.parse(max);\n\n\t\tReflect.set(this, 'max_value', max);\n\n\t\treturn this;\n\t}\n\n\tpublic setMinValue(min: number): this {\n\t\tnumberValidator.parse(min);\n\n\t\tReflect.set(this, 'min_value', min);\n\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIApplicationCommandNumberOption {\n\t\tthis.runRequiredValidations();\n\n\t\tif (this.autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandNumberOption\n\textends ApplicationCommandNumericOptionMinMaxValueMixin,\n\t\tApplicationCommandOptionWithChoicesAndAutocompleteMixin<number> {}\n","import { APIApplicationCommandRoleOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandRoleOption extends ApplicationCommandOptionBase {\n\tpublic override readonly type = ApplicationCommandOptionType.Role as const;\n\n\tpublic toJSON(): APIApplicationCommandRoleOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { APIApplicationCommandAttachmentOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandAttachmentOption extends ApplicationCommandOptionBase {\n\tpublic override readonly type = ApplicationCommandOptionType.Attachment as const;\n\n\tpublic toJSON(): APIApplicationCommandAttachmentOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { APIApplicationCommandStringOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\nimport { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithChoicesAndAutocompleteMixin';\n\n@mix(ApplicationCommandOptionWithChoicesAndAutocompleteMixin)\nexport class SlashCommandStringOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.String as const;\n\n\tpublic toJSON(): APIApplicationCommandStringOption {\n\t\tthis.runRequiredValidations();\n\n\t\tif (this.autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\treturn { ...this };\n\t}\n}\n\nexport interface SlashCommandStringOption extends ApplicationCommandOptionWithChoicesAndAutocompleteMixin<string> {}\n","import { APIApplicationCommandUserOption, ApplicationCommandOptionType } from 'discord-api-types/v9';\nimport { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase';\n\nexport class SlashCommandUserOption extends ApplicationCommandOptionBase {\n\tpublic readonly type = ApplicationCommandOptionType.User as const;\n\n\tpublic toJSON(): APIApplicationCommandUserOption {\n\t\tthis.runRequiredValidations();\n\n\t\treturn { ...this };\n\t}\n}\n","import { assertReturnOfBuilder, validateMaxOptionsLength } from '../Assertions';\nimport type { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase';\nimport { SlashCommandBooleanOption } from '../options/boolean';\nimport { SlashCommandChannelOption } from '../options/channel';\nimport { SlashCommandIntegerOption } from '../options/integer';\nimport { SlashCommandMentionableOption } from '../options/mentionable';\nimport { SlashCommandNumberOption } from '../options/number';\nimport { SlashCommandRoleOption } from '../options/role';\nimport { SlashCommandAttachmentOption } from '../options/attachment';\nimport { SlashCommandStringOption } from '../options/string';\nimport { SlashCommandUserOption } from '../options/user';\nimport type { ToAPIApplicationCommandOptions } from '../SlashCommandBuilder';\n\nexport class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {\n\tpublic readonly options!: ToAPIApplicationCommandOptions[];\n\n\t/**\n\t * Adds a boolean option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addBooleanOption(\n\t\tinput: SlashCommandBooleanOption | ((builder: SlashCommandBooleanOption) => SlashCommandBooleanOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandBooleanOption);\n\t}\n\n\t/**\n\t * Adds a user option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addUserOption(input: SlashCommandUserOption | ((builder: SlashCommandUserOption) => SlashCommandUserOption)) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandUserOption);\n\t}\n\n\t/**\n\t * Adds a channel option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addChannelOption(\n\t\tinput: SlashCommandChannelOption | ((builder: SlashCommandChannelOption) => SlashCommandChannelOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandChannelOption);\n\t}\n\n\t/**\n\t * Adds a role option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addRoleOption(input: SlashCommandRoleOption | ((builder: SlashCommandRoleOption) => SlashCommandRoleOption)) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandRoleOption);\n\t}\n\n\t/**\n\t * Adds an attachment option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addAttachmentOption(\n\t\tinput: SlashCommandAttachmentOption | ((builder: SlashCommandAttachmentOption) => SlashCommandAttachmentOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandAttachmentOption);\n\t}\n\n\t/**\n\t * Adds a mentionable option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addMentionableOption(\n\t\tinput: SlashCommandMentionableOption | ((builder: SlashCommandMentionableOption) => SlashCommandMentionableOption),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandMentionableOption);\n\t}\n\n\t/**\n\t * Adds a string option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addStringOption(\n\t\tinput:\n\t\t\t| SlashCommandStringOption\n\t\t\t| Omit<SlashCommandStringOption, 'setAutocomplete'>\n\t\t\t| Omit<SlashCommandStringOption, 'addChoices'>\n\t\t\t| ((\n\t\t\t\t\tbuilder: SlashCommandStringOption,\n\t\t\t ) =>\n\t\t\t\t\t| SlashCommandStringOption\n\t\t\t\t\t| Omit<SlashCommandStringOption, 'setAutocomplete'>\n\t\t\t\t\t| Omit<SlashCommandStringOption, 'addChoices'>),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandStringOption);\n\t}\n\n\t/**\n\t * Adds an integer option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addIntegerOption(\n\t\tinput:\n\t\t\t| SlashCommandIntegerOption\n\t\t\t| Omit<SlashCommandIntegerOption, 'setAutocomplete'>\n\t\t\t| Omit<SlashCommandIntegerOption, 'addChoices'>\n\t\t\t| ((\n\t\t\t\t\tbuilder: SlashCommandIntegerOption,\n\t\t\t ) =>\n\t\t\t\t\t| SlashCommandIntegerOption\n\t\t\t\t\t| Omit<SlashCommandIntegerOption, 'setAutocomplete'>\n\t\t\t\t\t| Omit<SlashCommandIntegerOption, 'addChoices'>),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandIntegerOption);\n\t}\n\n\t/**\n\t * Adds a number option\n\t *\n\t * @param input A function that returns an option builder, or an already built builder\n\t */\n\tpublic addNumberOption(\n\t\tinput:\n\t\t\t| SlashCommandNumberOption\n\t\t\t| Omit<SlashCommandNumberOption, 'setAutocomplete'>\n\t\t\t| Omit<SlashCommandNumberOption, 'addChoices'>\n\t\t\t| ((\n\t\t\t\t\tbuilder: SlashCommandNumberOption,\n\t\t\t ) =>\n\t\t\t\t\t| SlashCommandNumberOption\n\t\t\t\t\t| Omit<SlashCommandNumberOption, 'setAutocomplete'>\n\t\t\t\t\t| Omit<SlashCommandNumberOption, 'addChoices'>),\n\t) {\n\t\treturn this._sharedAddOptionMethod(input, SlashCommandNumberOption);\n\t}\n\n\tprivate _sharedAddOptionMethod<T extends ApplicationCommandOptionBase>(\n\t\tinput:\n\t\t\t| T\n\t\t\t| Omit<T, 'setAutocomplete'>\n\t\t\t| Omit<T, 'addChoices'>\n\t\t\t| ((builder: T) => T | Omit<T, 'setAutocomplete'> | Omit<T, 'addChoices'>),\n\t\tInstance: new () => T,\n\t): ShouldOmitSubcommandFunctions extends true ? Omit<this, 'addSubcommand' | 'addSubcommandGroup'> : this {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\tconst result = typeof input === 'function' ? input(new Instance()) : input;\n\n\t\tassertReturnOfBuilder(result, Instance);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n}\n","import {\n\tAPIApplicationCommandSubcommandGroupOption,\n\tAPIApplicationCommandSubcommandOption,\n\tApplicationCommandOptionType,\n} from 'discord-api-types/v9';\nimport { mix } from 'ts-mixer';\nimport { assertReturnOfBuilder, validateMaxOptionsLength, validateRequiredParameters } from './Assertions';\nimport type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase';\nimport { SharedNameAndDescription } from './mixins/NameAndDescription';\nimport { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions';\nimport type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder';\n\n/**\n * Represents a folder for subcommands\n *\n * For more information, go to https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups\n */\n@mix(SharedNameAndDescription)\nexport class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationCommandOptions {\n\t/**\n\t * The name of this subcommand group\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The description of this subcommand group\n\t */\n\tpublic readonly description: string = undefined!;\n\n\t/**\n\t * The subcommands part of this subcommand group\n\t */\n\tpublic readonly options: SlashCommandSubcommandBuilder[] = [];\n\n\t/**\n\t * Adds a new subcommand to this group\n\t *\n\t * @param input A function that returns a subcommand builder, or an already built builder\n\t */\n\tpublic addSubcommand(\n\t\tinput:\n\t\t\t| SlashCommandSubcommandBuilder\n\t\t\t| ((subcommandGroup: SlashCommandSubcommandBuilder) => SlashCommandSubcommandBuilder),\n\t) {\n\t\tconst { options } = this;\n\n\t\t// First, assert options conditions - we cannot have more than 25 options\n\t\tvalidateMaxOptionsLength(options);\n\n\t\t// Get the final result\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\tconst result = typeof input === 'function' ? input(new SlashCommandSubcommandBuilder()) : input;\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\tassertReturnOfBuilder(result, SlashCommandSubcommandBuilder);\n\n\t\t// Push it\n\t\toptions.push(result);\n\n\t\treturn this;\n\t}\n\n\tpublic toJSON(): APIApplicationCommandSubcommandGroupOption {\n\t\tvalidateRequiredParameters(this.name, this.description, this.options);\n\n\t\treturn {\n\t\t\ttype: ApplicationCommandOptionType.SubcommandGroup,\n\t\t\tname: this.name,\n\t\t\tdescription: this.description,\n\t\t\toptions: this.options.map((option) => option.toJSON()),\n\t\t};\n\t}\n}\n\nexport interface SlashCommandSubcommandGroupBuilder extends SharedNameAndDescription {}\n\n/**\n * Represents a subcommand\n *\n * For more information, go to https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups\n */\n@mix(SharedNameAndDescription, SharedSlashCommandOptions)\nexport class SlashCommandSubcommandBuilder implements ToAPIApplicationCommandOptions {\n\t/**\n\t * The name of this subcommand\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The description of this subcommand\n\t */\n\tpublic readonly description: string = undefined!;\n\n\t/**\n\t * The options of this subcommand\n\t */\n\tpublic readonly options: ApplicationCommandOptionBase[] = [];\n\n\tpublic toJSON(): APIApplicationCommandSubcommandOption {\n\t\tvalidateRequiredParameters(this.name, this.description, this.options);\n\n\t\treturn {\n\t\t\ttype: ApplicationCommandOptionType.Subcommand,\n\t\t\tname: this.name,\n\t\t\tdescription: this.description,\n\t\t\toptions: this.options.map((option) => option.toJSON()),\n\t\t};\n\t}\n}\n\nexport interface SlashCommandSubcommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions<false> {}\n","import { z } from 'zod';\nimport { ApplicationCommandType } from 'discord-api-types/v9';\nimport type { ContextMenuCommandType } from './ContextMenuCommandBuilder';\n\nconst namePredicate = z\n\t.string()\n\t.min(1)\n\t.max(32)\n\t.regex(/^( *[\\p{L}\\p{N}_-]+ *)+$/u);\n\nconst typePredicate = z.union([z.literal(ApplicationCommandType.User), z.literal(ApplicationCommandType.Message)]);\n\nconst booleanPredicate = z.boolean();\n\nexport function validateDefaultPermission(value: unknown): asserts value is boolean {\n\tbooleanPredicate.parse(value);\n}\n\nexport function validateName(name: unknown): asserts name is string {\n\tnamePredicate.parse(name);\n}\n\nexport function validateType(type: unknown): asserts type is ContextMenuCommandType {\n\ttypePredicate.parse(type);\n}\n\nexport function validateRequiredParameters(name: string, type: number) {\n\t// Assert name matches all conditions\n\tvalidateName(name);\n\n\t// Assert type is valid\n\tvalidateType(type);\n}\n","import { validateRequiredParameters, validateName, validateType, validateDefaultPermission } from './Assertions';\nimport type { ApplicationCommandType, RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v9';\n\nexport class ContextMenuCommandBuilder {\n\t/**\n\t * The name of this context menu command\n\t */\n\tpublic readonly name: string = undefined!;\n\n\t/**\n\t * The type of this context menu command\n\t */\n\tpublic readonly type: ContextMenuCommandType = undefined!;\n\n\t/**\n\t * Whether the command is enabled by default when the app is added to a guild\n\t *\n\t * @default true\n\t */\n\tpublic readonly defaultPermission: boolean | undefined = undefined;\n\n\t/**\n\t * Sets the name\n\t *\n\t * @param name The name\n\t */\n\tpublic setName(name: string) {\n\t\t// Assert the name matches the conditions\n\t\tvalidateName(name);\n\n\t\tReflect.set(this, 'name', name);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the type\n\t *\n\t * @param type The type\n\t */\n\tpublic setType(type: ContextMenuCommandType) {\n\t\t// Assert the type is valid\n\t\tvalidateType(type);\n\n\t\tReflect.set(this, 'type', type);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets whether the command is enabled by default when the application is added to a guild.\n\t *\n\t * **Note**: If set to `false`, you will have to later `PUT` the permissions for this command.\n\t *\n\t * @param value Whether or not to enable this command by default\n\t *\n\t * @see https://discord.com/developers/docs/interactions/application-commands#permissions\n\t */\n\tpublic setDefaultPermission(value: boolean) {\n\t\t// Assert the value matches the conditions\n\t\tvalidateDefaultPermission(value);\n\n\t\tReflect.set(this, 'defaultPermission', value);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns the final data that should be sent to Discord.\n\t *\n\t * **Note:** Calling this function will validate required properties based on their conditions.\n\t */\n\tpublic toJSON(): RESTPostAPIApplicationCommandsJSONBody {\n\t\tvalidateRequiredParameters(this.name, this.type);\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\ttype: this.type,\n\t\t\tdefault_permission: this.defaultPermission,\n\t\t};\n\t}\n}\n\nexport type ContextMenuCommandType = ApplicationCommandType.User | ApplicationCommandType.Message;\n","export interface JSONEncodable<T> {\n\t/**\n\t * Transforms this object to its JSON format\n\t */\n\ttoJSON: () => T;\n}\n\n/**\n * Indicates if an object is encodable or not.\n * @param maybeEncodable The object to check against\n */\nexport function isJSONEncodable(maybeEncodable: unknown): maybeEncodable is JSONEncodable<unknown> {\n\treturn maybeEncodable !== null && typeof maybeEncodable === 'object' && 'toJSON' in maybeEncodable;\n}\n"],"mappings":"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","names":[]}