@sapphire/framework
Version:
Discord bot framework built for advanced and amazing bots.
1 lines • 7.38 kB
Source Map (JSON)
{"version":3,"file":"Precondition.mjs","names":[],"sources":["../../../../src/lib/structures/Precondition.ts"],"sourcesContent":["import { Piece } from '@sapphire/pieces';\nimport { Result } from '@sapphire/result';\nimport type { Awaitable } from '@sapphire/utilities';\nimport type {\n\tChannelType,\n\tChatInputCommandInteraction,\n\tCommandInteraction,\n\tContextMenuCommandInteraction,\n\tMessage,\n\tPermissionsBitField,\n\tTextBasedChannel\n} from 'discord.js';\nimport type { CooldownPreconditionContext } from '../../preconditions/Cooldown';\nimport { PreconditionError } from '../errors/PreconditionError';\nimport type { UserError } from '../errors/UserError';\nimport type { ChatInputCommand, ContextMenuCommand, MessageCommand } from '../types/CommandTypes';\n\nexport type PreconditionResult = Awaitable<Result<unknown, UserError>>;\nexport type AsyncPreconditionResult = Promise<Result<unknown, UserError>>;\n\nexport class Precondition<Options extends Precondition.Options = Precondition.Options> extends Piece<Options, 'preconditions'> {\n\tpublic readonly position: number | null;\n\n\tpublic constructor(context: Precondition.LoaderContext, options: Options = {} as Options) {\n\t\tsuper(context, options);\n\t\tthis.position = options.position ?? null;\n\t}\n\n\tpublic messageRun?(message: Message, command: MessageCommand, context: Precondition.Context): Precondition.Result;\n\n\tpublic chatInputRun?(interaction: ChatInputCommandInteraction, command: ChatInputCommand, context: Precondition.Context): Precondition.Result;\n\n\tpublic contextMenuRun?(\n\t\tinteraction: ContextMenuCommandInteraction,\n\t\tcommand: ContextMenuCommand,\n\t\tcontext: Precondition.Context\n\t): Precondition.Result;\n\n\tpublic ok(): Precondition.Result {\n\t\treturn Result.ok();\n\t}\n\n\t/**\n\t * Constructs a {@link PreconditionError} with the precondition parameter set to `this`.\n\t * @param options The information.\n\t */\n\tpublic error(options: Omit<PreconditionError.Options, 'precondition'> = {}): Precondition.Result {\n\t\treturn Result.err(new PreconditionError({ precondition: this, ...options }));\n\t}\n\n\tprotected async fetchChannelFromInteraction(interaction: CommandInteraction): Promise<TextBasedChannel> {\n\t\tconst channel = (await interaction.client.channels.fetch(interaction.channelId, {\n\t\t\tcache: false,\n\t\t\tallowUnknownGuild: true\n\t\t})) as TextBasedChannel;\n\n\t\treturn channel;\n\t}\n}\n\nexport abstract class AllFlowsPrecondition extends Precondition {\n\tpublic abstract override messageRun(message: Message, command: MessageCommand, context: Precondition.Context): Precondition.Result;\n\n\tpublic abstract override chatInputRun(\n\t\tinteraction: ChatInputCommandInteraction,\n\t\tcommand: ChatInputCommand,\n\t\tcontext: Precondition.Context\n\t): Precondition.Result;\n\n\tpublic abstract override contextMenuRun(\n\t\tinteraction: ContextMenuCommandInteraction,\n\t\tcommand: ContextMenuCommand,\n\t\tcontext: Precondition.Context\n\t): Precondition.Result;\n}\n\n/**\n * The registered preconditions and their contexts, if any. When registering new ones, it is recommended to use\n * [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) so\n * custom ones are registered.\n *\n * When a key's value is `never`, it means that it does not take any context, which allows you to pass its identifier as\n * a bare string (e.g. `preconditions: ['NSFW']`), however, if context is required, a non-`never` type should be passed,\n * which will type {@link PreconditionContainerArray#append} and require an object with the name and a `context` with\n * the defined type.\n *\n * @example\n * ```typescript\n * declare module '@sapphire/framework' {\n * interface Preconditions {\n * // A precondition named `Moderator` which does not read `context`:\n * Moderator: never;\n *\n * // A precondition named `ChannelPermissions` which does read `context`:\n * ChannelPermissions: {\n * permissions: Permissions;\n * };\n * }\n * }\n *\n * // [✔] These are valid:\n * preconditions.append('Moderator');\n * preconditions.append({ name: 'Moderator' });\n * preconditions.append({\n * name: 'ChannelPermissions',\n * context: { permissions: new Permissions(8) }\n * });\n *\n * // [X] These are invalid:\n * preconditions.append({ name: 'Moderator', context: {} });\n * // ➡ `never` keys do not accept `context`.\n *\n * preconditions.append('ChannelPermissions');\n * // ➡ non-`never` keys always require `context`, a string cannot be used.\n *\n * preconditions.append({\n * name: 'ChannelPermissions',\n * context: { unknownProperty: 1 }\n * });\n * // ➡ mismatching `context` properties, `{ unknownProperty: number }` is not\n * // assignable to `{ permissions: Permissions }`.\n * ```\n */\nexport interface Preconditions {\n\tCooldown: CooldownPreconditionContext;\n\tDMOnly: never;\n\tEnabled: never;\n\tGuildNewsOnly: never;\n\tGuildNewsThreadOnly: never;\n\tGuildOnly: never;\n\tGuildPrivateThreadOnly: never;\n\tGuildPublicThreadOnly: never;\n\tGuildTextOnly: never;\n\tGuildVoiceOnly: never;\n\tGuildThreadOnly: never;\n\tNSFW: never;\n\tRunIn: {\n\t\ttypes: readonly ChannelType[] | RunInPreconditionCommandSpecificData;\n\t};\n\tClientPermissions: {\n\t\tpermissions: PermissionsBitField;\n\t};\n\tUserPermissions: {\n\t\tpermissions: PermissionsBitField;\n\t};\n}\n\n/**\n * The specific data for the precondition types for the `RunIn` precondition, when the command\n * specified the types for specific command types.\n */\nexport interface RunInPreconditionCommandSpecificData {\n\tmessageRun: readonly ChannelType[];\n\tchatInputRun: readonly ChannelType[];\n\tcontextMenuRun: readonly ChannelType[];\n}\n\nexport type PreconditionKeys = keyof Preconditions;\nexport type SimplePreconditionKeys = {\n\t[K in PreconditionKeys]: Preconditions[K] extends never ? K : never;\n}[PreconditionKeys];\n\nexport interface PreconditionOptions extends Piece.Options {\n\t/**\n\t * The position for the precondition to be set at in the global precondition list. If set to `null`, this\n\t * precondition will not be set as a global one.\n\t * @default null\n\t */\n\tposition?: number | null;\n}\n\nexport interface PreconditionContext extends Record<PropertyKey, unknown> {\n\texternal?: boolean;\n}\n\nexport namespace Precondition {\n\texport type Options = PreconditionOptions;\n\texport type LoaderContext = Piece.LoaderContext<'preconditions'>;\n\texport type Context = PreconditionContext;\n\texport type Result = PreconditionResult;\n\texport type AsyncResult = AsyncPreconditionResult;\n}\n\nexport namespace AllFlowsPrecondition {\n\texport type Options = PreconditionOptions;\n\texport type LoaderContext = Piece.LoaderContext<'preconditions'>;\n\texport type Context = PreconditionContext;\n\texport type Result = PreconditionResult;\n\texport type AsyncResult = AsyncPreconditionResult;\n}\n"],"mappings":";;;;;AAoBA,IAAa,eAAb,cAA+F,MAAgC;CAG9H,AAAO,YAAY,SAAqC,UAAmB,EAAE,EAAa;AACzF,QAAM,SAAS,QAAQ;AACvB,OAAK,WAAW,QAAQ,YAAY;;CAarC,AAAO,KAA0B;AAChC,SAAO,OAAO,IAAI;;;;;;CAOnB,AAAO,MAAM,UAA2D,EAAE,EAAuB;AAChG,SAAO,OAAO,IAAI,IAAI,kBAAkB;GAAE,cAAc;GAAM,GAAG;GAAS,CAAC,CAAC;;CAG7E,MAAgB,4BAA4B,aAA4D;AAMvG,SALiB,MAAM,YAAY,OAAO,SAAS,MAAM,YAAY,WAAW;GAC/E,OAAO;GACP,mBAAmB;GACnB,CAAC;;;AAMJ,IAAsB,uBAAtB,cAAmD,aAAa"}