Command
Overview
Command is a powerful and flexible command-line interface (CLI) base built with TypeScript. It is built on top of the commander
library to provide a robust framework for creating and managing commands, options, and arguments. This application is designed to be highly customizable and extendable, making it suitable for a wide range of use cases.
Features
- Command Management: Easily create, configure, and manage commands with support for subcommands.
- Options and Arguments: Define and handle options and arguments with ease, including support for global options.
- Help System: Customizable help documentation for commands, options, and arguments.
- Colorized Output: Enhanced terminal output with color support using the
chalk
library. - Autocomplete: Built-in support for command and option autocompletion.
- Logging: Integrated logging with
pino
for detailed and configurable logging. - Error Handling: Robust error handling and reporting.
- Input/Output: Helpers for reading and printing to the console. Adhering to silent/no-interaction/no-color flags
Installation
To install Command, use the following command:
npm install @radicjs/command
Usage
Commands should be defined in the wrapper function run
which is exported by the package. The resulting function should be exported as the default export of the file.
import { run } from '@radicjs/command';
export default run(app =>
app.program
.name('foo')
.description('A test command')
.action(async function () {
this.out.t`{green All set!}`
this.log.debug('All these work out of the box');
}),
);
Default Global Options
By default, the following global options are available:
-h, --help
: Display help for command.--log-level <level>
: Set log level (default:warn
).-v, --verbose
: Enables verbose output.--debug
: Enable debugging output.--no-interaction
: No interaction.--silent
: Disable output.--no-color
: Disable color output.
Custom global options
Create a new file run.ts
, wich will then serve as the wrapper for your commands.
import { run as _run, gopts } from '../src';
export const run: typeof _run = (...args) => {
// either clear all options
gopts.clearOptions();
// or remove some options
gopts.removeOption('help');
// then add some options. the GlobalOptionsCommand has this helper method to add the global options
gopts.add('-v, --version','output the version number',false).conflicts('V');
return _run(...args)
}
Help improvements
command.configureHelp({
// enabled by default. Must be set to true for the options below to take effect
// when set to true, the help output will be improved.
// you can also sort / disable sections
useImprovedHelp: true,
// default values, lower values are shown first. Set value to false to omit from help
outputOrder: {
'Usage' : 10,
'CommandDescription': 20,
'CommandsList' : 30,
'ArgumentsList' : 40,
'OptionsList' : 50,
'GlobalOptionsList' : 60,
},
// when using a lot of options, it can be helpful to seperate them by newlines.
// This is disabled by default
seperateGlobalOptionsByNewLine: true,
seperateOptionsByNewLine : true,
});
The improved help looks like this (plus some coloring):
-h, --help display help for command [default: false]
--log-level <level> set log level [allowed: 'trace'|'debug'|'info'|'warn'|'error'|'fatal'] [default: 'warn']
-v, --verbose enables verbose output [default: false]
--debug enable debugging output [default: false] [env: DEBUG]
--no-interaction no interaction
--silent disable output [default: false]
--no-color disable color output [env: NO_COLOR]
--json show json output [default: true]
Input/Output
- The
Command
package provides a number of helper functions for reading and printing to the console. These helpers are designed to be used in conjunction with theCommand
class to provide a consistent and easy-to-use interface for interacting with the terminal. - They also adhere to the
silent
,no-interaction
, andno-color
flags to provide a consistent user experience across different environments. - They are accessible through the
in
andout
property on theCommand
instance and theApplication
object - The
in
andout
properties are instances of theInput
andOutput
classes, respectively, which provide a number of methods for interacting with the terminal. - The
Input
andOutput
class are macroable, meaning you can add your own methods to them to extend their functionality.
The input questions are powered by the
inquirer
library.
Input Definitions:
command.action(async function () {
await this.in.checkbox({ message: '' /* ...options */ });
await this.in.confirm({ message: '' /* ...options */ });
await this.in.number({ message: '' /* ...options */ });
await this.in.input({ message: '' /* ...options */ });
await this.in.editor({ message: '' /* ...options */ });
await this.in.search({ message: '' /* ...options */ });
await this.in.password({ message: '' /* ...options */ });
await this.in.expand({ message: '' /* ...options */ });
await this.in.select({ message: '' /* ...options */ });
await this.in.rawlist({ message: '' /* ...options */ });
});
Macroable: Both the Input
and Output
classes are macroable, meaning you can add your own methods to them to extend their functionality.
this.in.macro('myMethod', function (arg1, arg2) {
// your custom method here
});
this.in.myMethod('arg1', 'arg2');
Augmenting: You can also augment the Input
and Output
classes with additional methods.
import { Input } from '@radicjs/command';
declare module '@radicjs/command' {
interface Input {
myMethod(arg1: string, arg2: string): Promise<string>;
}
}
Tab completion
@todo write docs
Examples
Can be found in the example directory for more examples.
Contributing
Contributions are welcome! Please read the contributing guidelines for more information.
License
This project is licensed under the MIT License. See the LICENSE file for details.