UNPKG

@sapphire/framework

Version:

Discord bot framework built for advanced and amazing bots.

291 lines (289 loc) • 8.21 kB
"use strict"; const require_lib_errors_Identifiers = require('../errors/Identifiers.cjs'); const require_lib_errors_UserError = require('../errors/UserError.cjs'); const require_lib_errors_ArgumentError = require('../errors/ArgumentError.cjs'); let __sapphire_pieces = require("@sapphire/pieces"); let __sapphire_result = require("@sapphire/result"); let __sapphire_lexure = require("@sapphire/lexure"); //#region src/lib/parsers/Args.ts /** * The argument parser to be used in {@link Command}. */ var Args = class { constructor(message, command, parser, context) { this.states = []; this.message = message; this.command = command; this.parser = parser; this.commandContext = context; } /** * Sets the parser to the first token. */ start() { this.parser.reset(); return this; } async pickResult(type, options = {}) { const argument = this.resolveArgument(type); if (!argument) return this.unavailableArgument(type); const result = await this.parser.singleParseAsync(async (arg) => argument.run(arg, { args: this, argument, message: this.message, command: this.command, commandContext: this.commandContext, ...options })); if (result.isErrAnd((value) => value === null)) return this.missingArguments(); return result; } async pick(type, options) { return (await this.pickResult(type, options)).unwrapRaw(); } async restResult(type, options = {}) { const argument = this.resolveArgument(type); if (!argument) return this.unavailableArgument(type); if (this.parser.finished) return this.missingArguments(); const state = this.parser.save(); const data = (0, __sapphire_lexure.join)(this.parser.many().unwrapOr([])); return (await argument.run(data, { args: this, argument, message: this.message, command: this.command, commandContext: this.commandContext, ...options })).inspectErr(() => this.parser.restore(state)); } async rest(type, options) { return (await this.restResult(type, options)).unwrapRaw(); } async repeatResult(type, options = {}) { const argument = this.resolveArgument(type); if (!argument) return this.unavailableArgument(type); if (this.parser.finished) return this.missingArguments(); const output = []; for (let i = 0, times = options.times ?? Infinity; i < times; i++) { const result = await this.parser.singleParseAsync(async (arg) => argument.run(arg, { args: this, argument, message: this.message, command: this.command, commandContext: this.commandContext, ...options })); if (result.isErr()) { if (result.unwrapErr() === null) break; if (output.length === 0) return result; break; } output.push(result.unwrap()); } return __sapphire_result.Result.ok(output); } async repeat(type, options) { return (await this.repeatResult(type, options)).unwrapRaw(); } async peekResult(type, options = {}) { this.save(); const result = typeof type === "function" ? await type() : await this.pickResult(type, options); this.restore(); return result; } async peek(type, options) { return (await this.peekResult(type, options)).unwrapRaw(); } nextMaybe(cb) { return __sapphire_result.Option.from(typeof cb === "function" ? this.parser.singleMap(cb) : this.parser.single()); } next(cb) { return (cb ? this.nextMaybe(cb) : this.nextMaybe()).unwrapOr(null); } /** * Checks if one or more flag were given. * @param keys The name(s) of the flag. * @example * ```typescript * // Suppose args are from '--f --g'. * console.log(args.getFlags('f')); * // >>> true * * console.log(args.getFlags('g', 'h')); * // >>> true * * console.log(args.getFlags('h')); * // >>> false * ``` */ getFlags(...keys) { return this.parser.flag(...keys); } /** * Gets the last value of one or more options as an {@link Option}. * If you do not care about safely handling non-existing values * you can use {@link Args.getOption} to get `string | null` as return type * @param keys The name(s) of the option. * @example * ```typescript * // Suppose args are from '--a=1 --b=2 --c=3'. * console.log(args.getOptionResult('a')); * // >>> Some { value: '1' } * * console.log(args.getOptionResult('b', 'c')); * // >>> Some { value: '2' } * * console.log(args.getOptionResult('d')); * // >>> None {} * ``` */ getOptionResult(...keys) { return this.parser.option(...keys); } /** * Gets the last value of one or more options. * Similar to {@link Args.getOptionResult} but returns the value on success, or `null` if not. * @param keys The name(s) of the option. * @example * ```typescript * // Suppose args are from '--a=1 --b=2 --c=3'. * console.log(args.getOption('a')); * // >>> '1' * * console.log(args.getOption('b', 'c')); * // >>> '2' * * console.log(args.getOption('d')); * // >>> null * ``` */ getOption(...keys) { return this.parser.option(...keys).unwrapOr(null); } /** * Gets all the values of one or more option. * @param keys The name(s) of the option. * @example * ```typescript * // Suppose args are from '--a=1 --a=1 --b=2 --c=3'. * console.log(args.getOptionsResult('a')); * // >>> Some { value: [ '1' ] } * * console.log(args.getOptionsResult('a', 'd')); * // >>> Some { value: [ '1' ] } * * console.log(args.getOptionsResult('b', 'c')); * // >>> Some { value: [ '2', '3' ] } * * console.log(args.getOptionsResult('d')); * // >>> None {} * ``` */ getOptionsResult(...keys) { return this.parser.options(...keys); } /** * Gets all the values of one or more option. * Similar to {@link Args.getOptionsResult} but returns the value on success, or `null` if not. * @param keys The name(s) of the option. * @example * ```typescript * // Suppose args are from '--a=1 --a=1 --b=2 --c=3'. * console.log(args.getOptions('a')); * // >>> ['1', '1'] * * console.log(args.getOptions('b', 'c')); * // >>> ['2', '3'] * * console.log(args.getOptions('d')); * // >>> null * ``` */ getOptions(...keys) { return this.parser.options(...keys).unwrapOr(null); } /** * Saves the current state into the stack following a FILO strategy (first-in, last-out). * @see Args#restore */ save() { this.states.push(this.parser.save()); } /** * Restores the previously saved state from the stack. * @see Args#save */ restore() { if (this.states.length !== 0) this.parser.restore(this.states.pop()); } /** * Whether all arguments have been consumed. */ get finished() { return this.parser.finished; } /** * Defines the `JSON.stringify` override. */ toJSON() { return { message: this.message, command: this.command, commandContext: this.commandContext }; } unavailableArgument(type) { const name = typeof type === "string" ? type : type.name; return __sapphire_result.Result.err(new require_lib_errors_UserError.UserError({ identifier: require_lib_errors_Identifiers.Identifiers.ArgsUnavailable, message: `The argument "${name}" was not found.`, context: { name, ...this.toJSON() } })); } missingArguments() { return __sapphire_result.Result.err(new require_lib_errors_UserError.UserError({ identifier: require_lib_errors_Identifiers.Identifiers.ArgsMissing, message: "There are no more arguments.", context: this.toJSON() })); } /** * Resolves an argument. * @param arg The argument name or {@link IArgument} instance. */ resolveArgument(arg) { if (typeof arg === "object") return arg; return __sapphire_pieces.container.stores.get("arguments").get(arg); } /** * Converts a callback into a usable argument. * @param cb The callback to convert into an {@link IArgument}. * @param name The name of the argument. */ static make(cb, name = "") { return { run: cb, name }; } /** * Constructs an {@link Ok} result. * @param value The value to pass. */ static ok(value) { return __sapphire_result.Result.ok(value); } /** * Constructs an {@link Err} result containing an {@link ArgumentError}. * @param options The options for the argument error. */ static error(options) { return __sapphire_result.Result.err(new require_lib_errors_ArgumentError.ArgumentError(options)); } }; //#endregion exports.Args = Args; //# sourceMappingURL=Args.cjs.map