UNPKG

@sapphire/framework

Version:

Discord bot framework built for advanced and amazing bots.

1 lines • 34.6 kB
{"version":3,"file":"Args.cjs","names":["output: ArgType[K][]","Result","Option","UserError","Identifiers","container","ArgumentError"],"sources":["../../../../src/lib/parsers/Args.ts"],"sourcesContent":["import type { ChannelTypes, GuildBasedChannelTypes } from '@sapphire/discord.js-utilities';\nimport { join, type ArgumentStream, type Parameter } from '@sapphire/lexure';\nimport { container } from '@sapphire/pieces';\nimport { Option, Result } from '@sapphire/result';\nimport type { Awaitable } from '@sapphire/utilities';\nimport type {\n\tCategoryChannel,\n\tChannelType,\n\tDMChannel,\n\tGuildMember,\n\tMessage,\n\tNewsChannel,\n\tRole,\n\tStageChannel,\n\tTextChannel,\n\tThreadChannel,\n\tUser,\n\tVoiceChannel\n} from 'discord.js';\nimport type { URL } from 'node:url';\nimport { ArgumentError } from '../errors/ArgumentError';\nimport { Identifiers } from '../errors/Identifiers';\nimport { UserError } from '../errors/UserError';\nimport type { EmojiObject } from '../resolvers/emoji';\nimport type { Argument, IArgument } from '../structures/Argument';\nimport type { MessageCommand } from '../types/CommandTypes';\n\n/**\n * The argument parser to be used in {@link Command}.\n */\nexport class Args {\n\t/**\n\t * The original message that triggered the command.\n\t */\n\tpublic readonly message: Message;\n\n\t/**\n\t * The command that is being run.\n\t */\n\tpublic readonly command: MessageCommand;\n\n\t/**\n\t * The context of the command being run.\n\t */\n\tpublic readonly commandContext: MessageCommand.RunContext;\n\n\t/**\n\t * The internal Lexure parser.\n\t */\n\tprotected readonly parser: ArgumentStream;\n\n\t/**\n\t * The states stored in the args.\n\t * @see Args#save\n\t * @see Args#restore\n\t */\n\tprivate readonly states: ArgumentStream.State[] = [];\n\n\tpublic constructor(message: Message, command: MessageCommand, parser: ArgumentStream, context: MessageCommand.RunContext) {\n\t\tthis.message = message;\n\t\tthis.command = command;\n\t\tthis.parser = parser;\n\t\tthis.commandContext = context;\n\t}\n\n\t/**\n\t * Sets the parser to the first token.\n\t */\n\tpublic start(): Args {\n\t\tthis.parser.reset();\n\t\treturn this;\n\t}\n\n\t/**\n\t * Retrieves the next parameter and parses it. Advances index on success.\n\t * @param type The type of the argument.\n\t * @param options The pickResult options.\n\t * @example\n\t * ```typescript\n\t * // !square 5\n\t * const resolver = Args.make((parameter, { argument }) => {\n\t * const parsed = Number(parameter);\n\t * if (Number.isNaN(parsed)) {\n\t * return Args.error({ argument, parameter, identifier: 'ArgumentNumberNaN', message: 'You must write a valid number.' });\n\t * }\n\t *\n\t * return Args.ok(parsed);\n\t * });\n\t *\n\t * const a = await args.pickResult(resolver);\n\t * if (!a.success) {\n\t * throw new UserError({ identifier: 'ArgumentNumberNaN', message: 'You must write a valid number.' });\n\t * }\n\t *\n\t * await message.channel.send(`The result is: ${a.value ** 2}!`);\n\t * // Sends \"The result is: 25\"\n\t * ```\n\t */\n\tpublic async pickResult<T>(type: IArgument<T>, options?: ArgOptions): Promise<ResultType<T>>;\n\t/**\n\t * Retrieves the next parameter and parses it. Advances index on success.\n\t * @param type The type of the argument.\n\t * @param options The pickResult options.\n\t * @example\n\t * ```typescript\n\t * // !add 1 2\n\t * const a = await args.pickResult('integer');\n\t * if (!a.success) {\n\t * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write two numbers, but the first one did not match.' });\n\t * }\n\t *\n\t * const b = await args.pickResult('integer');\n\t * if (!b.success) {\n\t * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write two numbers, but the second one did not match.' });\n\t * }\n\t *\n\t * await message.channel.send(`The result is: ${a.value + b.value}!`);\n\t * // Sends \"The result is: 3\"\n\t * ```\n\t */\n\tpublic async pickResult<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ResultType<ArgType[K]>>;\n\tpublic async pickResult<K extends keyof ArgType>(type: K, options: ArgOptions = {}): Promise<ResultType<ArgType[K]>> {\n\t\tconst argument = this.resolveArgument<ArgType[K]>(type);\n\t\tif (!argument) return this.unavailableArgument(type);\n\n\t\tconst result = await this.parser.singleParseAsync(async (arg) =>\n\t\t\targument.run(arg, {\n\t\t\t\targs: this,\n\t\t\t\targument,\n\t\t\t\tmessage: this.message,\n\t\t\t\tcommand: this.command,\n\t\t\t\tcommandContext: this.commandContext,\n\t\t\t\t...options\n\t\t\t})\n\t\t);\n\t\tif (result.isErrAnd((value) => value === null)) {\n\t\t\treturn this.missingArguments();\n\t\t}\n\n\t\treturn result as ResultType<ArgType[K]>;\n\t}\n\n\t/**\n\t * Similar to {@link Args.pickResult} but returns the value on success, throwing otherwise.\n\t * @param type The type of the argument.\n\t * @param options The pick options.\n\t * @example\n\t * ```typescript\n\t * // !square 5\n\t * const resolver = Args.make((parameter, { argument }) => {\n\t * const parsed = Number(parameter);\n\t * if (Number.isNaN(parsed)) {\n\t * return Args.error({ argument, parameter, identifier: 'ArgumentNumberNaN', message: 'You must write a valid number.' });\n\t * }\n\t *\n\t * return Args.ok(parsed);\n\t * });\n\t *\n\t * const a = await args.pick(resolver);\n\t *\n\t * await message.channel.send(`The result is: ${a ** 2}!`);\n\t * // Sends \"The result is: 25\"\n\t * ```\n\t */\n\tpublic async pick<T>(type: IArgument<T>, options?: ArgOptions): Promise<T>;\n\t/**\n\t * Similar to {@link Args.pickResult} but returns the value on success, throwing otherwise.\n\t * @param type The type of the argument.\n\t * @param options The pick options.\n\t * @example\n\t * ```typescript\n\t * // !add 1 2\n\t * const a = await args.pick('integer');\n\t * const b = await args.pick('integer');\n\t * await message.channel.send(`The result is: ${a + b}!`);\n\t * // Sends \"The result is: 3\"\n\t * ```\n\t */\n\tpublic async pick<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ArgType[K]>;\n\tpublic async pick<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ArgType[K]> {\n\t\tconst result = await this.pickResult(type, options);\n\t\treturn result.unwrapRaw();\n\t}\n\n\t/**\n\t * Retrieves all the following arguments.\n\t * @param type The type of the argument.\n\t * @param options The restResult options.\n\t * @example\n\t * ```typescript\n\t * // !reverse Hello world!\n\t * const resolver = Args.make((parameter) => Args.ok(parameter.split('').reverse()));\n\t *\n\t * const a = await args.restResult(resolver);\n\t * if (!a.success) {\n\t * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write some text.' });\n\t * }\n\t *\n\t * await message.channel.send(`The reversed value is... ${a.value}`);\n\t * // Sends \"The reversed value is... !dlrow olleH\"\n\t * ```\n\t */\n\tpublic async restResult<T>(type: IArgument<T>, options?: ArgOptions): Promise<ResultType<T>>;\n\t/**\n\t * Retrieves all the following arguments.\n\t * @param type The type of the argument.\n\t * @param options The restResult options.\n\t * @example\n\t * ```typescript\n\t * // !add 2 Hello World!\n\t * const a = await args.pickResult('integer');\n\t * if (!a.success) {\n\t * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write a number and a text, but the former did not match.' });\n\t * }\n\t *\n\t * const b = await args.restResult('string', { minimum: 1 });\n\t * if (!b.success) {\n\t * throw new UserError({ identifier: 'AddArgumentError', message: 'You must write a number and a text, but the latter did not match.' });\n\t * }\n\t *\n\t * await message.channel.send(`The repeated value is... ${b.value.repeat(a.value)}!`);\n\t * // Sends \"The repeated value is... Hello World!Hello World!\"\n\t * ```\n\t */\n\tpublic async restResult<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ResultType<ArgType[K]>>;\n\tpublic async restResult<T>(type: keyof ArgType | IArgument<T>, options: ArgOptions = {}): Promise<ResultType<T>> {\n\t\tconst argument = this.resolveArgument(type);\n\t\tif (!argument) return this.unavailableArgument(type);\n\t\tif (this.parser.finished) return this.missingArguments();\n\n\t\tconst state = this.parser.save();\n\t\tconst data = join(this.parser.many().unwrapOr<Parameter[]>([]));\n\t\tconst result = await argument.run(data, {\n\t\t\targs: this,\n\t\t\targument,\n\t\t\tmessage: this.message,\n\t\t\tcommand: this.command,\n\t\t\tcommandContext: this.commandContext,\n\t\t\t...options\n\t\t});\n\n\t\treturn result.inspectErr(() => this.parser.restore(state));\n\t}\n\n\t/**\n\t * Similar to {@link Args.restResult} but returns the value on success, throwing otherwise.\n\t * @param type The type of the argument.\n\t * @param options The rest options.\n\t * @example\n\t * ```typescript\n\t * // !reverse Hello world!\n\t * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse()));\n\t * const a = await args.rest(resolver);\n\t * await message.channel.send(`The reversed value is... ${a}`);\n\t * // Sends \"The reversed value is... !dlrow olleH\"\n\t * ```\n\t */\n\tpublic async rest<T>(type: IArgument<T>, options?: ArgOptions): Promise<T>;\n\t/**\n\t * Similar to {@link Args.restResult} but returns the value on success, throwing otherwise.\n\t * @param type The type of the argument.\n\t * @param options The rest options.\n\t * @example\n\t * ```typescript\n\t * // !add 2 Hello World!\n\t * const a = await args.pick('integer');\n\t * const b = await args.rest('string', { minimum: 1 });\n\t * await message.channel.send(`The repeated value is... ${b.repeat(a)}!`);\n\t * // Sends \"The repeated value is... Hello World!Hello World!\"\n\t * ```\n\t */\n\tpublic async rest<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ArgType[K]>;\n\tpublic async rest<K extends keyof ArgType>(type: K, options?: ArgOptions): Promise<ArgType[K]> {\n\t\tconst result = await this.restResult(type, options);\n\t\treturn result.unwrapRaw();\n\t}\n\n\t/**\n\t * Retrieves all the following arguments.\n\t * @param type The type of the argument.\n\t * @param options The repeatResult options.\n\t * @example\n\t * ```typescript\n\t * // !add 2 Hello World!\n\t * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse()));\n\t * const result = await args.repeatResult(resolver, { times: 5 });\n\t * if (!result.success) {\n\t * throw new UserError({ identifier: 'CountArgumentError', message: 'You must write up to 5 words.' });\n\t * }\n\t *\n\t * await message.channel.send(`You have written ${result.value.length} word(s): ${result.value.join(' ')}`);\n\t * // Sends \"You have written 2 word(s): olleH !dlroW\"\n\t * ```\n\t */\n\tpublic async repeatResult<T>(type: IArgument<T>, options?: RepeatArgOptions): Promise<ArrayResultType<T>>;\n\t/**\n\t * Retrieves all the following arguments.\n\t * @param type The type of the argument.\n\t * @param options The repeatResult options.\n\t * @example\n\t * ```typescript\n\t * // !reverse-each 2 Hello World!\n\t * const result = await args.repeatResult('string', { times: 5 });\n\t * if (!result.success) {\n\t * throw new UserError({ identifier: 'CountArgumentError', message: 'You must write up to 5 words.' });\n\t * }\n\t *\n\t * await message.channel.send(`You have written ${result.value.length} word(s): ${result.value.join(' ')}`);\n\t * // Sends \"You have written 2 word(s): Hello World!\"\n\t * ```\n\t */\n\tpublic async repeatResult<K extends keyof ArgType>(type: K, options?: RepeatArgOptions): Promise<ArrayResultType<ArgType[K]>>;\n\tpublic async repeatResult<K extends keyof ArgType>(type: K, options: RepeatArgOptions = {}): Promise<ArrayResultType<ArgType[K]>> {\n\t\tconst argument = this.resolveArgument(type);\n\t\tif (!argument) return this.unavailableArgument(type);\n\t\tif (this.parser.finished) return this.missingArguments();\n\n\t\tconst output: ArgType[K][] = [];\n\n\t\tfor (let i = 0, times = options.times ?? Infinity; i < times; i++) {\n\t\t\tconst result = await this.parser.singleParseAsync(async (arg) =>\n\t\t\t\targument.run(arg, {\n\t\t\t\t\targs: this,\n\t\t\t\t\targument,\n\t\t\t\t\tmessage: this.message,\n\t\t\t\t\tcommand: this.command,\n\t\t\t\t\tcommandContext: this.commandContext,\n\t\t\t\t\t...options\n\t\t\t\t})\n\t\t\t);\n\n\t\t\tif (result.isErr()) {\n\t\t\t\tconst error = result.unwrapErr();\n\t\t\t\tif (error === null) break;\n\n\t\t\t\tif (output.length === 0) {\n\t\t\t\t\treturn result as Result.Err<UserError | ArgumentError<ArgType[K]>>;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\toutput.push(result.unwrap() as ArgType[K]);\n\t\t}\n\n\t\treturn Result.ok(output);\n\t}\n\n\t/**\n\t * Similar to {@link Args.repeatResult} but returns the value on success, throwing otherwise.\n\t * @param type The type of the argument.\n\t * @param options The repeat options.\n\t * @example\n\t * ```typescript\n\t * // !reverse-each 2 Hello World!\n\t * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse()));\n\t * const result = await args.repeat(resolver, { times: 5 });\n\t * await message.channel.send(`You have written ${result.length} word(s): ${result.join(' ')}`);\n\t * // Sends \"You have written 2 word(s): Hello World!\"\n\t * ```\n\t */\n\tpublic async repeat<T>(type: IArgument<T>, options?: RepeatArgOptions): Promise<T[]>;\n\t/**\n\t * Similar to {@link Args.repeatResult} but returns the value on success, throwing otherwise.\n\t * @param type The type of the argument.\n\t * @param options The repeat options.\n\t * @example\n\t * ```typescript\n\t * // !add 2 Hello World!\n\t * const words = await args.repeat('string', { times: 5 });\n\t * await message.channel.send(`You have written ${words.length} word(s): ${words.join(' ')}`);\n\t * // Sends \"You have written 2 word(s): Hello World!\"\n\t * ```\n\t */\n\tpublic async repeat<K extends keyof ArgType>(type: K, options?: RepeatArgOptions): Promise<ArgType[K][]>;\n\tpublic async repeat<K extends keyof ArgType>(type: K, options?: RepeatArgOptions): Promise<ArgType[K][]> {\n\t\tconst result = await this.repeatResult(type, options);\n\t\treturn result.unwrapRaw();\n\t}\n\n\t/**\n\t * Peeks the following parameter(s) without advancing the parser's state.\n\t * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult},\n\t * or {@link Args.restResult}; otherwise, passing the custom argument or the argument type with options\n\t * will use {@link Args.pickResult} and only peek a single argument.\n\t * @param type The function, custom argument, or argument name.\n\t * @example\n\t * ```typescript\n\t * // !reversedandscreamfirst hello world\n\t * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse().join('')));\n\t *\n\t * const result = await args.repeatResult(resolver);\n\t * await result.inspectAsync((value) =>\n\t * \tmessage.channel.send(`Reversed ${value.length} word(s): ${value.join(' ')}`)\n\t * ); // Reversed 2 word(s): olleh dlrow\n\t *\n\t * const firstWord = await args.pickResult('string');\n\t * await firstWord.inspectAsync((value) =>\n\t * \tmessage.channel.send(firstWord.value.toUpperCase())\n\t * ); // HELLO\n\t * ```\n\t */\n\tpublic async peekResult<T>(type: () => Argument.Result<T>): Promise<ResultType<T>>;\n\t/**\n\t * Peeks the following parameter(s) without advancing the parser's state.\n\t * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult},\n\t * or {@link Args.restResult}; otherwise, passing the custom argument or the argument type with options\n\t * will use {@link Args.pickResult} and only peek a single argument.\n\t * @param type The function, custom argument, or argument name.\n\t * @param options The peekResult options.\n\t * @example\n\t * ```typescript\n\t * // !reverseandscreamfirst sapphire community\n\t * const resolver = Args.make((arg) => Args.ok(arg.split('').reverse().join('')));\n\t *\n\t * const peekedWord = await args.peekResult(resolver);\n\t * await peekedWord.inspectAsync((value) => message.channel.send(value)); // erihppas\n\t *\n\t * const firstWord = await args.pickResult('string');\n\t * await firstWord.inspectAsync((value) => message.channel.send(value.toUpperCase())); // SAPPHIRE\n\t * ```\n\t */\n\tpublic async peekResult<T>(type: IArgument<T>, options?: ArgOptions): Promise<ResultType<T>>;\n\t/**\n\t * Peeks the following parameter(s) without advancing the parser's state.\n\t * Passing a function as a parameter allows for returning {@link Args.pickResult}, {@link Args.repeatResult},\n\t * or {@link Args.restResult}; otherwise, passing the custom argument or the argument type with options\n\t * will use {@link Args.pickResult} and only peek a single argument.\n\t * @param type The function, custom argument, or argument name.\n\t * @param options The peekResult options.\n\t * @example\n\t * ```typescript\n\t * // !datethenaddtwo 1608867472611\n\t * const date = await args.peekResult('date');\n\t * await date.inspectAsync((value) =>\n\t * \tmessage.channel.send(`Your date (in UTC): ${value.toUTCString()}`)\n\t * ); // Your date (in UTC): Fri, 25 Dec 2020 03:37:52 GMT\n\t *\n\t * const result = await args.pickResult('number', { maximum: Number.MAX_SAFE_INTEGER - 2 });\n\t * await result.inspectAsync((value) =>\n\t * \tmessage.channel.send(`Your number plus two: ${value + 2}`)\n\t * ); // Your number plus two: 1608867472613\n\t * ```\n\t */\n\tpublic async peekResult<K extends keyof ArgType>(\n\t\ttype: (() => Awaitable<Argument.Result<ArgType[K]>>) | K,\n\t\toptions?: ArgOptions\n\t): Promise<ResultType<ArgType[K]>>;\n\n\tpublic async peekResult<K extends keyof ArgType>(\n\t\ttype: (() => Awaitable<Argument.Result<ArgType[K]>>) | K,\n\t\toptions: ArgOptions = {}\n\t): Promise<ResultType<ArgType[K]>> {\n\t\tthis.save();\n\t\tconst result = typeof type === 'function' ? await type() : await this.pickResult(type, options);\n\t\tthis.restore();\n\t\treturn result;\n\t}\n\n\t/**\n\t * Similar to {@link Args.peekResult} but returns the value on success, throwing otherwise.\n\t * @param type The function, custom argument, or argument name.\n\t * @example\n\t * ```typescript\n\t * // !bigintsumthensquarefirst 25 50 75\n\t * const resolver = Args.make((arg, { argument }) => {\n\t * try {\n\t * return Args.ok(BigInt(arg));\n\t * } catch {\n\t * return Args.error({ parameter: arg, argument, identifier: 'InvalidBigInt', message: 'You must specify a valid number for a bigint.' })\n\t * }\n\t * });\n\t *\n\t * const peeked = await args.repeatResult(resolver);\n\t * await peeked.inspectAsync((value) => message.channel.send(`Sum: **${value.reduce((x, y) => x + y, 0n)}**`)); // Sum: 150n\n\t *\n\t * const first = await args.pick(resolver);\n\t * await message.channel.send(`First bigint squared: ${first**2n}`); // First bigint squared: 625\n\t * ```\n\t */\n\tpublic async peek<T>(type: () => Argument.Result<T>): Promise<T>;\n\t/**\n\t * Similar to {@link Args.peekResult} but returns the value on success, throwing otherwise.\n\t * @param type The function, custom argument, or argument name.\n\t * @param options The peek options.\n\t * @example\n\t * ```typescript\n\t * import { SnowflakeRegex } from '@sapphire/discord.js-utilities';\n\t * import { DiscordSnowflake } from '@sapphire/snowflake';\n\t *\n\t * // !createdat 730159185517477900\n\t * const snowflakeResolver = Args.make<bigint>((arg, { argument }) => {\n\t * return SnowflakeRegex.test(arg)\n\t * ? Args.ok(BigInt(arg))\n\t * : Args.error({ parameter: arg, argument, identifier: 'InvalidSnowflake', message: 'You must specify a valid snowflake.' });\n\t * });\n\t *\n\t * const snowflake = await args.peek(snowflakeResolver);\n\t * const timestamp = Number((snowflake >> 22n) + DiscordSnowflake.epoch);\n\t * const createdAt = new Date(timestamp);\n\t *\n\t * await message.channel.send(\n\t * `The snowflake ${snowflake} was registered on ${createdAt.toUTCString()}.`\n\t * ); // The snowflake 730159185517477900 was registered on Tue, 07 Jul 2020 20:31:55 GMT.\n\t *\n\t * const id = await args.pick('string');\n\t * await message.channel.send(`Your ID, reversed: ${id.split('').reverse().join('')}`); // Your ID, reversed: 009774715581951037\n\t * ```\n\t */\n\tpublic async peek<T>(type: IArgument<T>, options?: ArgOptions): Promise<T>;\n\t/**\n\t * Similar to {@link Args.peekResult} but returns the value on success, throwing otherwise.\n\t * @param type The function, custom argument, or argument name.\n\t * @param options The peek options.\n\t * @example\n\t * ```typescript\n\t * // !messagelink https://discord.com/channels/737141877803057244/737142209639350343/791843123898089483\n\t * const remoteMessage = await args.peek('message');\n\t * await message.channel.send(\n\t * `${remoteMessage.author.tag}: ${remoteMessage.content}`\n\t * ); // RealShadowNova#7462: Yeah, Sapphire has been a great experience so far, especially being able to help and contribute.\n\t *\n\t * const url = await args.pick('hyperlink');\n\t * await message.channel.send(`Hostname: ${url.hostname}`); // Hostname: discord.com\n\t * ```\n\t */\n\tpublic async peek<K extends keyof ArgType>(type: (() => Argument.Result<ArgType[K]>) | K, options?: ArgOptions): Promise<ArgType[K]>;\n\tpublic async peek<K extends keyof ArgType>(type: (() => Argument.Result<ArgType[K]>) | K, options?: ArgOptions): Promise<ArgType[K]> {\n\t\tconst result = await this.peekResult(type, options);\n\t\treturn result.unwrapRaw();\n\t}\n\n\t/**\n\t * Retrieves the next raw argument from the parser.\n\t * @example\n\t * ```typescript\n\t * // !numbers 1 2 3\n\t *\n\t * console.log(args.nextMaybe());\n\t * // -> { exists: true, value: '1' }\n\t * ```\n\t */\n\tpublic nextMaybe(): Option<string>;\n\t/**\n\t * Retrieves the value of the next unused ordered token, but only if it could be transformed.\n\t * That token will now be used if the transformation succeeds.\n\t * @typeparam T Output type of the {@link ArgsNextCallback callback}.\n\t * @param cb Gives an option of either the resulting value, or nothing if failed.\n\t * @example\n\t * ```typescript\n\t * // !numbers 1 2 3\n\t * const parse = (x: string) => {\n\t * const n = Number(x);\n\t * return Number.isNaN(n) ? none() : some(n);\n\t * };\n\t *\n\t * console.log(args.nextMaybe(parse));\n\t * // -> { exists: true, value: 1 }\n\t * ```\n\t */\n\tpublic nextMaybe<T>(cb: ArgsNextCallback<T>): Option<T>;\n\tpublic nextMaybe<T>(cb?: ArgsNextCallback<T>): Option<T | string> {\n\t\treturn Option.from<T | string>(typeof cb === 'function' ? this.parser.singleMap(cb) : this.parser.single());\n\t}\n\n\t/**\n\t * Similar to {@link Args.nextMaybe} but returns the value on success, null otherwise.\n\t * @example\n\t * ```typescript\n\t * // !numbers 1 2 3\n\t *\n\t * console.log(args.next());\n\t * // -> '1'\n\t * ```\n\t */\n\tpublic next(): string;\n\t/**\n\t * Similar to {@link Args.nextMaybe} but returns the value on success, null otherwise.\n\t * @typeparam T Output type of the {@link ArgsNextCallback callback}.\n\t * @param cb Gives an option of either the resulting value, or nothing if failed.\n\t * @example\n\t * ```typescript\n\t * // !numbers 1 2 3\n\t * const parse = (x: string) => {\n\t * const n = Number(x);\n\t * return Number.isNaN(n) ? none() : some(n);\n\t * };\n\t *\n\t * console.log(args.nextMaybe(parse));\n\t * // -> 1\n\t * ```\n\t */\n\tpublic next<T>(cb: ArgsNextCallback<T>): T;\n\tpublic next<T>(cb?: ArgsNextCallback<T>): T | string | null {\n\t\tconst value = cb ? this.nextMaybe<T | string | null>(cb) : this.nextMaybe();\n\t\treturn value.unwrapOr(null);\n\t}\n\n\t/**\n\t * Checks if one or more flag were given.\n\t * @param keys The name(s) of the flag.\n\t * @example\n\t * ```typescript\n\t * // Suppose args are from '--f --g'.\n\t * console.log(args.getFlags('f'));\n\t * // >>> true\n\t *\n\t * console.log(args.getFlags('g', 'h'));\n\t * // >>> true\n\t *\n\t * console.log(args.getFlags('h'));\n\t * // >>> false\n\t * ```\n\t */\n\tpublic getFlags(...keys: readonly string[]): boolean {\n\t\treturn this.parser.flag(...keys);\n\t}\n\n\t/**\n\t * Gets the last value of one or more options as an {@link Option}.\n\t * If you do not care about safely handling non-existing values\n\t * you can use {@link Args.getOption} to get `string | null` as return type\n\t * @param keys The name(s) of the option.\n\t * @example\n\t * ```typescript\n\t * // Suppose args are from '--a=1 --b=2 --c=3'.\n\t * console.log(args.getOptionResult('a'));\n\t * // >>> Some { value: '1' }\n\t *\n\t * console.log(args.getOptionResult('b', 'c'));\n\t * // >>> Some { value: '2' }\n\t *\n\t * console.log(args.getOptionResult('d'));\n\t * // >>> None {}\n\t * ```\n\t */\n\tpublic getOptionResult(...keys: readonly string[]): Option<string> {\n\t\treturn this.parser.option(...keys);\n\t}\n\n\t/**\n\t * Gets the last value of one or more options.\n\t * Similar to {@link Args.getOptionResult} but returns the value on success, or `null` if not.\n\t * @param keys The name(s) of the option.\n\t * @example\n\t * ```typescript\n\t * // Suppose args are from '--a=1 --b=2 --c=3'.\n\t * console.log(args.getOption('a'));\n\t * // >>> '1'\n\t *\n\t * console.log(args.getOption('b', 'c'));\n\t * // >>> '2'\n\t *\n\t * console.log(args.getOption('d'));\n\t * // >>> null\n\t * ```\n\t */\n\tpublic getOption(...keys: readonly string[]): string | null {\n\t\treturn this.parser.option(...keys).unwrapOr(null);\n\t}\n\n\t/**\n\t * Gets all the values of one or more option.\n\t * @param keys The name(s) of the option.\n\t * @example\n\t * ```typescript\n\t * // Suppose args are from '--a=1 --a=1 --b=2 --c=3'.\n\t * console.log(args.getOptionsResult('a'));\n\t * // >>> Some { value: [ '1' ] }\n\t *\n\t * console.log(args.getOptionsResult('a', 'd'));\n\t * // >>> Some { value: [ '1' ] }\n\t *\n\t * console.log(args.getOptionsResult('b', 'c'));\n\t * // >>> Some { value: [ '2', '3' ] }\n\t *\n\t * console.log(args.getOptionsResult('d'));\n\t * // >>> None {}\n\t * ```\n\t */\n\tpublic getOptionsResult(...keys: readonly string[]): Option<readonly string[]> {\n\t\treturn this.parser.options(...keys);\n\t}\n\n\t/**\n\t * Gets all the values of one or more option.\n\t * Similar to {@link Args.getOptionsResult} but returns the value on success, or `null` if not.\n\t * @param keys The name(s) of the option.\n\t * @example\n\t * ```typescript\n\t * // Suppose args are from '--a=1 --a=1 --b=2 --c=3'.\n\t * console.log(args.getOptions('a'));\n\t * // >>> ['1', '1']\n\t *\n\t * console.log(args.getOptions('b', 'c'));\n\t * // >>> ['2', '3']\n\t *\n\t * console.log(args.getOptions('d'));\n\t * // >>> null\n\t * ```\n\t */\n\tpublic getOptions(...keys: readonly string[]): readonly string[] | null {\n\t\treturn this.parser.options(...keys).unwrapOr(null);\n\t}\n\n\t/**\n\t * Saves the current state into the stack following a FILO strategy (first-in, last-out).\n\t * @see Args#restore\n\t */\n\tpublic save(): void {\n\t\tthis.states.push(this.parser.save());\n\t}\n\n\t/**\n\t * Restores the previously saved state from the stack.\n\t * @see Args#save\n\t */\n\tpublic restore(): void {\n\t\tif (this.states.length !== 0) this.parser.restore(this.states.pop()!);\n\t}\n\n\t/**\n\t * Whether all arguments have been consumed.\n\t */\n\tpublic get finished(): boolean {\n\t\treturn this.parser.finished;\n\t}\n\n\t/**\n\t * Defines the `JSON.stringify` override.\n\t */\n\tpublic toJSON(): ArgsJson {\n\t\treturn { message: this.message, command: this.command, commandContext: this.commandContext };\n\t}\n\n\tprotected unavailableArgument<T>(type: string | IArgument<T>): Result.Err<UserError> {\n\t\tconst name = typeof type === 'string' ? type : type.name;\n\t\treturn Result.err(\n\t\t\tnew UserError({\n\t\t\t\tidentifier: Identifiers.ArgsUnavailable,\n\t\t\t\tmessage: `The argument \"${name}\" was not found.`,\n\t\t\t\tcontext: { name, ...this.toJSON() }\n\t\t\t})\n\t\t);\n\t}\n\n\tprotected missingArguments(): Result.Err<UserError> {\n\t\treturn Result.err(new UserError({ identifier: Identifiers.ArgsMissing, message: 'There are no more arguments.', context: this.toJSON() }));\n\t}\n\n\t/**\n\t * Resolves an argument.\n\t * @param arg The argument name or {@link IArgument} instance.\n\t */\n\tprivate resolveArgument<T>(arg: keyof ArgType | IArgument<T>): IArgument<T> | undefined {\n\t\tif (typeof arg === 'object') return arg;\n\t\treturn container.stores.get('arguments').get(arg as string) as IArgument<T> | undefined;\n\t}\n\n\t/**\n\t * Converts a callback into a usable argument.\n\t * @param cb The callback to convert into an {@link IArgument}.\n\t * @param name The name of the argument.\n\t */\n\tpublic static make<T>(cb: IArgument<T>['run'], name = ''): IArgument<T> {\n\t\treturn { run: cb, name };\n\t}\n\n\t/**\n\t * Constructs an {@link Ok} result.\n\t * @param value The value to pass.\n\t */\n\tpublic static ok<T>(value: T): Result.Ok<T> {\n\t\treturn Result.ok(value);\n\t}\n\n\t/**\n\t * Constructs an {@link Err} result containing an {@link ArgumentError}.\n\t * @param options The options for the argument error.\n\t */\n\tpublic static error<T>(options: ArgumentError.Options<T>): Result.Err<ArgumentError<T>> {\n\t\treturn Result.err(new ArgumentError<T>(options));\n\t}\n}\n\nexport interface ArgsJson {\n\tmessage: Message<boolean>;\n\tcommand: MessageCommand;\n\tcommandContext: MessageCommand.RunContext;\n}\n\nexport interface ArgType {\n\tboolean: boolean;\n\tchannel: ChannelTypes;\n\tdate: Date;\n\tdmChannel: DMChannel;\n\temoji: EmojiObject;\n\tfloat: number;\n\tguildCategoryChannel: CategoryChannel;\n\tguildChannel: GuildBasedChannelTypes;\n\tguildNewsChannel: NewsChannel;\n\tguildNewsThreadChannel: ThreadChannel & { type: ChannelType.AnnouncementThread; parent: NewsChannel | null };\n\tguildPrivateThreadChannel: ThreadChannel & { type: ChannelType.PrivateThread; parent: TextChannel | null };\n\tguildPublicThreadChannel: ThreadChannel & { type: ChannelType.PublicThread; parent: TextChannel | null };\n\tguildStageVoiceChannel: StageChannel;\n\tguildTextChannel: TextChannel;\n\tguildThreadChannel: ThreadChannel;\n\tguildVoiceChannel: VoiceChannel;\n\thyperlink: URL;\n\tinteger: number;\n\tmember: GuildMember;\n\tmessage: Message;\n\tnumber: number;\n\trole: Role;\n\tstring: string;\n\turl: URL;\n\tuser: User;\n\tenum: string;\n}\n\nexport interface ArgOptions extends Omit<Argument.Context, 'message' | 'command'> {}\n\nexport interface RepeatArgOptions extends ArgOptions {\n\t/**\n\t * The maximum amount of times the argument can be repeated.\n\t * @default Infinity\n\t */\n\ttimes?: number;\n}\n\n/**\n * The callback used for {@link Args.nextMaybe} and {@link Args.next}.\n */\nexport interface ArgsNextCallback<T> {\n\t/**\n\t * The value to be mapped.\n\t */\n\t(value: string): Option<T>;\n}\n\nexport type ResultType<T> = Result<T, UserError | ArgumentError<T>>;\nexport type ArrayResultType<T> = Result<T[], UserError | ArgumentError<T>>;\n"],"mappings":"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"}