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

console-commando

v7.0.1

Published

A tool for creating console commands

Downloads

28

Readme

Console Commando

Actions Status Typedoc

A library for creating command line tools with node.

Installation:

npm install --save console-commando

Why you want to use this

console-commando allows you to easily create complex command line utilities in a simple, type-safe, testable, modular way.

Creating both simple and complex commands becomes a trivial task.

This library provides a very simple way of creating all kinds of commands, from simple CLI tools with a few options, to semantic CLIs with several levels of nesting.

With console-commando you can create cli utilities that make sense very easily. The following for example would be trivial to set up:

mycommand my-resource my-action --an-option --another=option and arbitrary arguments

console-commando also produces easy to read help automatically as well as bash completion for sub commands.

Additionally, everything in console-commando is type-safe, functional and immutable, reducing ambiguity and the need for new or this.

Usage

Key concepts

Command

The core of console-commando is the Command object. A helper function command() is provided to easily create new Command objects.

import { command } from "console-commando";

const myCommand = command("a-name");
// Returns a new Command with the specified name.

Options and Arguments

An Option is a flag that can be passed to the command and will modify the execution behavior. Options are prefixed with -- (long option) or - (short option).

There are several types of options and corresponding helper functions to add them to a command.

Examples of options could be: -h, --help, --flag=value, or --flag value.

An Argument is similar to an option, but instead of being specified by name, the value is passed to the command positionally.

For example in the following command invocation:

command -f --f2=val --f3 1 arg1 arg2
  • -f is a boolean option (short) set to true by being present in the invocation.
  • --f2 is a string option (long), it's value is set to "val"
  • --f3 is a numeric option (long) set to 1
  • arg1 and arg2 are positional arguments (only the values are used).

Example: Simple Command

You can create simple commands very easily. Just provide a few settings and an action. The action will be called with any options passed in the command-line.

// Using CommonJS modules
import { command, stringOption, numericOption, flag } from "console-commando";

// Create a new command, with name, version and description.
command("command-name")
  // since everything is immutable, each "with" function returns a new Command
  // with the specified value set.
  .withVersion("1.0.1")
  .withDescription("")

  // Add global options.
  // -h or --host, with description and default value
  .withOption(stringOption("host", "h", "Host name", "localhost"))
  // Options are strictly typed.
  .withOption(numericOption("port", "p", "Port number", 8080))
  // Flags have no value parameter, they are set to true if present.
  .withOption(flag("debug", "d", "Enable debugging"))

  // A handler is the function that gets called if this command is invoked.
  .withHandler((cmd, state) => {
    console.log(JSON.stringify(state));
  })

  // Pass arguments to the command and run it.
  .withRuntimeArgs()
  .run();

Subcommands

You can add subcommands to your command any time by using the command method:

// Using node's require
import { commando, flag, stringOption } from "console-commando";

// Create a new command, with name, version and description.
command("command-name")
  .withVersion("1.0.1")
  .withDescription("")

  // Add global options.
  .withOption(flag("verbose", "-v", "Log more output", true))

  // Act on global options, before any sub commands are executed.
  // State is immutable yet a preprocessor can return a new state that will be
  // passed to later preprocessors and to the invoked handler.
  .withPreProcessor((_, state) => state.set("runtime", "state"));
)

  // Add a subcommand.
  .withSubCommand(
    // Sub commands are also commands.
    command("subcommand")
      // You can add options.
      .withOption(stringOption("sub-option", "s", "An option for the subcommand"))
      // Define an action for this sub command.
      .withHandler((command, state) => {
        // Get options for this command.
        const subOption = command.getStringOption("subOption");
        // Or get global options for the root command.
        const verbose = command.getFlag("verbose");
      })

      // And you can add sub commands to sub commands too.
      //.withSubCommand(...)
      // ...
      // and so on, and so forth
      (),
  )

  // Pass arguments to the command and run it.
  .withRuntimeArgs()
  .run();

CLI auto completion

Similarly to npm completion, console-commando makes it easy to get auto completion for your commands.

Simply run the following in your terminal:

source <(your-command completion)

Note that this assumes the command has been installed as an executable command with the name specified in the root command.

After doing this you should be able to auto complete your command, subcommands and options when hitting the tab key twice.

API

Console commando's public API is a series of pure functions that produce immutable intermediate Command objects. Command objects are are immutable, via immutable.js.

Read the API Documentation

Defining the Command

The Command interface defines the main functionality of console-commando programs.

command(): Command factory

command(name);

Creates a new Command with a given name.

withVersion: (version: string) => Command

command(name).withVersion("1.0.0");

Returns a copy of the Command with the given version string.

withDescription: (description: string) => Command

command(name).withDescription("some text");

Returns a copy of the Command with the given description string.

withOption: (definition: Option) => Command

Returns a copy of the Command with the given option.

withArgument: (definition: Argument) => Command

Returns a copy of the Command with the given argument.

withSubCommand: (subCommand: Command) => Command

Returns a Command with a new subcommand attached to it.

withHandler: (fn: Handler) => Command

Returns a command with the given action handler. This is the function that will be called when this command or subcommand is invoked.

The action can return a value of ReturnValue.SUCCESS or ReturnValue.FAILURE to indicate the exit status.

withPreProcessor: (fn: PreProcessor) => Command

Returns a new Command with the given pre-processor. This function will be executed before any handlers and can be used to mutate the global state.

getFlag: (name: string) => boolean

When used within a handler, it returns the value of a boolean option.

getStringOption: (name: string) => string | undefined

When used within a handler, it returns the value of a string option.

getNumericOption: (name: string) => number | undefined

When used within a handler, it returns the value of a numeric option.

getMultiStringOption: (name: string) => string[]

When used within a handler, it returns the value of a multi-string option.

getStringArg: (name: string) => string | undefined

When used within a handler, it returns the value of a string argument.

getNumericArg: (name: string) => number | undefined

When used within a handler, it returns the value of a numeric argument.

getMultiStringArg: (name: string) => string[]

When used within a handler, it returns the value of a multi-string argument.

Running the command

withRuntimeArgs: (args?: string[], parsed?: ParsedRuntimeArgs) => Command

Adds runtime arguments to the command. If invoked without arguments it will default to process.argv.slice(2), i.e. the command line arguments after the command name.

run: (state?: RuntimeState) => Promise<ReturnValue>

Runs the command. Required for anything to happen.

Contributing

I would love to hear from anyone using this library, and if there's anything that you thing may improve it, please add an issue in github!

I'd also welcome any pull requests, although I'd suggest that you create an issue first to start the discussion.

The main points of improvement at the moment are:

  • better test case coverage.
  • documentation improvements.
  • stronger option parsing and validation.
  • option to override help text.
  • and any issues/bugs that are still open in github.