Skip to content

northern/cli

Repository files navigation

@northern/cli

A lightweight, typed CLI program framework for building command-driven tools with consistent help output and parameter parsing.

Feature overview

  • Typed program model with Program, Command, Argument, and Option definitions.
  • Built-in parsing for required arguments and optional flags.
  • Three parameter modes: value, switch, and enum.
  • Automatic help output for global and command-specific options.
  • Validation and errors via ParameterError when arguments are invalid or duplicated.
  • Pluggable console powered by @northern/console for consistent styled output.

Install

npm install @northern/cli

Example

Run the included example:

npm run example -- greet --name "Freddy Krueger"

Note: The first -- is to indicate that what follows are parameters for the command being executed, not parameters for npm run.

We can also turn off color output by adding the --nocolor parameter:

npm run example -- greet --name "Freddy Krueger" --nocolor

How to use

1) Define your program

import { Interpreter, ParameterType, Program } from '@northern/cli';

const program: Program = {
	title: 'Acme Tool',
	version: '1.2.3',
	name: 'acme',
	options: [
		{
			name: 'verbose',
			description: 'Enable verbose output',
			type: ParameterType.SWITCH,
			directives: ['-v', '--verbose'],
			example: '--verbose',
			default: false,
		},
	],
	commands: [
		{
			name: 'build',
			description: 'Build the project',
			arguments: [
				{
					name: 'source',
					description: 'Source file',
					type: ParameterType.VALUE,
					directives: ['-s', '--source'],
					example: '--source ./app.yaml',
				},
			],
			options: [
				{
					name: 'mode',
					description: 'Build mode',
					type: ParameterType.ENUM,
					directives: ['-m', '--mode'],
					example: '--mode production',
					values: ['development', 'production'],
					default: 'development',
				},
			],
		},
	],
};

2) Parse arguments and execute

const interpreter = new Interpreter(program, process.argv.slice(2));

if (!interpreter.init()) {
	process.exit(1);
}

const command = interpreter.getCommand();
if (!command) {
	interpreter.displayHelp(process.argv[2]);
	process.exit(1);
}

const params = interpreter.getParameters(command);
if (!params) {
	interpreter.displayCommandHelp(command);
	process.exit(1);
}

const globalOptions = interpreter.getGlobalOptions() ?? {};

// Execute your command using parsed values
// e.g. runBuild(params, globalOptions)

3) What parsing does

  • Required arguments must be present or getParameters() returns null.
  • Options default to their default value when not specified.
  • Switch options (ParameterType.SWITCH) resolve to true if present.
  • Enum options (ParameterType.ENUM) must match one of the configured values.
  • Duplicate directives (e.g. --verbose --verbose) trigger a parse error.

Reference documentation

Types

ParameterType

  • ParameterType.VALUE — a directive that requires a value (e.g. --config path).
  • ParameterType.SWITCH — a boolean flag (e.g. --verbose).
  • ParameterType.ENUM — a directive that accepts one of a predefined set of values.

Argument

Required parameter definition:

Field Type Description
name string Internal key used in parsed output.
description string Human-readable help text.
type ParameterType Parameter type.
directives string[] Accepted flags (e.g. ['-s', '--source']).
example string Example usage shown in help.
values? string[] Allowed values for ENUM parameters.

Option

Optional parameter definition. Same as Argument plus:

Field Type Description
default unknown Default value when option is omitted.

Command

Field Type Description
name string Command name (e.g. build).
description string Help summary.
arguments? Argument[] Required parameters.
options? Option[] Command-specific options.

Program

Field Type Description
title string Display title shown in the banner.
version string Version string.
name string Executable name for usage output.
options Option[] Global options.
commands Command[] Available commands.

Parameters

Record<string, unknown> containing parsed values keyed by Argument/Option name.

ICommand

interface ICommand {
	run(parameters: Parameters): Promise<unknown>
}

Use this to define an execution contract for command handlers.

Errors

ParameterError

Thrown internally when parsing fails (missing values, invalid enums, duplicate directives). The interpreter returns null from getParameters()/getGlobalOptions() to preserve backward compatibility.

Interpreter

Constructor

new Interpreter(program: Program, args: string[], console?: Console)
new Interpreter(program: Program, console?: Console, args?: string[])

Creates a parser instance. You can pass args (typically process.argv.slice(2)) and/or a custom console. Both argument orders are supported for backward compatibility.

init()

init(): boolean

Displays general help when no arguments are provided and returns false.

getCommand()

getCommand(): Command | null

Returns the command matching the first argument (case-insensitive), or null.

getBanner()

getBanner(): string

Returns a formatted banner string with title and version.

displayHelp(command?: string)

Displays general help and optionally an “unknown command” message.

displayCommandHelp(command: Command)

Shows command-specific usage, required arguments, options, and global options.

getParameters(command: Command)

getParameters(command: Command): Parameters | null

Parses required arguments and command options. Returns null on validation failure.

getGlobalOptions()

getGlobalOptions(): Parameters | null

Parses global options only. Returns null on validation failure.

setConsole(console: Console)

Replaces the internal console instance (useful for testing).

getConsole()

getConsole(): Console

Returns the current console instance (useful for testing).

About

Build Command Line Interface programs with TypeScript

Resources

License

Stars

Watchers

Forks

Packages

No packages published