Skip to main content

Using options

Now that we've gone over boolean flags, what if we want a string instead of a boolean value? That's where options come in. Options are formatted like flags, but followed by =value. For example, an option could be --size=2048. Users of UNIX-like command-line tools may once again be familiar with this format, such as in help --find=entry.

Just like with flags, you can use options in two ways: declarative and imperative.

tip

Options are either strings, an array of strings, or undefined.

caution

When an option is read through args.getOption('<optionName>') but it is not provided by the user, the value of that variable will default to undefined.

Imperative Options

Imperative options are options you specify in the command options, and using them means Sapphire will only parse the specified options.

We recommend this method because it can avoid unexpected situations where something, for example in args.rest('string'), is parsed as an option mistakenly.

To add imperative options to your command you specify them in your command's options, like so:

import { ApplyOptions } from '@sapphire/decorators';import { Command, Args } from '@sapphire/framework';import type { Message } from 'discord.js';export class OptionsCommand extends Command {  public constructor(context: Command.Context, options: Command.Options) {    super(context, {      ...options,      options: ['size']    });  }  public async messageRun(message: Message, args: Args) {}}
info

We only parse the options that you specify when using imperative options. If the user provides anything else like --this=cool, that won't be parsed as options with this code, because we only set --size=.

Next, to read the values for the provided options we use args.getOption('<optionName>') or args.getOptions('<optionName>')

The difference between args.getOption('<optionName>') and args.getOptions('<optionName>') is that the former will only read the last value provided for an option and return a string, whereas the latter will read all values provided and return an array of strings.

For example, consider the following:

  • @bot avatar --size=2048 --size=4096 with getOption will return '4096'
  • @bot avatar --size=2048 --size=4096 with getOptions will return ['2048', '4096']
import { ApplyOptions } from '@sapphire/decorators';import { Command, Args } from '@sapphire/framework';import type { Message } from 'discord.js';export class OptionsCommand extends Command {  public constructor(context: Command.Context, options: Command.Options) {    super(context, {      ...options,      options: ['size']    });  }  public async messageRun(message: Message, args: Args) {    const sizeForAvatar = args.getOption('size');  }}
info

Unlike methods like args.pick and args.rest, args.getOption('<optionName>') and args.getOptions('<optionName>') aren't asynchronous, so they don't need to be awaited - they return regular strings, arrays of strings, or undefined, rather than a promise.

Declarative Options

When opting for declarative options it means that Sapphire will try to parse everything that starts with 2 consecutive hyphens. That means that --these=.. --will=... --all=.. --be=... --options=.... This can lead to unexpected situations, especially when using args.rest('string'). However, the flipside is that it's easy for you as a developer because you won't need to keep track of what options you have specified and are trying to get from the args.

To use and configure declarative options you can follow most of the same for imperative options, with the difference being that instead of providing an array of items to the options option, you simply set that property to true. Here is an example:

import { ApplyOptions } from '@sapphire/decorators';import { Command, Args } from '@sapphire/framework';import type { Message } from 'discord.js';export class OptionsCommand extends Command {  public constructor(context: Command.Context, options: Command.Options) {    super(context, {      ...options,      options: true    });  }  public async messageRun(message: Message, args: Args) {    const [size, format] = args.getOptions('size', 'format');  }}