UNPKG

@sapphire/framework

Version:

Discord bot framework built for advanced and amazing bots.

1,215 lines (1,197 loc) 170 kB
/// <reference types="node" /> import * as discord_js0 from 'discord.js'; import { Snowflake, Message, ChatInputCommandInteraction, ContextMenuCommandInteraction, CommandInteraction, TextBasedChannel, ChannelType, PermissionsBitField, Collection, DMChannel, CategoryChannel, NewsChannel, ThreadChannel, TextChannel, StageChannel, VoiceChannel, GuildMember, Role, User, AutocompleteInteraction, ChatInputApplicationCommandData, UserApplicationCommandData, MessageApplicationCommandData, ApplicationCommandManager, ApplicationCommand as ApplicationCommand$1, PermissionResolvable, PermissionsString, Interaction, ClientEvents, Client, Events as Events$1, ClientOptions, Guild, PartialDMChannel } from 'discord.js'; import { RateLimitManager } from '@sapphire/ratelimits'; import { Piece, AliasPiece, AliasPieceJSON, AliasStore, Store, StoreRegistry, LoaderStrategy } from '@sapphire/pieces'; export { AliasPiece, AliasPieceJSON, AliasPieceOptions, AliasStore, Container, LoaderError, LoaderPieceContext, MissingExportsError, Piece, PieceContext, PieceJSON, PieceLocationJSON, PieceOf, PieceOptions, Store, StoreManagerManuallyRegisteredPiece, StoreManuallyRegisteredPiece, StoreOf, StoreOptions, StoreRegistry, StoreRegistryEntries, StoreRegistryKey, StoreRegistryValue, container } from '@sapphire/pieces'; import { Awaitable, Nullish } from '@sapphire/utilities'; export { Awaitable } from '@sapphire/utilities'; import * as _sapphire_result0 from '@sapphire/result'; import { Result, Option } from '@sapphire/result'; export * from '@sapphire/result'; import { ChannelTypes, GuildBasedChannelTypes, TextBasedChannelTypes, AnyInteraction } from '@sapphire/discord.js-utilities'; import { ArgumentStream, IUnorderedStrategy, Lexer } from '@sapphire/lexure'; import { URL } from 'node:url'; import { SlashCommandBuilder, SlashCommandSubcommandsOnlyBuilder, SlashCommandOptionsOnlyBuilder, ContextMenuCommandBuilder } from '@discordjs/builders'; import { EventEmitter } from 'node:events'; //#region src/lib/errors/UserError.d.ts /** * The UserError class to be emitted in the pieces. * @property name This will be `'UserError'` and can be used to distinguish the type of error when any error gets thrown * @example * ```typescript * throw new UserError({ * identifier: 'AddArgumentError', * message: 'You must write two numbers, but the second one did not match.', * context: { received: 2, expected: 3 } * }); * ``` */ declare class UserError extends Error { /** * An identifier, useful to localize emitted errors. */ readonly identifier: string; /** * User-provided context. */ readonly context: unknown; /** * Constructs an UserError. * @param options The UserError options */ constructor(options: UserError.Options); get name(): string; } declare namespace UserError { /** * The options for {@link UserError}. * @since 1.0.0 */ interface Options { /** * The identifier for this error. * @since 1.0.0 */ identifier: string; /** * The message to be passed to the Error constructor. * @since 1.0.0 */ message?: string; /** * The extra context to provide more information about this error. * @since 1.0.0 * @default null */ context?: unknown; } } //# sourceMappingURL=UserError.d.mts.map //#region src/lib/types/Enums.d.ts declare enum CooldownLevel { Author = "author", Channel = "channel", Guild = "guild", } declare enum PluginHook { PreGenericsInitialization = "preGenericsInitialization", PreInitialization = "preInitialization", PostInitialization = "postInitialization", PreLogin = "preLogin", PostLogin = "postLogin", } /** * The scope the cooldown applies to. */ declare enum BucketScope { /** * Per channel cooldowns. */ Channel = 0, /** * Global cooldowns. */ Global = 1, /** * Per guild cooldowns. */ Guild = 2, /** * Per user cooldowns. */ User = 3, } declare enum RegisterBehavior { Overwrite = "OVERWRITE", LogToConsole = "LOG_TO_CONSOLE", /** * Finds all differences in the commands provided using our internal computation method, and logs them to the console, while applying them. * * @danger This can potentially cause slowdowns when booting up your bot as computing differences on big commands can take a while. * We recommend you use `OVERWRITE` instead in production. */ VerboseOverwrite = "VERBOSE_OVERWRITE", /** * Makes Sapphire handle all command registrations, removals, and updates for you. * * This mode can only be set as the **default** behavior, and cannot be set per-command. * * In this mode: * - any `idHints` set per-command are no longer respected, and can be omitted. * - any `behaviorWhenNotIdentical` that are set per-command are no longer respected, and can be omitted. * - any application commands that are *not* registered through Sapphire's {@link ApplicationCommandRegistry} are removed from the application. * - the same applies for guild commands, but only for guilds that are registered in the registry via `guildIds`. */ BulkOverwrite = "BULK_OVERWRITE", } declare enum InternalRegistryAPIType { ChatInput = 0, ContextMenu = 1, } /** * The allowed values for {@link CommandOptions.runIn} as an enum. * @since 2.0.0 */ declare enum CommandOptionsRunTypeEnum { Dm = "DM", GuildText = "GUILD_TEXT", GuildVoice = "GUILD_VOICE", GuildNews = "GUILD_NEWS", GuildNewsThread = "GUILD_NEWS_THREAD", GuildPublicThread = "GUILD_PUBLIC_THREAD", GuildPrivateThread = "GUILD_PRIVATE_THREAD", GuildAny = "GUILD_ANY", } /** * The available command pre-conditions. * @since 2.0.0 */ declare enum CommandPreConditions { Cooldown = "Cooldown", /** @deprecated Use {@link RunIn} instead. */ DirectMessageOnly = "DMOnly", RunIn = "RunIn", /** @deprecated Use {@link RunIn} instead. */ GuildNewsOnly = "GuildNewsOnly", /** @deprecated Use {@link RunIn} instead. */ GuildNewsThreadOnly = "GuildNewsThreadOnly", /** @deprecated Use {@link RunIn} instead. */ GuildOnly = "GuildOnly", /** @deprecated Use {@link RunIn} instead. */ GuildPrivateThreadOnly = "GuildPrivateThreadOnly", /** @deprecated Use {@link RunIn} instead. */ GuildPublicThreadOnly = "GuildPublicThreadOnly", /** @deprecated Use {@link RunIn} instead. */ GuildTextOnly = "GuildTextOnly", /** @deprecated Use {@link RunIn} instead. */ GuildVoiceOnly = "GuildVoiceOnly", /** @deprecated Use {@link RunIn} instead. */ GuildThreadOnly = "GuildThreadOnly", NotSafeForWork = "NSFW", ClientPermissions = "ClientPermissions", UserPermissions = "UserPermissions", } //# sourceMappingURL=Enums.d.mts.map //#region src/preconditions/Cooldown.d.ts interface CooldownPreconditionContext extends AllFlowsPrecondition.Context { scope?: BucketScope; delay: number; limit?: number; filteredUsers?: Snowflake[]; } declare class CorePrecondition$e extends AllFlowsPrecondition { buckets: WeakMap<Command, RateLimitManager<string>>; messageRun(message: Message, command: Command, context: CooldownPreconditionContext): AllFlowsPrecondition.Result; chatInputRun(interaction: ChatInputCommandInteraction, command: Command, context: CooldownPreconditionContext): AllFlowsPrecondition.Result; contextMenuRun(interaction: ContextMenuCommandInteraction, command: Command, context: CooldownPreconditionContext): AllFlowsPrecondition.Result; private sharedRun; private getIdFromMessage; private getIdFromInteraction; private getManager; } //# sourceMappingURL=Cooldown.d.mts.map //#region src/lib/errors/PreconditionError.d.ts /** * Errors thrown by preconditions * @property name This will be `'PreconditionError'` and can be used to distinguish the type of error when any error gets thrown */ declare class PreconditionError extends UserError { readonly precondition: Precondition; constructor(options: PreconditionError.Options); get name(): string; } declare namespace PreconditionError { /** * The options for {@link PreconditionError}. * @since 1.0.0 */ interface Options extends Omit<UserError.Options, 'identifier'> { /** * The precondition that caused the error. * @since 1.0.0 */ precondition: Precondition; /** * The identifier. * @since 1.0.0 * @default precondition.name */ identifier?: string; } } //# sourceMappingURL=PreconditionError.d.mts.map //#region src/lib/structures/Precondition.d.ts type PreconditionResult = Awaitable<Result<unknown, UserError>>; type AsyncPreconditionResult = Promise<Result<unknown, UserError>>; /** * The registered preconditions and their contexts, if any. When registering new ones, it is recommended to use * [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) so * custom ones are registered. * * When a key's value is `never`, it means that it does not take any context, which allows you to pass its identifier as * a bare string (e.g. `preconditions: ['NSFW']`), however, if context is required, a non-`never` type should be passed, * which will type {@link PreconditionContainerArray#append} and require an object with the name and a `context` with * the defined type. * * @example * ```typescript * declare module '@sapphire/framework' { * interface Preconditions { * // A precondition named `Moderator` which does not read `context`: * Moderator: never; * * // A precondition named `ChannelPermissions` which does read `context`: * ChannelPermissions: { * permissions: Permissions; * }; * } * } * * // [✔] These are valid: * preconditions.append('Moderator'); * preconditions.append({ name: 'Moderator' }); * preconditions.append({ * name: 'ChannelPermissions', * context: { permissions: new Permissions(8) } * }); * * // [X] These are invalid: * preconditions.append({ name: 'Moderator', context: {} }); * // ➡ `never` keys do not accept `context`. * * preconditions.append('ChannelPermissions'); * // ➡ non-`never` keys always require `context`, a string cannot be used. * * preconditions.append({ * name: 'ChannelPermissions', * context: { unknownProperty: 1 } * }); * // ➡ mismatching `context` properties, `{ unknownProperty: number }` is not * // assignable to `{ permissions: Permissions }`. * ``` */ interface Preconditions { Cooldown: CooldownPreconditionContext; DMOnly: never; Enabled: never; GuildNewsOnly: never; GuildNewsThreadOnly: never; GuildOnly: never; GuildPrivateThreadOnly: never; GuildPublicThreadOnly: never; GuildTextOnly: never; GuildVoiceOnly: never; GuildThreadOnly: never; NSFW: never; RunIn: { types: readonly ChannelType[] | RunInPreconditionCommandSpecificData; }; ClientPermissions: { permissions: PermissionsBitField; }; UserPermissions: { permissions: PermissionsBitField; }; } /** * The specific data for the precondition types for the `RunIn` precondition, when the command * specified the types for specific command types. */ interface RunInPreconditionCommandSpecificData { messageRun: readonly ChannelType[]; chatInputRun: readonly ChannelType[]; contextMenuRun: readonly ChannelType[]; } type PreconditionKeys = keyof Preconditions; type SimplePreconditionKeys = { [K in PreconditionKeys]: Preconditions[K] extends never ? K : never }[PreconditionKeys]; interface PreconditionOptions extends Piece.Options { /** * The position for the precondition to be set at in the global precondition list. If set to `null`, this * precondition will not be set as a global one. * @default null */ position?: number | null; } interface PreconditionContext extends Record<PropertyKey, unknown> { external?: boolean; } declare class Precondition<Options extends Precondition.Options = Precondition.Options> extends Piece<Options, 'preconditions'> { readonly position: number | null; constructor(context: Precondition.LoaderContext, options?: Options); messageRun?(message: Message, command: MessageCommand, context: Precondition.Context): Precondition.Result; chatInputRun?(interaction: ChatInputCommandInteraction, command: ChatInputCommand, context: Precondition.Context): Precondition.Result; contextMenuRun?(interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, context: Precondition.Context): Precondition.Result; ok(): Precondition.Result; /** * Constructs a {@link PreconditionError} with the precondition parameter set to `this`. * @param options The information. */ error(options?: Omit<PreconditionError.Options, 'precondition'>): Precondition.Result; protected fetchChannelFromInteraction(interaction: CommandInteraction): Promise<TextBasedChannel>; } declare namespace Precondition { type Options = PreconditionOptions; type LoaderContext = Piece.LoaderContext<'preconditions'>; type Context = PreconditionContext; type Result = PreconditionResult; type AsyncResult = AsyncPreconditionResult; } declare abstract class AllFlowsPrecondition extends Precondition { abstract messageRun(message: Message, command: MessageCommand, context: Precondition.Context): Precondition.Result; abstract chatInputRun(interaction: ChatInputCommandInteraction, command: ChatInputCommand, context: Precondition.Context): Precondition.Result; abstract contextMenuRun(interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, context: Precondition.Context): Precondition.Result; } declare namespace AllFlowsPrecondition { type Options = PreconditionOptions; type LoaderContext = Piece.LoaderContext<'preconditions'>; type Context = PreconditionContext; type Result = PreconditionResult; type AsyncResult = AsyncPreconditionResult; } //# sourceMappingURL=Precondition.d.mts.map //#region src/lib/utils/preconditions/IPreconditionContainer.d.ts /** * Defines the result's value for a PreconditionContainer. * @since 1.0.0 */ type PreconditionContainerResult = Result<unknown, UserError>; /** * Defines the return type of the generic {@link IPreconditionContainer.messageRun}. * @since 1.0.0 */ type PreconditionContainerReturn = Awaitable<PreconditionContainerResult>; /** * Async-only version of {@link PreconditionContainerReturn}, to be used when the run method is async. * @since 1.0.0 */ type AsyncPreconditionContainerReturn = Promise<PreconditionContainerResult>; /** * An abstracted precondition container to be implemented by classes. * @since 1.0.0 */ interface IPreconditionContainer { /** * Runs a precondition container. * @since 1.0.0 * @param message The message that ran this precondition. * @param command The command the message invoked. * @param context The context for the precondition. */ messageRun(message: Message, command: Command, context?: PreconditionContext): PreconditionContainerReturn; /** * Runs a precondition container. * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param context The context for the precondition. */ chatInputRun(interaction: ChatInputCommandInteraction, command: Command, context?: PreconditionContext): PreconditionContainerReturn; /** * Runs a precondition container. * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param context The context for the precondition. */ contextMenuRun(interaction: ContextMenuCommandInteraction, command: Command, context?: PreconditionContext): PreconditionContainerReturn; } //# sourceMappingURL=IPreconditionContainer.d.mts.map //#region src/lib/utils/preconditions/PreconditionContainerSingle.d.ts /** * Defines the simple options for the {@link PreconditionContainerSingle}, where only the name of the precondition can * be defined. * @since 2.0.0 */ interface SimplePreconditionSingleResolvableDetails { /** * The name of the precondition to retrieve from {@link SapphireClient.preconditions}. * @since 2.0.0 */ name: SimplePreconditionKeys; } /** * Defines the detailed options for the {@link PreconditionContainerSingle}, where both the {@link PreconditionContext} and the * name of the precondition can be defined. * @since 1.0.0 */ interface PreconditionSingleResolvableDetails<K extends PreconditionKeys = PreconditionKeys> { /** * The name of the precondition to retrieve from {@link SapphireClient.preconditions}. * @since 1.0.0 */ name: K; /** * The context to be set at {@link PreconditionContainerSingle.context}. * @since 1.0.0 */ context: Preconditions[K]; } /** * Defines the data accepted by {@link PreconditionContainerSingle}'s constructor. * @since 1.0.0 */ type PreconditionSingleResolvable = SimplePreconditionKeys | SimplePreconditionSingleResolvableDetails | PreconditionSingleResolvableDetails; /** * An {@link IPreconditionContainer} which runs a single precondition from {@link SapphireClient.preconditions}. * @since 1.0.0 */ declare class PreconditionContainerSingle implements IPreconditionContainer { /** * The context to be used when calling {@link Precondition.run}. This will always be an empty object (`{}`) when the * container was constructed with a string, otherwise it is a direct reference to the value from * {@link PreconditionSingleResolvableDetails.context}. * @since 1.0.0 */ readonly context: Record<PropertyKey, unknown>; /** * The name of the precondition to run. * @since 1.0.0 */ readonly name: string; constructor(data: PreconditionSingleResolvable); /** * Runs the container. * @since 1.0.0 * @param message The message that ran this precondition. * @param command The command the message invoked. * @param context The context for the message precondition. */ messageRun(message: Message, command: MessageCommand, context?: PreconditionContext): PreconditionResult | _sapphire_result0.Err<UserError, any>; /** * Runs the container. * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param context The context for the chat input command precondition. */ chatInputRun(interaction: ChatInputCommandInteraction, command: ChatInputCommand, context?: PreconditionContext): PreconditionResult | _sapphire_result0.Err<UserError, any>; /** * Runs the container. * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param context The context for the context menu command precondition. */ contextMenuRun(interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, context?: PreconditionContext): PreconditionResult | _sapphire_result0.Err<UserError, any>; } //# sourceMappingURL=PreconditionContainerSingle.d.mts.map //#region src/lib/utils/preconditions/conditions/IPreconditionCondition.d.ts /** * Defines the condition for {@link PreconditionContainerArray}s to run. * @since 1.0.0 */ interface IPreconditionCondition { /** * Runs the containers one by one. * @seealso {@link PreconditionRunMode.Sequential} * @since 1.0.0 * @param message The message that ran this precondition. * @param command The command the message invoked. * @param entries The containers to run. * @param context The context for the precondition. */ messageSequential(message: Message, command: MessageCommand, entries: readonly IPreconditionContainer[], context: PreconditionContext): PreconditionContainerReturn; /** * Runs all the containers using `Promise.all`, then checks the results once all tasks finished running. * @seealso {@link PreconditionRunMode.Parallel} * @since 1.0.0 * @param message The message that ran this precondition. * @param command The command the message invoked. * @param entries The containers to run. * @param context The context for the precondition. */ messageParallel(message: Message, command: MessageCommand, entries: readonly IPreconditionContainer[], context: PreconditionContext): PreconditionContainerReturn; /** * Runs the containers one by one. * @seealso {@link PreconditionRunMode.Sequential} * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param entries The containers to run. * @param context The context for the precondition. */ chatInputSequential(interaction: ChatInputCommandInteraction, command: ChatInputCommand, entries: readonly IPreconditionContainer[], context: PreconditionContext): PreconditionContainerReturn; /** * Runs all the containers using `Promise.all`, then checks the results once all tasks finished running. * @seealso {@link PreconditionRunMode.Parallel} * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param entries The containers to run. * @param context The context for the precondition. */ chatInputParallel(interaction: ChatInputCommandInteraction, command: ChatInputCommand, entries: readonly IPreconditionContainer[], context: PreconditionContext): PreconditionContainerReturn; /** * Runs the containers one by one. * @seealso {@link PreconditionRunMode.Sequential} * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param entries The containers to run. * @param context The context for the precondition. */ contextMenuSequential(interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, entries: readonly IPreconditionContainer[], context: PreconditionContext): PreconditionContainerReturn; /** * Runs all the containers using `Promise.all`, then checks the results once all tasks finished running. * @seealso {@link PreconditionRunMode.Parallel} * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param entries The containers to run. * @param context The context for the precondition. */ contextMenuParallel(interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, entries: readonly IPreconditionContainer[], context: PreconditionContext): PreconditionContainerReturn; } //# sourceMappingURL=IPreconditionCondition.d.mts.map //#region src/lib/utils/preconditions/PreconditionContainerArray.d.ts /** * The run mode for a {@link PreconditionContainerArray}. * @since 1.0.0 */ declare enum PreconditionRunMode { /** * The entries are run sequentially, this is the default behaviour and can be slow when doing long asynchronous * tasks, but is performance savvy. * @since 1.0.0 */ Sequential = 0, /** * All entries are run in parallel using `Promise.all`, then the results are processed after all of them have * completed. * @since 1.0.0 */ Parallel = 1, } /** * The condition for a {@link PreconditionContainerArray}. */ declare enum PreconditionRunCondition { /** * Defines a condition where all the entries must pass. This uses {@link PreconditionConditionAnd}. * @since 1.0.0 */ And = 0, /** * Defines a condition where at least one entry must pass. This uses {@link PreconditionConditionOr}. * @since 1.0.0 */ Or = 1, } /** * Defines the detailed options for the {@link PreconditionContainerArray}, where both the {@link PreconditionRunMode} and the * entries can be defined. * @since 1.0.0 */ interface PreconditionArrayResolvableDetails { /** * The data that will be used to resolve {@link IPreconditionContainer} dependent of this one. * @since 1.0.0 */ entries: readonly PreconditionEntryResolvable[]; /** * The mode the {@link PreconditionContainerArray} will run. * @since 1.0.0 */ mode: PreconditionRunMode; } /** * Defines the data accepted by {@link PreconditionContainerArray}'s constructor. * @since 1.0.0 */ type PreconditionArrayResolvable = readonly PreconditionEntryResolvable[] | PreconditionArrayResolvableDetails; /** * Defines the data accepted for each entry of the array. * @since 1.0.0 * @seealso {@link PreconditionArrayResolvable} * @seealso {@link PreconditionArrayResolvableDetails.entries} */ type PreconditionEntryResolvable = PreconditionSingleResolvable | PreconditionArrayResolvable; /** * An {@link IPreconditionContainer} that defines an array of multiple {@link IPreconditionContainer}s. * * By default, array containers run either of two conditions: AND and OR ({@link PreconditionRunCondition}), the top level * will always default to AND, where the nested one flips the logic (OR, then children arrays are AND, then OR...). * * This allows `['Connect', ['Moderator', ['DJ', 'SongAuthor']]]` to become a thrice-nested precondition container, where: * - Level 1: [Single(Connect), Array] runs AND, both containers must return a successful value. * - Level 2: [Single(Moderator), Array] runs OR, either container must return a successful value. * - Level 3: [Single(DJ), Single(SongAuthor)] runs AND, both containers must return a successful value. * * In other words, it is identical to doing: * ```typescript * Connect && (Moderator || (DJ && SongAuthor)); * ``` * @remark More advanced logic can be accomplished by adding more {@link IPreconditionCondition}s (e.g. other operators), * see {@link PreconditionContainerArray.conditions} for more information. * @since 1.0.0 */ declare class PreconditionContainerArray implements IPreconditionContainer { /** * The mode at which this precondition will run. * @since 1.0.0 */ readonly mode: PreconditionRunMode; /** * The {@link IPreconditionContainer}s the array holds. * @since 1.0.0 */ readonly entries: IPreconditionContainer[]; /** * The {@link PreconditionRunCondition} that defines how entries must be handled. * @since 1.0.0 */ readonly runCondition: PreconditionRunCondition; constructor(data?: PreconditionArrayResolvable, parent?: PreconditionContainerArray | null); /** * Adds a new entry to the array. * @since 1.0.0 * @param entry The value to add to the entries. */ add(entry: IPreconditionContainer): this; append(keyOrEntries: SimplePreconditionSingleResolvableDetails | SimplePreconditionKeys | PreconditionContainerArray): this; append<K extends PreconditionKeys>(entry: PreconditionSingleResolvableDetails<K>): this; /** * Runs the container. * @since 1.0.0 * @param message The message that ran this precondition. * @param command The command the message invoked. * @param context The context for the message command precondition. */ messageRun(message: Message, command: MessageCommand, context?: PreconditionContext): PreconditionContainerReturn; /** * Runs the container. * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param context The context for the chat input precondition. */ chatInputRun(interaction: ChatInputCommandInteraction, command: ChatInputCommand, context?: PreconditionContext): PreconditionContainerReturn; /** * Runs the container. * @since 3.0.0 * @param interaction The interaction that ran this precondition. * @param command The command the interaction invoked. * @param context The context for the context menu precondition. */ contextMenuRun(interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, context?: PreconditionContext): PreconditionContainerReturn; /** * Parses the precondition entry resolvables, and adds them to the entries. * @since 1.0.0 * @param entries The entries to parse. */ protected parse(entries: Iterable<PreconditionEntryResolvable>): this; /** * Retrieves a condition from {@link PreconditionContainerArray.conditions}, assuming existence. * @since 1.0.0 */ protected get condition(): IPreconditionCondition; /** * The preconditions to be run. Extra ones can be added by augmenting {@link PreconditionRunCondition} and then * inserting {@link IPreconditionCondition}s. * @since 1.0.0 * @example * ```typescript * // Adding more kinds of conditions * * // Set the new condition: * PreconditionContainerArray.conditions.set(2, PreconditionConditionRandom); * * // Augment Sapphire to add the new condition, in case of a JavaScript * // project, this can be moved to an `Augments.d.ts` (or any other name) * // file somewhere: * declare module '@sapphire/framework' { * export enum PreconditionRunCondition { * Random = 2 * } * } * ``` */ static readonly conditions: Collection<PreconditionRunCondition, IPreconditionCondition>; } //# sourceMappingURL=PreconditionContainerArray.d.mts.map //#region src/lib/errors/Identifiers.d.ts declare enum Identifiers { ArgsMissing = "argsMissing", ArgsUnavailable = "argsUnavailable", ArgumentBooleanError = "booleanError", ArgumentChannelError = "channelError", ArgumentDateError = "dateError", ArgumentDateTooEarly = "dateTooEarly", ArgumentDateTooFar = "dateTooFar", ArgumentDMChannelError = "dmChannelError", ArgumentEmojiError = "emojiError", ArgumentFloatError = "floatError", ArgumentFloatTooLarge = "floatTooLarge", ArgumentFloatTooSmall = "floatTooSmall", ArgumentGuildError = "guildError", ArgumentGuildCategoryChannelError = "categoryChannelError", ArgumentGuildChannelError = "guildChannelError", ArgumentGuildChannelMissingGuildError = "guildChannelMissingGuildError", ArgumentGuildNewsChannelError = "guildNewsChannelError", ArgumentGuildNewsThreadChannelError = "guildNewsThreadChannelError", ArgumentGuildPrivateThreadChannelError = "guildPrivateThreadChannelError", ArgumentGuildPublicThreadChannelError = "guildPublicThreadChannelError", ArgumentGuildStageVoiceChannelError = "guildStageVoiceChannelError", ArgumentGuildTextChannelError = "guildTextChannelError", ArgumentGuildThreadChannelError = "guildThreadChannelError", ArgumentGuildVoiceChannelError = "guildVoiceChannelError", ArgumentHyperlinkError = "hyperlinkError", ArgumentIntegerError = "integerError", ArgumentIntegerTooLarge = "integerTooLarge", ArgumentIntegerTooSmall = "integerTooSmall", ArgumentMemberError = "memberError", ArgumentMemberMissingGuild = "memberMissingGuild", ArgumentMessageError = "messageError", ArgumentNumberError = "numberError", ArgumentNumberTooLarge = "numberTooLarge", ArgumentNumberTooSmall = "numberTooSmall", ArgumentRoleError = "roleError", ArgumentRoleMissingGuild = "roleMissingGuild", ArgumentStringTooLong = "stringTooLong", ArgumentStringTooShort = "stringTooShort", ArgumentUserError = "userError", ArgumentEnumEmptyError = "enumEmptyError", ArgumentEnumError = "enumError", CommandDisabled = "commandDisabled", PreconditionCooldown = "preconditionCooldown", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionDMOnly = "preconditionDmOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildNewsOnly = "preconditionGuildNewsOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildNewsThreadOnly = "preconditionGuildNewsThreadOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildOnly = "preconditionGuildOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildPrivateThreadOnly = "preconditionGuildPrivateThreadOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildPublicThreadOnly = "preconditionGuildPublicThreadOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildTextOnly = "preconditionGuildTextOnly", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionGuildVoiceOnly = "preconditionGuildVoiceOnly", PreconditionNSFW = "preconditionNsfw", PreconditionClientPermissions = "preconditionClientPermissions", PreconditionClientPermissionsNoClient = "preconditionClientPermissionsNoClient", PreconditionClientPermissionsNoPermissions = "preconditionClientPermissionsNoPermissions", PreconditionRunIn = "preconditionRunIn", PreconditionUserPermissions = "preconditionUserPermissions", PreconditionUserPermissionsNoPermissions = "preconditionUserPermissionsNoPermissions", /** @deprecated Use {@link PreconditionRunIn} instead. */ PreconditionThreadOnly = "preconditionThreadOnly", PreconditionUnavailable = "preconditionUnavailable", PreconditionMissingMessageHandler = "preconditionMissingMessageHandler", PreconditionMissingChatInputHandler = "preconditionMissingChatInputHandler", PreconditionMissingContextMenuHandler = "preconditionMissingContextMenuHandler", } //# sourceMappingURL=Identifiers.d.mts.map //#region src/lib/resolvers/emoji.d.ts declare function resolveEmoji(parameter: string): Result<EmojiObject, Identifiers>; interface EmojiObject { name: string | null; id: string | null; animated?: boolean; } //# sourceMappingURL=emoji.d.mts.map //#region src/lib/parsers/Args.d.ts /** * The argument parser to be used in {@link Command}. */ declare class Args { /** * The original message that triggered the command. */ readonly message: Message; /** * The command that is being run. */ readonly command: MessageCommand; /** * The context of the command being run. */ readonly commandContext: MessageCommand.RunContext; /** * The internal Lexure parser. */ protected readonly parser: ArgumentStream; /** * The states stored in the args. * @see Args#save * @see Args#restore */ private readonly states; constructor(message: Message, command: MessageCommand, parser: ArgumentStream, context: MessageCommand.RunContext); /** * Sets the parser to the first token. */ start(): Args; /** * Retrieves the next parameter and parses it. Advances index on success. * @param type The type of the argument. * @param options The pickResult options. * @example * ```typescript * // !square 5 * const resolver = Args.make((parameter, { argument }) => { * const parsed = Number(parameter); * if (Number.isNaN(parsed)) { * return Args.error({ argument, parameter, identifier: 'ArgumentNumberNaN', message: 'You must write a valid number.' }); * } * * return Args.ok(parsed); * }); * * const a = await args.pickResult(resolver); * if (!a.success) { * throw new UserError({ identifier: 'ArgumentNumberNaN', message: 'You must write a valid number.' }); * } * * await message.channel.send(`The result is: ${a.value ** 2}!`); * // Sends "The result is: 25" * ``` */ pickResult<T>(type: IArgument<T>, options?: ArgOptions): Promise<ResultType<T>>; /** * Retrieves the next parameter and parses it. Advances index on success. * @param type The type of the argument. * @param options The pickResult options. * @example * ```typescript * // !add 1 2 * const a = await args.pickResult('integer'); * if (!a.success) { * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write two numbers, but the first one did not match.' }); * } * * const b = await args.pickResult('integer'); * if (!b.success) { * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write two numbers, but the second one did not match.' }); * } * * await message.channel.send(`The result is: ${a.value + b.value}!`); * // Sends "The result is: 3" * ``` */ pickResult<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ResultType<ArgType[K]>>; /** * Similar to {@link Args.pickResult} but returns the value on success, throwing otherwise. * @param type The type of the argument. * @param options The pick options. * @example * ```typescript * // !square 5 * const resolver = Args.make((parameter, { argument }) => { * const parsed = Number(parameter); * if (Number.isNaN(parsed)) { * return Args.error({ argument, parameter, identifier: 'ArgumentNumberNaN', message: 'You must write a valid number.' }); * } * * return Args.ok(parsed); * }); * * const a = await args.pick(resolver); * * await message.channel.send(`The result is: ${a ** 2}!`); * // Sends "The result is: 25" * ``` */ pick<T>(type: IArgument<T>, options?: ArgOptions): Promise<T>; /** * Similar to {@link Args.pickResult} but returns the value on success, throwing otherwise. * @param type The type of the argument. * @param options The pick options. * @example * ```typescript * // !add 1 2 * const a = await args.pick('integer'); * const b = await args.pick('integer'); * await message.channel.send(`The result is: ${a + b}!`); * // Sends "The result is: 3" * ``` */ pick<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ArgType[K]>; /** * Retrieves all the following arguments. * @param type The type of the argument. * @param options The restResult options. * @example * ```typescript * // !reverse Hello world! * const resolver = Args.make((parameter) => Args.ok(parameter.split('').reverse())); * * const a = await args.restResult(resolver); * if (!a.success) { * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write some text.' }); * } * * await message.channel.send(`The reversed value is... ${a.value}`); * // Sends "The reversed value is... !dlrow olleH" * ``` */ restResult<T>(type: IArgument<T>, options?: ArgOptions): Promise<ResultType<T>>; /** * Retrieves all the following arguments. * @param type The type of the argument. * @param options The restResult options. * @example * ```typescript * // !add 2 Hello World! * const a = await args.pickResult('integer'); * if (!a.success) { * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write a number and a text, but the former did not match.' }); * } * * const b = await args.restResult('string', { minimum: 1 }); * if (!b.success) { * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write a number and a text, but the latter did not match.' }); * } * * await message.channel.send(`The repeated value is... ${b.value.repeat(a.value)}!`); * // Sends "The repeated value is... Hello World!Hello World!" * ``` */ restResult<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ResultType<ArgType[K]>>; /** * Similar to {@link Args.restResult} but returns the value on success, throwing otherwise. * @param type The type of the argument. * @param options The rest options. * @example * ```typescript * // !reverse Hello world! * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse())); * const a = await args.rest(resolver); * await message.channel.send(`The reversed value is... ${a}`); * // Sends "The reversed value is... !dlrow olleH" * ``` */ rest<T>(type: IArgument<T>, options?: ArgOptions): Promise<T>; /** * Similar to {@link Args.restResult} but returns the value on success, throwing otherwise. * @param type The type of the argument. * @param options The rest options. * @example * ```typescript * // !add 2 Hello World! * const a = await args.pick('integer'); * const b = await args.rest('string', { minimum: 1 }); * await message.channel.send(`The repeated value is... ${b.repeat(a)}!`); * // Sends "The repeated value is... Hello World!Hello World!" * ``` */ rest<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ArgType[K]>; /** * Retrieves all the following arguments. * @param type The type of the argument. * @param options The repeatResult options. * @example * ```typescript * // !add 2 Hello World! * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse())); * const result = await args.repeatResult(resolver, { times: 5 }); * if (!result.success) { * throw new UserError({ identifier: 'CountArgumentError', message: 'You must write up to 5 words.' }); * } * * await message.channel.send(`You have written ${result.value.length} word(s): ${result.value.join(' ')}`); * // Sends "You have written 2 word(s): olleH !dlroW" * ``` */ repeatResult<T>(type: IArgument<T>, options?: RepeatArgOptions): Promise<ArrayResultType<T>>; /** * Retrieves all the following arguments. * @param type The type of the argument. * @param options The repeatResult options. * @example * ```typescript * // !reverse-each 2 Hello World! * const result = await args.repeatResult('string', { times: 5 }); * if (!result.success) { * throw new UserError({ identifier: 'CountArgumentError', message: 'You must write up to 5 words.' }); * } * * await message.channel.send(`You have written ${result.value.length} word(s): ${result.value.join(' ')}`); * // Sends "You have written 2 word(s): Hello World!" * ``` */ repeatResult<K extends keyof ArgType>(type: K, options?: RepeatArgOptions): Promise<ArrayResultType<ArgType[K]>>; /** * Similar to {@link Args.repeatResult} but returns the value on success, throwing otherwise. * @param type The type of the argument. * @param options The repeat options. * @example * ```typescript * // !reverse-each 2 Hello World! * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse())); * const result = await args.repeat(resolver, { times: 5 }); * await message.channel.send(`You have written ${result.length} word(s): ${result.join(' ')}`); * // Sends "You have written 2 word(s): Hello World!" * ``` */ repeat<T>(type: IArgument<T>, options?: RepeatArgOptions): Promise<T[]>; /** * Similar to {@link Args.repeatResult} but returns the value on success, throwing otherwise. * @param type The type of the argument. * @param options The repeat options. * @example * ```typescript * // !add 2 Hello World! * const words = await args.repeat('string', { times: 5 }); * await message.channel.send(`You have written ${words.length} word(s): ${words.join(' ')}`); * // Sends "You have written 2 word(s): Hello World!" * ``` */ repeat<K extends keyof ArgType>(type: K, options?: RepeatArgOptions): Promise<ArgType[K][]>; /** * Peeks the following parameter(s) without advancing the parser's state. * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult}, * or {@link Args.restResult}; otherwise, passing the custom argument or the argument type with options * will use {@link Args.pickResult} and only peek a single argument. * @param type The function, custom argument, or argument name. * @example * ```typescript * // !reversedandscreamfirst hello world * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse().join(''))); * * const result = await args.repeatResult(resolver); * await result.inspectAsync((value) => * message.channel.send(`Reversed ${value.length} word(s): ${value.join(' ')}`) * ); // Reversed 2 word(s): olleh dlrow * * const firstWord = await args.pickResult('string'); * await firstWord.inspectAsync((value) => * message.channel.send(firstWord.value.toUpperCase()) * ); // HELLO * ``` */ peekResult<T>(type: () => Argument.Result<T>): Promise<ResultType<T>>; /** * Peeks the following parameter(s) without advancing the parser's state. * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult}, * or {@link Args.restResult}; otherwise, passing the custom argument or the argument type with options * will use {@link Args.pickResult} and only peek a single argument. * @param type The function, custom argument, or argument name. * @param options The peekResult options. * @example * ```typescript * // !reverseandscreamfirst sapphire community * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse().join(''))); * * const peekedWord = await args.peekResult(resolver); * await peekedWord.inspectAsync((value) => message.channel.send(value)); // erihppas * * const firstWord = await args.pickResult('string'); * await firstWord.inspectAsync((value) => message.channel.send(value.toUpperCase())); // SAPPHIRE * ``` */ peekResult<T>(type: IArgument<T>, options?: ArgOptions): Promise<ResultType<T>>; /** * Peeks the following parameter(s) without advancing the parser's state. * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult}, * or {@link Args.restResult}; otherwise, passing the custom argument or the argument type with options * will use {@link Args.pickResult} and only peek a single argument. * @param type The function, custom argument, or argument name. * @param options The peekResult options. * @example * ```typescript * // !datethenaddtwo 1608867472611 * const date = await args.peekResult('date'); * await date.inspectAsync((value) => * message.channel.send(`Your date (in UTC): ${value.toUTCString()}`) * ); // Your date (in UTC): Fri, 25 Dec 2020 03:37:52 GMT * * const result = await args.pickResult('number', { maximum: Number.MAX_SAFE_INTEGER - 2 }); * await result.inspectAsync((value) => * message.channel.send(`Your number plus two: ${value + 2}`) * ); // Your number plus two: 1608867472613 * ``` */ peekResult<K extends keyof ArgType>(type: (() => Awaitable<Argument.Result<ArgType[K]>>) | K, options?: ArgOptions): Promise<ResultType<ArgType[K]>>; /** * Similar to {@link Args.peekResult} but returns the value on success, throwing otherwise. * @param type The function, custom argument, or argument name. * @example * ```typescript * // !bigintsumthensquarefirst 25 50 75 * const resolver = Args.make((arg, { argument }) => { * try { * return Args.ok(BigInt(arg)); * } catch { * return Args.error({ parameter: arg, argument, identifier: 'InvalidBigInt', message: 'You must specify a valid number for a bigint.' }) * } * }); * * const peeked = await args.repeatResult(resolver); * await peeked.inspectAsync((value) => message.channel.send(`Sum: **${value.reduce((x, y) => x + y, 0n)}**`)); // Sum: 150n * * const first = await args.pick(resolver); * await message.channel.send(`First bigint squared: ${first**2n}`); // First bigint squared: 625 * ``` */ peek<T>(type: () => Argument.Result<T>): Promise<T>; /** * Similar to {@link Args.peekResult} but returns the value on success, throwing otherwise. * @param type The function, custom argument, or argument name. * @param options The peek options. * @example * ```typescript * import { SnowflakeRegex } from '@sapphire/discord.js-utilities'; * import { DiscordSnowflake } from '@sapphire/snowflake'; * * // !createdat 730159185517477900 * const snowflakeResolver = Args.make<bigint>((arg, { argument }) => { * return SnowflakeRegex.test(arg) * ? Args.ok(BigInt(arg)) * : Args.error({ parameter: arg, argument, identifier: 'InvalidSnowflake', message: 'You must specify a valid snowflake.' }); * }); * * const snowflake = await args.peek(snowflakeResolver); * const timestamp = Number((snowflake >> 22n) + DiscordSnowflake.epoch); * const createdAt = new Date(timestamp); * * await message.channel.send( * `The snowflake ${snowflake} was registered on ${createdAt.toUTCString()}.` * ); // The snowflake 730159185517477900 was registered on Tue, 07 Jul 2020 20:31:55 GMT. * * const id = await args.pick('string'); * await message.channel.send(`Your ID, reversed: ${id.split('').reverse().join('')}`); // Your ID, reversed: 009774715581951037 * ``` */ peek<T>(type: IArgument<T>, options?: ArgOptions): Promise<T>; /** * Similar to {@link Args.peekResult} but returns the value on success, throwing otherwise. * @param type The function, custom argument, or argument name. * @param options The peek options. * @example * ```typescript * // !messagelink https://discord.com/channels/737141877803057244/737142209639350343/791843123898089483 * const remoteMessage = await args.peek('message'); * await message.channel.send( * `${remoteMessage.author.tag}: ${remoteMessage.content}` * ); // RealShadowNova#7462: Yeah, Sapphire has been a great experience so far, especially being able to help and contribute. * * const url = await args.pick('hyperlink'); * await message.channel.send(`Hostname: ${url.hostname}`); // Hostname: discord.com * ``` */ peek<K extends keyof ArgType>(type: (() => Argument.Result<ArgType[K]>) | K, options?: ArgOptions): Promise<ArgType[K]>; /** * Retrieves the next raw argument from the parser. * @example * ```typescript * // !numbers 1 2 3 * * console.log(args.nextMaybe()); * // -> { exists: true, value: '1' } * ``` */ nextMaybe(): Option<string>; /** * Retrieves the value of the next unused ordered token, but only if it could be transformed. * That token will now be used if the transformation succeeds. * @typeparam T Output type of the {@link ArgsNextCallback callback}. * @param cb Gives an option of either the resulting value, or nothing if failed. * @example * ```typescript * // !numbers 1 2 3 * const parse = (x: strin