UNPKG

@sapphire/framework

Version:

Discord bot framework built for advanced and amazing bots.

300 lines (297 loc) • 8.9 kB
'use strict'; var lexure = require('@sapphire/lexure'); var pieces = require('@sapphire/pieces'); var result = require('@sapphire/result'); var ArgumentError_cjs = require('../errors/ArgumentError.cjs'); var Identifiers_cjs = require('../errors/Identifiers.cjs'); var UserError_cjs = require('../errors/UserError.cjs'); var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var _Args = class _Args { constructor(message, command, parser, context) { /** * The states stored in the args. * @see Args#save * @see Args#restore */ 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) { const result = await this.pickResult(type, options); return result.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 = lexure.join(this.parser.many().unwrapOr([])); const result = await argument.run(data, { args: this, argument, message: this.message, command: this.command, commandContext: this.commandContext, ...options }); return result.inspectErr(() => this.parser.restore(state)); } async rest(type, options) { const result = await this.restResult(type, options); return result.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()) { const error = result.unwrapErr(); if (error === null) break; if (output.length === 0) { return result; } break; } output.push(result.unwrap()); } return result.Result.ok(output); } async repeat(type, options) { const result = await this.repeatResult(type, options); return result.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) { const result = await this.peekResult(type, options); return result.unwrapRaw(); } nextMaybe(cb) { return result.Option.from(typeof cb === "function" ? this.parser.singleMap(cb) : this.parser.single()); } next(cb) { const value = cb ? this.nextMaybe(cb) : this.nextMaybe(); return value.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 result.Result.err( new UserError_cjs.UserError({ identifier: Identifiers_cjs.Identifiers.ArgsUnavailable, message: `The argument "${name}" was not found.`, context: { name, ...this.toJSON() } }) ); } missingArguments() { return result.Result.err(new UserError_cjs.UserError({ identifier: Identifiers_cjs.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 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 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 result.Result.err(new ArgumentError_cjs.ArgumentError(options)); } }; __name(_Args, "Args"); var Args = _Args; exports.Args = Args; //# sourceMappingURL=Args.cjs.map //# sourceMappingURL=Args.cjs.map