Skip to content

API | vorpal.command

dc edited this page Dec 24, 2015 · 17 revisions

Vorpal Command

The Command object is the building block for all commands in your CLI app. Running vorpal.command adds a new command and returns a new instance of the Command object, which holds a series of chainable methods for declaring and customizing your command.

API

vorpal.command(command[, description])

Adds a new command to your command line API. Returns a Command object.

vorpal
  .command('foo <requiredArg> [optionalArg]')
  .option('-v, --verbose', 'Print foobar instead.')
  .description('Outputs "bar".')
  .alias('foosball')
  .action(function(args, callback) {
    if (args.options.verbose) {
      this.log('foobar');
    } else {
      this.log('bar');
    }
    callback();
  });

When a command is executed by the user, the action method is fired, passing in the arguments and options given by the user, and a callback that ends the command when called.

Optional arguments
vorpal.command('foo [str]');
// $ foo bar -> {str: 'bar'}
Required arguments

When a required argument is not given the by user, the command's automated help menu is called.

vorpal.command('foo <str>');
// $ foo bar -> {str: 'bar'}
Variadic arguments

A variadic argument simply means the user can pass in multiple words to the argument, and the results are returned as an array of strings.

vorpal.command('foo [strings...]');
// $ foo bar and so on -> {strings: ['bar', `and`, `so`, `on`]}
Multiple arguments

Put the required arguments first, and variadic in the back.

vorpal.command('foo <required> [optional] [variadic...]');
// $ foo bar and so on 
// -> {required: 'bar', optional: 'and', variadic: [`so`, `on`]}
Optional description

You can optionally pass a description as the second parameter. This populates the automated help menu.

vorpal.command('foo', 'Outputs bar.'); 
$ help
  ...

    foo        Outputs bar.
Multi-word commands

Commands longer than one word will be grouped in the help menu.

vorpal.command('do this'); 
vorpal.command('do that and then <this>'); 
$ help
  ...

  Command Groups:

    do *     2 sub-commands.

.command.description(string)

If you don't pass a description into vorpal.command(...), you can use the description method as an alternative.

vorpal
  .command('foo')
  .description('outputs bar');

.command.alias(name[, names...])

Provides an alias to the command. If the user enters the alias, the original command will be fired.

vorpal
  .command('foo', 'Outputs bar.')
  .alias('foobar');
app~$ foobar
bar
app~$

.command.parse(parseFunction)

Parse and alter the raw command entered by the user before it is executing. Useful for things such as auto-appending pipes to the command under certain conditions.

vorpal
  .command('blabber', 'Outputs a whole bunch of text.')
  .parse(function (command, args) { 
    return command + ' | less';   
  });

.command.option(string[, description])

Extra options for the user. You can provide both short and long versions of an option, optional and required parameters. Results of an option are passed into the .action method's first parameter.

vorpal
  .command('print these options', 'Prints the options.')
  .option('-f, --force', 'Force file overwrite.')
  .option('-a, --amount <coffee>', 'Number of cups of coffee.')
  .option('-v, --verbosity [level]', 'Sets verbosity level.')
  .option('-A', 'Does amazing things.')
  .option('--amazing', 'Does amazing things')
  // ...
app~$ print these options -f --amount 8 -v -A --amazing
{ options: {
  force: true, 
  amount: 8, 
  verbosity: 
  true, 
  A: true,
  amazing: true
}}

.command.types(object)

Explicitly types the data returned by given options.

vorpal
  .command('stringify')
  .option('-a, --amount <amt>', 'A number to stringify.')
  .types({
    string: ['a', 'amount']
  })
  .action(function (args, cb) {
    this.log(args.options);
    cb();
  });
app~$ stringify -a 7
{amount: '7'}         # would have otherwise been an integer

.command.hidden()

Makes the command invisible, though executable. Removes from all automated help menus.

vorpal
  .command('hidden', 'Secret command.')
  .hidden();

.command.remove()

Deletes a given command. Useful for getting rid of unwanted functionality when importing external extensions.

  const help = vorpal.find('help');
  if (help) { 
    help.remove();
  }

.command.help()

