npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

subcommand

v2.1.1

Published

create CLI tools with subcommands

Downloads

77,129

Readme

subcommand

Create CLI tools with subcommands. A minimalist CLI router based on minimist and cliclopts.

NPM

js-standard-style

Build Status

basic usage

first, define your CLI API in JSON like this:

var commands = [
  {
    name: 'foo',
    options: [ // cliclopts options
      {
        name: 'loud',
        boolean: true,
        default: false,
        abbr: 'v',
        help: 'print out all output loudly'
      }
    ],
    command: function foo (args) {
      // called when `foo` is matched
    }
  },
  {
    name: 'bar',
    command: function bar (args) {
      // called when `bar` is matched
    }
  }
]

then pass them into subcommand:

var subcommand = require('subcommand')
var match = subcommand(config, opts)

subcommand returns a function (called match above) that you can use to match/route arguments to their subcommands

the return value will be true if a subcommand was matched, or false if no subcommand was matched

var matched = match(['foo'])
// matched will be true, and foo's `command` function will be called

var matched = match(['foo', 'baz', 'taco'])
// matched will be true, and foo's `command` function will be called with `['baz', 'taco']`

var matched = match(['bar'])
// matched will be true, and bar's `command` function will be called

var matched = match(['uhoh'])
// matched will be false

advanced usage

instead of an array, you can also pass an object that looks like this as the first argument to subcommand:

{
  root: // root command options and handler
  defaults: // default options
  all: // function that gets called always, regardless of match or no match
  none: // function that gets called only when there is no matched subcommand
  usage: // subcommand to use for printing usage
  commands: // the commands array from basic usage
}

see test.js for a concrete example

root

to pass options to the 'root' command (e.g. when no subcommand is passed in), set up your config like this:

var config = {
  root: {
    options: [ // cliclopts options
      {
        name: 'loud',
        boolean: true,
        default: false,
        abbr: 'v'
      }
    ],
    command: function (args) {
      // called when no subcommand is specified
    }
  },
  commands: yourSubCommandsArray
}

defaults

you can pass in a defaults options array, and all subcommands as well as the root command will inherit the default options

var config = {
  defaults: [
    {name: 'path', default: process.cwd()} // all commands (and root) will now always have a 'path' default option
  ],
  commands: yourSubCommandsArray
}

all

pass a function under the all key and it will get called with the parsed arguments 100% of the time

var config = {
  all: function all (args) { /** will be called always in addition to the command/root `command` handlers **/ },
  commands: yourSubCommandsArray
}

none

pass a function under the none key and it will get called when no subcommand is matched

var config = {
  none: function none (args) { /** will only be called when no subcommand is matched **/ },
  commands: yourSubCommandsArray
}

usage

The usage option makes it easy to print cliclops usage for the root command and subcommands.

Basic usage

By default, usage is printed with the --help or -h option. Set usage to true to print cliclops.usage() with --help:

var config = {
  usage: true
}

Use usage.help to print information above cliclops.usage(). Change the name of the usage option by specifying usage.option:

var config = {
  usage: {
    help: 'general usage info',
    option: {
      name: 'info',
      abbr: 'i'
    }
  }
}

This will print the usage with --info or -i instead of --help. The option is used for the root and subcommands.

Advanced Usage

You can also define custom usage functions for the root and subcommands. These are passed the help text and cliclops.usage().

var config = {
  usage: {
    help: 'general help message', // Message to print before cliclops.usage()
    option: {
      // minimist option to use for printing usage
      name: 'help',
      abbr: 'h'
    },
    command: function (args, help, usage) {
      // optional function to print usage. 
      console.log(help) // prints: "general help message"
      console.log(usage) // prints: cliclops.usage() 
    }
  },
  commands: [{
    name: 'foo',
    help: 'foo help message',
    options: [
      {
        name: 'loud',
        help: 'print out all output loudly'
      }
    ],
    usage: function (args, help, usage) {
      // called when `foo` is matched and --help option is used
      console.log(help) // prints: "foo help message"
      console.log(usage) // prints: cliclops.usage()
    },
    command: function foo (args) {
      // called when `foo` is matched
    }
  }]
}