index.js.map
62.8 KB
{"version":3,"sources":["../src/index.ts","../src/messages/embed/Assertions.ts","../src/messages/embed/Embed.ts","../src/messages/formatters.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/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"],"sourcesContent":["export * as EmbedAssertions from './messages/embed/Assertions';\nexport * from './messages/embed/Embed';\nexport * from './messages/formatters';\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/string';\nexport * from './interactions/slashCommands/options/user';\n\nexport * as ContextMenuCommandAssertions from './interactions/contextMenuCommands/Assertions';\nexport * from './interactions/contextMenuCommands/ContextMenuCommandBuilder';\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(fields: APIEmbedField[], amountAdding: number): void {\n\tfieldLengthPredicate.parse(fields.length + amountAdding);\n}\n\nexport const authorNamePredicate = fieldNamePredicate.nullable();\n\nexport const urlPredicate = z.string().url().nullish();\n\nexport const colorPredicate = z.number().gte(0).lte(0xffffff).nullable();\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\tAPIEmbedProvider,\n\tAPIEmbedThumbnail,\n\tAPIEmbedVideo,\n} from 'discord-api-types/v9';\nimport {\n\tauthorNamePredicate,\n\tcolorPredicate,\n\tdescriptionPredicate,\n\tembedFieldsArrayPredicate,\n\tfieldInlinePredicate,\n\tfieldNamePredicate,\n\tfieldValuePredicate,\n\tfooterTextPredicate,\n\ttimestampPredicate,\n\ttitlePredicate,\n\turlPredicate,\n\tvalidateFieldLength,\n} from './Assertions';\n\nexport interface AuthorOptions {\n\tname: string;\n\turl?: string;\n\ticonURL?: string;\n}\n\nexport interface FooterOptions {\n\ttext: string;\n\ticonURL?: string;\n}\n\n/**\n * Represents an embed in a message (image/video preview, rich embed, etc.)\n */\nexport class Embed implements APIEmbed {\n\t/**\n\t * An array of fields of this embed\n\t */\n\tpublic fields: APIEmbedField[];\n\n\t/**\n\t * The embed title\n\t */\n\tpublic title?: string;\n\n\t/**\n\t * The embed description\n\t */\n\tpublic description?: string;\n\n\t/**\n\t * The embed url\n\t */\n\tpublic url?: string;\n\n\t/**\n\t * The embed color\n\t */\n\tpublic color?: number;\n\n\t/**\n\t * The timestamp of the embed in the ISO format\n\t */\n\tpublic timestamp?: string;\n\n\t/**\n\t * The embed thumbnail data\n\t */\n\tpublic thumbnail?: APIEmbedThumbnail;\n\n\t/**\n\t * The embed image data\n\t */\n\tpublic image?: APIEmbedImage;\n\n\t/**\n\t * Received video data\n\t */\n\tpublic video?: APIEmbedVideo;\n\n\t/**\n\t * The embed author data\n\t */\n\tpublic author?: APIEmbedAuthor;\n\n\t/**\n\t * Received data about the embed provider\n\t */\n\tpublic provider?: APIEmbedProvider;\n\n\t/**\n\t * The embed footer data\n\t */\n\tpublic footer?: APIEmbedFooter;\n\n\tpublic constructor(data: APIEmbed = {}) {\n\t\tthis.title = data.title;\n\t\tthis.description = data.description;\n\t\tthis.url = data.url;\n\t\tthis.color = data.color;\n\t\tthis.thumbnail = data.thumbnail;\n\t\tthis.image = data.image;\n\t\tthis.video = data.video;\n\t\tthis.author = data.author;\n\t\tthis.provider = data.provider;\n\t\tthis.footer = data.footer;\n\t\tthis.fields = data.fields ?? [];\n\n\t\tif (data.timestamp) this.timestamp = new Date(data.timestamp).toISOString();\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.title?.length ?? 0) +\n\t\t\t(this.description?.length ?? 0) +\n\t\t\tthis.fields.reduce((prev, curr) => prev + curr.name.length + curr.value.length, 0) +\n\t\t\t(this.footer?.text.length ?? 0) +\n\t\t\t(this.author?.name.length ?? 0)\n\t\t);\n\t}\n\n\t/**\n\t * Adds a field to the embed (max 25)\n\t *\n\t * @param field The field to add.\n\t */\n\tpublic addField(field: APIEmbedField): this {\n\t\treturn this.addFields(field);\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\t// Data assertions\n\t\tembedFieldsArrayPredicate.parse(fields);\n\n\t\t// Ensure adding these fields won't exceed the 25 field limit\n\t\tvalidateFieldLength(this.fields, fields.length);\n\n\t\tthis.fields.push(...Embed.normalizeFields(...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\t// Data assertions\n\t\tembedFieldsArrayPredicate.parse(fields);\n\n\t\t// Ensure adding these fields won't exceed the 25 field limit\n\t\tvalidateFieldLength(this.fields, fields.length - deleteCount);\n\n\t\tthis.fields.splice(index, deleteCount, ...Embed.normalizeFields(...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: AuthorOptions | null): this {\n\t\tif (options === null) {\n\t\t\tthis.author = undefined;\n\t\t\treturn this;\n\t\t}\n\n\t\tconst { name, iconURL, url } = options;\n\t\t// Data assertions\n\t\tauthorNamePredicate.parse(name);\n\t\turlPredicate.parse(iconURL);\n\t\turlPredicate.parse(url);\n\n\t\tthis.author = { name, url, icon_url: 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 | null): this {\n\t\t// Data assertions\n\t\tcolorPredicate.parse(color);\n\n\t\tthis.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\t// Data assertions\n\t\tdescriptionPredicate.parse(description);\n\n\t\tthis.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: FooterOptions | null): this {\n\t\tif (options === null) {\n\t\t\tthis.footer = undefined;\n\t\t\treturn this;\n\t\t}\n\n\t\tconst { text, iconURL } = options;\n\t\t// Data assertions\n\t\tfooterTextPredicate.parse(text);\n\t\turlPredicate.parse(iconURL);\n\n\t\tthis.footer = { text, icon_url: 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\t// Data assertions\n\t\turlPredicate.parse(url);\n\n\t\tthis.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\t// Data assertions\n\t\turlPredicate.parse(url);\n\n\t\tthis.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\t// Data assertions\n\t\ttimestampPredicate.parse(timestamp);\n\n\t\tthis.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\t// Data assertions\n\t\ttitlePredicate.parse(title);\n\n\t\tthis.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\t// Data assertions\n\t\turlPredicate.parse(url);\n\n\t\tthis.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 };\n\t}\n\n\t/**\n\t * Normalizes field input and resolves strings\n\t *\n\t * @param fields Fields to normalize\n\t */\n\tpublic static normalizeFields(...fields: APIEmbedField[]): APIEmbedField[] {\n\t\treturn fields.flat(Infinity).map((field) => {\n\t\t\tfieldNamePredicate.parse(field.name);\n\t\t\tfieldValuePredicate.parse(field.value);\n\t\t\tfieldInlinePredicate.parse(field.inline);\n\n\t\t\treturn { name: field.name, value: field.value, inline: field.inline ?? undefined };\n\t\t});\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 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\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 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 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 maxArrayLengthPredicate = z.unknown().array().max(25);\n\nexport function validateMaxOptionsLength(options: unknown): asserts options is ToAPIApplicationCommandOptions[] {\n\tmaxArrayLengthPredicate.parse(options);\n}\n\nexport function validateMaxChoicesLength(choices: APIApplicationCommandOptionChoice[]) {\n\tmaxArrayLengthPredicate.parse(choices);\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) {\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 = 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 channelTypePredicate = z.union(\n\tallowedChannelTypes.map((type) => z.literal(type)) as [\n\t\tZodLiteral<ChannelType>,\n\t\tZodLiteral<ChannelType>,\n\t\t...ZodLiteral<ChannelType>[]\n\t],\n);\n\nexport class ApplicationCommandOptionChannelTypesMixin {\n\tpublic readonly channel_types?: ApplicationCommandOptionAllowedChannelTypes[];\n\n\t/**\n\t * Adds a channel type to this option\n\t *\n\t * @param channelType The type of channel to allow\n\t */\n\tpublic addChannelType(channelType: ApplicationCommandOptionAllowedChannelTypes) {\n\t\tif (this.channel_types === undefined) {\n\t\t\tReflect.set(this, 'channel_types', []);\n\t\t}\n\n\t\tchannelTypePredicate.parse(channelType);\n\t\tthis.channel_types!.push(channelType);\n\n\t\treturn this;\n\t}\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\tchannelTypes.forEach((channelType) => this.addChannelType(channelType));\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().nonnegative();\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, 'maxValue', 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, 'minValue', 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\tprotected readonly maxValue?: number;\n\tprotected readonly minValue?: 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 { validateMaxChoicesLength } from '../Assertions';\n\nconst stringPredicate = z.string().min(1).max(100);\nconst numberPredicate = z.number().gt(-Infinity).lt(Infinity);\nconst choicesPredicate = z.tuple([stringPredicate, z.union([stringPredicate, numberPredicate])]).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 a choice for this option\n\t *\n\t * @param name The name of the choice\n\t * @param value The value of the choice\n\t */\n\tpublic addChoice(name: string, value: T): Omit<this, 'setAutocomplete'> {\n\t\tif (this.autocomplete) {\n\t\t\tthrow new RangeError('Autocomplete and choices are mutually exclusive to each other.');\n\t\t}\n\n\t\tif (this.choices === undefined) {\n\t\t\tReflect.set(this, 'choices', []);\n\t\t}\n\n\t\tvalidateMaxChoicesLength(this.choices!);\n\n\t\t// Validate name\n\t\tstringPredicate.parse(name);\n\n\t\t// Validate the value\n\t\tif (this.type === ApplicationCommandOptionType.String) {\n\t\t\tstringPredicate.parse(value);\n\t\t} else {\n\t\t\tnumberPredicate.parse(value);\n\t\t}\n\n\t\tthis.choices!.push({ name, value });\n\n\t\treturn this;\n\t}\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: [name: string, value: T][]): Omit<this, 'setAutocomplete'> {\n\t\tif (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\tfor (const [label, value] of choices) this.addChoice(label, value);\n\t\treturn this;\n\t}\n\n\tpublic setChoices<Input extends [name: string, value: T][]>(\n\t\tchoices: Input,\n\t): Input extends []\n\t\t? this & Pick<ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T>, 'setAutocomplete'>\n\t\t: Omit<this, 'setAutocomplete'> {\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\tfor (const [label, value] of choices) this.addChoice(label, value);\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<U extends boolean>(\n\t\tautocomplete: U,\n\t): U extends true\n\t\t? Omit<this, 'addChoice' | 'addChoices'>\n\t\t: this & Pick<ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T>, 'addChoice' | 'addChoices'> {\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().nonnegative();\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, 'maxValue', 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, 'minValue', 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 { 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 { 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 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, 'addChoice' | '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, 'addChoice' | '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, 'addChoice' | '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, 'addChoice' | '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, 'addChoice' | '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, 'addChoice' | '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, 'addChoice' | 'addChoices'>\n\t\t\t| ((builder: T) => T | Omit<T, 'setAutocomplete'> | Omit<T, 'addChoice' | '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/slash-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\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\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/slash-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\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\nconst namePredicate = z\n\t.string()\n\t.min(1)\n\t.max(32)\n\t.regex(/^( *[\\p{L}\\p{N}_-]+ *)+$/u);\n\nexport function validateName(name: unknown): asserts name is string {\n\tnamePredicate.parse(name);\n}\n\nconst typePredicate = z.union([z.literal(ApplicationCommandType.User), z.literal(ApplicationCommandType.Message)]);\n\nexport function validateType(type: unknown): asserts type is ContextMenuCommandType {\n\ttypePredicate.parse(type);\n}\n\nconst booleanPredicate = z.boolean();\n\nexport function validateDefaultPermission(value: unknown): asserts value is boolean {\n\tbooleanPredicate.parse(value);\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"],"mappings":"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","names":[]}