Overrides the auto-generated help method for a given command, which is invoked through [command] --help or [command] /?.

vorpal
  .command('foo')
  .help(function (args) {
    this.log('This command outputs "bar".');
  })
  .action(function(args, cb){
    this.log('bar');
  });

.command.autocompletion(function)

Registers a custom tabbed autocompletion for this command.

vorpal
  .command("bake", "Bakes a meal.")
  .autocompletion(function(text, iteration, cb) {
    var meals = ["cookies", "pie", "cake"];
    if (iteration > 1) {
      cb(void 0, meals);
    } else {
      var match = this.match(text, meals);
      if (match) {
        cb(void 0, meals);
      } else {
        cb(void 0, void 0);
      }
    }
  })
  .action(...);
Explanation

If a user has typed part of a registered command, the default auto-completion will fill in the rest of the command:

node~$ co
node~$ cook

However, after the user has fully typed the command cook, you can now implement command-specific auto-completion:

node~$ bake coo            # tab is pressed
node~$ bake cookies        # tab is pressed again
cake  cookies  pie
node~$ bake cookies 

To further describe the implementation:

vorpal
  .command("bake", "Bakes a meal.")
  .autocompletion(function(text, iteration, cb) {
    
    // The meals are all of the possible actions.
    var meals = ["cookies", "pie", "cake"];
    
    // The iteration is the count of how many times
    // the `tab` key was pressed in a row. You can
    // make multiple presses return all of the options
    // for the user's convenience. 
    if (iteration > 1) {

      // By returning an array of values, Vorpal
      // will format them in a pretty fashion, as
      // in the example above.
      cb(void 0, meals);

    } else {

      // `this.match` is a helper function that will
      // return the closest auto-completion match.
      // Just makin' your job easier.
      var match = this.match(text, meals);
      
      if (match) {

        // If there is a good autocomplete, return
        // it in the callback (first param is reserved
        // for errors).
        cb(void 0, meals);
      } else {

        // If you don't want to do anything, just
        // return undefined.
        cb(void 0, void 0);
      }
    }
  })
  .action(...);

.command.action(function)

This is the action execution function of a given command. It passes in an arguments object and callback.

Actions are executed async and must either call the passed callback upon completion or return a Promise.

// As a callback:
command(...).action(function(args, cb){
  var self = this;
  doSomethingAsync(function(results){
    self.log(results);
    // If this is not called, Vorpal will not 
    // return its CLI prompt after command completion.
    cb();
  });
});

// As a newly created Promise:
command(...).action(function(args, cb){
  return new Promise(function(resolve, reject) {
    if (skiesAlignTonight) {
      resolve();
    } else {
      reject("Better luck next time");
    }
  });
});

// Or as a pre-packaged promise of your app:
command(...).action(function(args, cb){
  return app.promisedAction(args.action);
});
Action Arguments

Given the following command:

vorpal
  .command('order pizza [type] [otherThings...]', 'Orders a type of food.')
  .option('-s, --size <size>', 'Size of pizza.')
  .option('-a, --anchovies', 'Include anchovies.')
  .option('-p, --pineapple', 'Include pineapple.')
  .option('-o', 'Include olives.')
  .option('-d, --delivery', 'Pizza should be delivered')
  .action(function(args, cb){
    this.log(args);
    cb();
  });

Args would be returned as follows:

$myapp~$ order pizza pepperoni some other args -pod --size "medium" --no-anchovies
{
  "type": "pepperoni",
  "otherThings": ["some", "other", "args"]
  "options": {
    "pineapple": true,
    "o": true,
    "delivery": true,
    "anchovies": false,
    "size": "medium",
  }
}
CommandInstance

The this in a Vorpal action exposes a CommandInstance object with several methods. See CommandInstance section for more details.

.command.cancel(function)

Triggers a function if the user cancels mid the command using [control] + c.

vorpal
  .command('foo')
  .action(function(args, cb){
    // ... long, complicated action
  })
  .cancel(function () {
    this.log('Didn\'t mother teach you to be patient?');
    // ... cleanup code, as the
    // command was halted mid-cycle.
  });

Clone this wiki locally