UNPKG

@sapphire/framework

Version:

Discord bot framework built for advanced and amazing bots.

1 lines • 11.5 kB
{"version":3,"file":"PreconditionContainerArray.cjs","names":["PreconditionContainerSingle","Collection","PreconditionConditionAnd","PreconditionConditionOr"],"sources":["../../../../../src/lib/utils/preconditions/PreconditionContainerArray.ts"],"sourcesContent":["import { Collection, type ChatInputCommandInteraction, type ContextMenuCommandInteraction, type Message } from 'discord.js';\nimport type { PreconditionContext, PreconditionKeys, SimplePreconditionKeys } from '../../structures/Precondition';\nimport type { ChatInputCommand, ContextMenuCommand, MessageCommand } from '../../types/CommandTypes';\nimport type { IPreconditionContainer, PreconditionContainerReturn } from './IPreconditionContainer';\nimport {\n\tPreconditionContainerSingle,\n\ttype PreconditionSingleResolvable,\n\ttype PreconditionSingleResolvableDetails,\n\ttype SimplePreconditionSingleResolvableDetails\n} from './PreconditionContainerSingle';\nimport type { IPreconditionCondition } from './conditions/IPreconditionCondition';\nimport { PreconditionConditionAnd } from './conditions/PreconditionConditionAnd';\nimport { PreconditionConditionOr } from './conditions/PreconditionConditionOr';\n\n/**\n * The run mode for a {@link PreconditionContainerArray}.\n * @since 1.0.0\n */\nexport enum PreconditionRunMode {\n\t/**\n\t * The entries are run sequentially, this is the default behaviour and can be slow when doing long asynchronous\n\t * tasks, but is performance savvy.\n\t * @since 1.0.0\n\t */\n\tSequential,\n\n\t/**\n\t * All entries are run in parallel using `Promise.all`, then the results are processed after all of them have\n\t * completed.\n\t * @since 1.0.0\n\t */\n\tParallel\n}\n\n/**\n * The condition for a {@link PreconditionContainerArray}.\n */\nexport enum PreconditionRunCondition {\n\t/**\n\t * Defines a condition where all the entries must pass. This uses {@link PreconditionConditionAnd}.\n\t * @since 1.0.0\n\t */\n\tAnd,\n\n\t/**\n\t * Defines a condition where at least one entry must pass. This uses {@link PreconditionConditionOr}.\n\t * @since 1.0.0\n\t */\n\tOr\n}\n\n/**\n * Defines the detailed options for the {@link PreconditionContainerArray}, where both the {@link PreconditionRunMode} and the\n * entries can be defined.\n * @since 1.0.0\n */\nexport interface PreconditionArrayResolvableDetails {\n\t/**\n\t * The data that will be used to resolve {@link IPreconditionContainer} dependent of this one.\n\t * @since 1.0.0\n\t */\n\tentries: readonly PreconditionEntryResolvable[];\n\n\t/**\n\t * The mode the {@link PreconditionContainerArray} will run.\n\t * @since 1.0.0\n\t */\n\tmode: PreconditionRunMode;\n}\n\n/**\n * Defines the data accepted by {@link PreconditionContainerArray}'s constructor.\n * @since 1.0.0\n */\nexport type PreconditionArrayResolvable = readonly PreconditionEntryResolvable[] | PreconditionArrayResolvableDetails;\n\n/**\n * Defines the data accepted for each entry of the array.\n * @since 1.0.0\n * @seealso {@link PreconditionArrayResolvable}\n * @seealso {@link PreconditionArrayResolvableDetails.entries}\n */\nexport type PreconditionEntryResolvable = PreconditionSingleResolvable | PreconditionArrayResolvable;\n\nfunction isSingle(entry: PreconditionEntryResolvable): entry is PreconditionSingleResolvable {\n\treturn typeof entry === 'string' || Reflect.has(entry, 'name');\n}\n\n/**\n * An {@link IPreconditionContainer} that defines an array of multiple {@link IPreconditionContainer}s.\n *\n * By default, array containers run either of two conditions: AND and OR ({@link PreconditionRunCondition}), the top level\n * will always default to AND, where the nested one flips the logic (OR, then children arrays are AND, then OR...).\n *\n * This allows `['Connect', ['Moderator', ['DJ', 'SongAuthor']]]` to become a thrice-nested precondition container, where:\n * - Level 1: [Single(Connect), Array] runs AND, both containers must return a successful value.\n * - Level 2: [Single(Moderator), Array] runs OR, either container must return a successful value.\n * - Level 3: [Single(DJ), Single(SongAuthor)] runs AND, both containers must return a successful value.\n *\n * In other words, it is identical to doing:\n * ```typescript\n * Connect && (Moderator || (DJ && SongAuthor));\n * ```\n * @remark More advanced logic can be accomplished by adding more {@link IPreconditionCondition}s (e.g. other operators),\n * see {@link PreconditionContainerArray.conditions} for more information.\n * @since 1.0.0\n */\nexport class PreconditionContainerArray implements IPreconditionContainer {\n\t/**\n\t * The mode at which this precondition will run.\n\t * @since 1.0.0\n\t */\n\tpublic readonly mode: PreconditionRunMode;\n\n\t/**\n\t * The {@link IPreconditionContainer}s the array holds.\n\t * @since 1.0.0\n\t */\n\tpublic readonly entries: IPreconditionContainer[];\n\n\t/**\n\t * The {@link PreconditionRunCondition} that defines how entries must be handled.\n\t * @since 1.0.0\n\t */\n\tpublic readonly runCondition: PreconditionRunCondition;\n\n\tpublic constructor(data: PreconditionArrayResolvable = [], parent: PreconditionContainerArray | null = null) {\n\t\tthis.entries = [];\n\t\tthis.runCondition = parent?.runCondition === PreconditionRunCondition.And ? PreconditionRunCondition.Or : PreconditionRunCondition.And;\n\n\t\tif (Array.isArray(data)) {\n\t\t\tconst casted = data as readonly PreconditionEntryResolvable[];\n\n\t\t\tthis.mode = parent?.mode ?? PreconditionRunMode.Sequential;\n\t\t\tthis.parse(casted);\n\t\t} else {\n\t\t\tconst casted = data as PreconditionArrayResolvableDetails;\n\n\t\t\tthis.mode = casted.mode;\n\t\t\tthis.parse(casted.entries);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a new entry to the array.\n\t * @since 1.0.0\n\t * @param entry The value to add to the entries.\n\t */\n\tpublic add(entry: IPreconditionContainer): this {\n\t\tthis.entries.push(entry);\n\t\treturn this;\n\t}\n\n\tpublic append(keyOrEntries: SimplePreconditionSingleResolvableDetails | SimplePreconditionKeys | PreconditionContainerArray): this;\n\tpublic append<K extends PreconditionKeys>(entry: PreconditionSingleResolvableDetails<K>): this;\n\tpublic append(entry: PreconditionContainerArray | PreconditionSingleResolvable): this {\n\t\tthis.entries.push(entry instanceof PreconditionContainerArray ? entry : new PreconditionContainerSingle(entry));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Runs the container.\n\t * @since 1.0.0\n\t * @param message The message that ran this precondition.\n\t * @param command The command the message invoked.\n\t * @param context The context for the message command precondition.\n\t */\n\tpublic messageRun(message: Message, command: MessageCommand, context: PreconditionContext = {}): PreconditionContainerReturn {\n\t\treturn this.mode === PreconditionRunMode.Sequential\n\t\t\t? this.condition.messageSequential(message, command, this.entries, context)\n\t\t\t: this.condition.messageParallel(message, command, this.entries, context);\n\t}\n\n\t/**\n\t * Runs the container.\n\t * @since 3.0.0\n\t * @param interaction The interaction that ran this precondition.\n\t * @param command The command the interaction invoked.\n\t * @param context The context for the chat input precondition.\n\t */\n\tpublic chatInputRun(\n\t\tinteraction: ChatInputCommandInteraction,\n\t\tcommand: ChatInputCommand,\n\t\tcontext: PreconditionContext = {}\n\t): PreconditionContainerReturn {\n\t\treturn this.mode === PreconditionRunMode.Sequential\n\t\t\t? this.condition.chatInputSequential(interaction, command, this.entries, context)\n\t\t\t: this.condition.chatInputParallel(interaction, command, this.entries, context);\n\t}\n\n\t/**\n\t * Runs the container.\n\t * @since 3.0.0\n\t * @param interaction The interaction that ran this precondition.\n\t * @param command The command the interaction invoked.\n\t * @param context The context for the context menu precondition.\n\t */\n\tpublic contextMenuRun(\n\t\tinteraction: ContextMenuCommandInteraction,\n\t\tcommand: ContextMenuCommand,\n\t\tcontext: PreconditionContext = {}\n\t): PreconditionContainerReturn {\n\t\treturn this.mode === PreconditionRunMode.Sequential\n\t\t\t? this.condition.contextMenuSequential(interaction, command, this.entries, context)\n\t\t\t: this.condition.contextMenuParallel(interaction, command, this.entries, context);\n\t}\n\n\t/**\n\t * Parses the precondition entry resolvables, and adds them to the entries.\n\t * @since 1.0.0\n\t * @param entries The entries to parse.\n\t */\n\tprotected parse(entries: Iterable<PreconditionEntryResolvable>): this {\n\t\tfor (const entry of entries) {\n\t\t\tthis.add(\n\t\t\t\tisSingle(entry) //\n\t\t\t\t\t? new PreconditionContainerSingle(entry)\n\t\t\t\t\t: new PreconditionContainerArray(entry, this)\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Retrieves a condition from {@link PreconditionContainerArray.conditions}, assuming existence.\n\t * @since 1.0.0\n\t */\n\tprotected get condition(): IPreconditionCondition {\n\t\treturn PreconditionContainerArray.conditions.get(this.runCondition)!;\n\t}\n\n\t/**\n\t * The preconditions to be run. Extra ones can be added by augmenting {@link PreconditionRunCondition} and then\n\t * inserting {@link IPreconditionCondition}s.\n\t * @since 1.0.0\n\t * @example\n\t * ```typescript\n\t * // Adding more kinds of conditions\n\t *\n\t * // Set the new condition:\n\t * PreconditionContainerArray.conditions.set(2, PreconditionConditionRandom);\n\t *\n\t * // Augment Sapphire to add the new condition, in case of a JavaScript\n\t * // project, this can be moved to an `Augments.d.ts` (or any other name)\n\t * // file somewhere:\n\t * declare module '@sapphire/framework' {\n\t * export enum PreconditionRunCondition {\n\t * Random = 2\n\t * }\n\t * }\n\t * ```\n\t */\n\tpublic static readonly conditions = new Collection<PreconditionRunCondition, IPreconditionCondition>([\n\t\t[PreconditionRunCondition.And, PreconditionConditionAnd],\n\t\t[PreconditionRunCondition.Or, PreconditionConditionOr]\n\t]);\n}\n"],"mappings":";;;;;;;;;;;AAkBA,IAAY,sEAAL;;;;;;AAMN;;;;;;AAOA;;;;;;AAMD,IAAY,gFAAL;;;;;AAKN;;;;;AAMA;;;AAoCD,SAAS,SAAS,OAA2E;AAC5F,QAAO,OAAO,UAAU,YAAY,QAAQ,IAAI,OAAO,OAAO;;;;;;;;;;;;;;;;;;;;;AAsB/D,IAAa,6BAAb,MAAa,2BAA6D;CAmBzE,AAAO,YAAY,OAAoC,EAAE,EAAE,SAA4C,MAAM;AAC5G,OAAK,UAAU,EAAE;AACjB,OAAK,eAAe,QAAQ,iBAAiB,yBAAyB,MAAM,yBAAyB,KAAK,yBAAyB;AAEnI,MAAI,MAAM,QAAQ,KAAK,EAAE;GACxB,MAAM,SAAS;AAEf,QAAK,OAAO,QAAQ,QAAQ,oBAAoB;AAChD,QAAK,MAAM,OAAO;SACZ;GACN,MAAM,SAAS;AAEf,QAAK,OAAO,OAAO;AACnB,QAAK,MAAM,OAAO,QAAQ;;;;;;;;CAS5B,AAAO,IAAI,OAAqC;AAC/C,OAAK,QAAQ,KAAK,MAAM;AACxB,SAAO;;CAKR,AAAO,OAAO,OAAwE;AACrF,OAAK,QAAQ,KAAK,iBAAiB,6BAA6B,QAAQ,IAAIA,wFAA4B,MAAM,CAAC;AAC/G,SAAO;;;;;;;;;CAUR,AAAO,WAAW,SAAkB,SAAyB,UAA+B,EAAE,EAA+B;AAC5H,SAAO,KAAK,SAAS,oBAAoB,aACtC,KAAK,UAAU,kBAAkB,SAAS,SAAS,KAAK,SAAS,QAAQ,GACzE,KAAK,UAAU,gBAAgB,SAAS,SAAS,KAAK,SAAS,QAAQ;;;;;;;;;CAU3E,AAAO,aACN,aACA,SACA,UAA+B,EAAE,EACH;AAC9B,SAAO,KAAK,SAAS,oBAAoB,aACtC,KAAK,UAAU,oBAAoB,aAAa,SAAS,KAAK,SAAS,QAAQ,GAC/E,KAAK,UAAU,kBAAkB,aAAa,SAAS,KAAK,SAAS,QAAQ;;;;;;;;;CAUjF,AAAO,eACN,aACA,SACA,UAA+B,EAAE,EACH;AAC9B,SAAO,KAAK,SAAS,oBAAoB,aACtC,KAAK,UAAU,sBAAsB,aAAa,SAAS,KAAK,SAAS,QAAQ,GACjF,KAAK,UAAU,oBAAoB,aAAa,SAAS,KAAK,SAAS,QAAQ;;;;;;;CAQnF,AAAU,MAAM,SAAsD;AACrE,OAAK,MAAM,SAAS,QACnB,MAAK,IACJ,SAAS,MAAM,GACZ,IAAIA,wFAA4B,MAAM,GACtC,IAAI,2BAA2B,OAAO,KAAK,CAC9C;AAGF,SAAO;;;;;;CAOR,IAAc,YAAoC;AACjD,SAAO,2BAA2B,WAAW,IAAI,KAAK,aAAa;;;2BAwB7C,aAAa,IAAIC,sBAA6D,CACpG,CAAC,yBAAyB,KAAKC,6FAAyB,EACxD,CAAC,yBAAyB,IAAIC,2FAAwB,CACtD,CAAC"}