Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bandersnatch

Package Overview
Dependencies
Maintainers
1
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bandersnatch - npm Package Compare versions

Comparing version 1.0.0-alpha.4 to 1.0.0-alpha.5

27

lib/command.d.ts

@@ -18,10 +18,24 @@ import { Argv, Arguments as BaseArguments } from 'yargs';

constructor(command?: string | string[] | undefined, description?: string | undefined);
/**
* Adds a new positional argument to the command.
* This is shorthand for .add(argument(...))
*/
argument<K extends string, O extends ArgumentOptions>(name: K, descriptionOrOptions?: string | O, options?: O): Command<T & { [key in K]: InferArgType<O, string>; }>;
/**
* Adds a new option to the command.
* This is shorthand for .add(option(...))
*/
option<K extends string, O extends OptionOptions>(name: K, descriptionOrOptions?: string | O, options?: O): Command<T & { [key in K]: InferArgType<O, unknown>; }>;
/**
* This is the base method for adding arguments and options, but it doesn't provide
* type hints. Use .argument() and .option() instead.
* This is the base method for adding arguments, options and commands, but it
* doesn't provide type hints. Use .argument() and .option() instead.
*/
add(obj: Argument | Option | Command): this;
/**
* Mark as the default command.
*/
default(): this;
/**
* Provide a function to execute when this command is invoked.
*/
action(fn: HandlerFn<T>): this;

@@ -31,3 +45,2 @@ private getArguments;

private getCommands;
private toModule;
/**

@@ -38,2 +51,3 @@ * Calls the command() method on the passed in yargs instance and returns it.

toYargs(yargs: Argv): Argv<T>;
private toModule;
/**

@@ -49,5 +63,10 @@ * Returns a formatted command which can be used in the command() function

/**
* Returns the command handler
* Wraps the actual command handler to insert prompt and async handler logic.
*/
private getHandler;
/**
* Returns an array of arguments and options which should be prompted, because
* they are promptable (isPromptable() returned true) and they are not
* provided in the args passed in to this function.
*/
private getQuestions;

@@ -54,0 +73,0 @@ /**

40

lib/command.js

@@ -42,3 +42,4 @@ "use strict";

}
/*
/**
* Adds a new positional argument to the command.
* This is shorthand for .add(argument(...))

@@ -55,3 +56,4 @@ */

}
/*
/**
* Adds a new option to the command.
* This is shorthand for .add(option(...))

@@ -69,4 +71,4 @@ */

/**
* This is the base method for adding arguments and options, but it doesn't provide
* type hints. Use .argument() and .option() instead.
* This is the base method for adding arguments, options and commands, but it
* doesn't provide type hints. Use .argument() and .option() instead.
*/

@@ -95,2 +97,5 @@ add(obj) {

}
/**
* Mark as the default command.
*/
default() {

@@ -100,2 +105,5 @@ this.command = '$0';

}
/**
* Provide a function to execute when this command is invoked.
*/
action(fn) {

@@ -114,2 +122,9 @@ this.handler = fn;

}
/**
* Calls the command() method on the passed in yargs instance and returns it.
* See https://github.com/yargs/yargs/blob/master/docs/advanced.md#providing-a-command-module
*/
toYargs(yargs) {
return yargs.command(this.toModule());
}
toModule() {

@@ -126,9 +141,2 @@ const module = {

/**
* Calls the command() method on the passed in yargs instance and returns it.
* See https://github.com/yargs/yargs/blob/master/docs/advanced.md#providing-a-command-module
*/
toYargs(yargs) {
return yargs.command(this.toModule());
}
/**
* Returns a formatted command which can be used in the command() function

@@ -164,3 +172,3 @@ * of yargs.

/**
* Returns the command handler
* Wraps the actual command handler to insert prompt and async handler logic.
*/

@@ -176,2 +184,4 @@ getHandler() {

chain = chain.then(async (args) => {
// @todo check if command has sub-commands, and if so, do not throw an
// error but maybe show help instead?
if (!this.handler) {

@@ -188,2 +198,7 @@ throw new Error('No handler defined for this command.');

}
/**
* Returns an array of arguments and options which should be prompted, because
* they are promptable (isPromptable() returned true) and they are not
* provided in the args passed in to this function.
*/
getQuestions(args) {

@@ -194,2 +209,3 @@ // If we need to prompt for things, fill questions array

const presentInArgs = Object.constructor.hasOwnProperty.call(args, name);
// @todo How can we force prompting when default was used?
if (!presentInArgs && arg.isPromptable()) {

@@ -196,0 +212,0 @@ questions.push({

@@ -5,6 +5,4 @@ export * from './argument';

export * from './option';
export * from './printer';
export * from './program';
export * from './repl';
export * from './runner';
export * from './utils';

@@ -10,6 +10,4 @@ "use strict";

__export(require("./option"));
__export(require("./printer"));
__export(require("./program"));
__export(require("./repl"));
__export(require("./runner"));
__export(require("./utils"));
import { Argv } from 'yargs';
import { Command } from './command';
import { Arguments } from './command';
import { Runner } from './runner';
declare type FailFn = (msg: string, err: Error, args: Arguments, usage?: string) => void;
import { Repl } from './repl';
declare type ProgramOptions = {
/**
* Whether or not to add a global help command that displays an overview of
* commands. Can also be enabled by calling `program().withHelp()`.
*
* Defaults to `false`.
*/
help?: boolean;
/**
* Whether or not to add a global version command that displays the version as
* specified in the package.json file. Can also be enabled by calling
* `program().withVersion()`.
*
* Defaults to `false`.
*/
version?: boolean;
fail?: FailFn;
/**
* Sets a custom REPL prompt.
*
* Defaults to `>`.
*/
prompt?: string;
exitOnError?: boolean;
};
/**
* Creates a new bandersnatch program.
*/
export declare function program(description?: string, options?: ProgramOptions): Program;

@@ -19,29 +36,52 @@ export declare class Program {

private replInstance?;
private runnerInstance?;
constructor(description?: string | undefined, options?: ProgramOptions);
/**
* Create a new yargs instance. Not intended for public use.
* Create a new yargs instance. This method may change at any time, not
* intended for public use.
*
* @private
*/
createYargsInstance(): Argv<{}>;
/**
* Adds a new command to the program.
*/
add<T>(command: Command<T>): this;
/**
* Adds a new command to the program and marks it as the default command.
*/
default<T>(command: Command<T>): this;
prompt(prompt: string): this;
/**
* Adds a global help command that displays an overview of commands.
*/
withHelp(): this;
/**
* Adds a global version command that displays the version as specified in the
* package.json file.
*/
withVersion(): this;
fail(fn: FailFn): this;
/**
* Evaluate command (or process.argv) and return runner instance.
* Sets a custom REPL prompt.
*/
eval(command?: string | ReadonlyArray<string>): Runner<unknown>;
prompt(prompt: string): this;
/**
* Run a command (or process.argv) and print output.
* Evaluate command (or process.argv) and return promise.
*/
run(command?: string | ReadonlyArray<string>): Runner<unknown>;
run(command?: string | ReadonlyArray<string>): Promise<unknown>;
/**
* Run event loop which reads command from stdin.
*/
repl(): void;
repl(): Repl;
/**
* When argv is set, run the program, otherwise start repl loop.
*/
runOrRepl(): Promise<unknown> | Repl;
/**
* Method to execute when a failure occurs, rather than printing the failure
* message.
*
* Called with the failure message that would have been printed, the Error
* instance originally thrown and yargs state when the failure occured.
*/
private failHandler;
private defaultFailFn;
}
export {};

@@ -7,7 +7,8 @@ "use strict";

const yargs_1 = __importDefault(require("yargs/yargs"));
const ansi_colors_1 = require("ansi-colors");
const command_1 = require("./command");
const repl_1 = require("./repl");
const utils_1 = require("./utils");
const runner_1 = require("./runner");
/**
* Creates a new bandersnatch program.
*/
function program(description, options = {}) {

@@ -17,2 +18,5 @@ return new Program(description, options);

exports.program = program;
function extractCommandFromProcess() {
return process.argv.slice(2);
}
class Program {

@@ -23,15 +27,8 @@ constructor(description, options = {}) {

this.commands = [];
this.defaultFailFn = (msg, err, args, usage) => {
if (msg) {
console.error(ansi_colors_1.yellow(msg));
}
if (usage) {
console.error('');
console.error(usage);
}
process.exit(1);
};
}
/**
* Create a new yargs instance. Not intended for public use.
* Create a new yargs instance. This method may change at any time, not
* intended for public use.
*
* @private
*/

@@ -52,8 +49,7 @@ createYargsInstance() {

// Custom fail function.
// TODO current yargs types doesn't include the third parameter.
yargs.fail(this.failHandler.bind(this));
// Exit on errors?
yargs.exitProcess(!!this.options.exitOnError);
// In case we're in a REPL session, do not exit on errors.
yargs.exitProcess(!this.replInstance);
// Add commands
this.commands.forEach(command => {
this.commands.forEach((command) => {
command.toYargs(yargs);

@@ -63,2 +59,5 @@ });

}
/**
* Adds a new command to the program.
*/
add(command) {

@@ -68,2 +67,5 @@ this.commands.push(command);

}
/**
* Adds a new command to the program and marks it as the default command.
*/
default(command) {

@@ -73,6 +75,5 @@ this.commands.push(command.default());

}
prompt(prompt) {
this.options.prompt = prompt;
return this;
}
/**
* Adds a global help command that displays an overview of commands.
*/
withHelp() {

@@ -82,2 +83,6 @@ this.options.help = true;

}
/**
* Adds a global version command that displays the version as specified in the
* package.json file.
*/
withVersion() {

@@ -87,20 +92,35 @@ this.options.version = true;

}
fail(fn) {
this.options.fail = fn;
/**
* Sets a custom REPL prompt.
*/
prompt(prompt) {
this.options.prompt = prompt;
return this;
}
/**
* Evaluate command (or process.argv) and return runner instance.
* Evaluate command (or process.argv) and return promise.
*/
eval(command) {
const cmd = command || process.argv.slice(2);
// Set executor to promise resolving to the return value of the command
run(command) {
const cmd = command || extractCommandFromProcess();
// Return promise resolving to the return value of the command
// handler.
this.runnerInstance = runner_1.runner((resolve, reject) => {
return new Promise((resolve, reject) => {
this.createYargsInstance().parse(cmd, {}, (err, argv, output) => {
// Output is a string for built-in commands like --version and --help
/**
* From the yargs docs:
* > any text that would have been output by yargs to the terminal,
* > had a callback not been provided.
* http://yargs.js.org/docs/#api-parseargs-context-parsecallback
*
* Seems that this is primarily used for built-in commands like
* --version and --help.
*/
if (output) {
console.log(output);
}
// TODO when is err defined?
/**
* From the yargs docs:
* > Populated if any validation errors raised while parsing.
* http://yargs.js.org/docs/#api-parseargs-context-parsecallback
*/
if (err) {

@@ -120,11 +140,4 @@ console.error(err);

});
return this.runnerInstance.eval();
}
/**
* Run a command (or process.argv) and print output.
*/
run(command) {
return this.eval(command).print();
}
/**
* Run event loop which reads command from stdin.

@@ -134,4 +147,2 @@ */

this.replInstance = repl_1.repl(this, this.options.prompt);
// Don't exit on errors.
this.options.exitOnError = false;
// Add exit command

@@ -142,32 +153,36 @@ this.add(command_1.command('exit', 'Exit the application').action(() => {

this.replInstance.start();
return this.replInstance;
}
/**
* When argv is set, run the program, otherwise start repl loop.
*/
runOrRepl() {
return extractCommandFromProcess().length ? this.run() : this.repl();
}
/**
* Method to execute when a failure occurs, rather than printing the failure
* message.
*
* Called with the failure message that would have been printed, the Error
* instance originally thrown and yargs state when the failure occured.
*/
failHandler(msg, err, yargs) {
// TODO needs more use-cases: only do something when msg is set, and have
// errors always handled in the runner?
if (this.replInstance) {
// In case we're in a REPL session, forward the message which may
// originate from yargs. Errors are handled in the runner.
msg && this.replInstance.setError(msg);
if (msg) {
// If msg is set, it's probably a validation error from yargs we want to
// print.
console.error(msg);
if (this.replInstance) {
// In case we're in a REPL session, indicate we printed a message, so we
// can prevent the program resolve handler to execute.
this.replInstance.gotYargsMsg();
}
else {
// In other cases, exit with status of 1.
process.exit(1);
}
}
else {
const args = yargs.argv;
const usage = yargs.help();
const cb = () => {
if (this.options.fail) {
// Call custom fail function.
this.options.fail(msg, err, args, usage);
}
else {
// Call default fail function.
this.defaultFailFn(msg, err, args, usage);
}
};
// We call the fail function in the runner chain if available, to give
// async printer a chance to complete first.
this.runnerInstance
? this.runnerInstance.then(cb)
: Promise.resolve().then(cb);
}
}
}
exports.Program = Program;

@@ -7,9 +7,30 @@ import { Program } from './program';

private server?;
private lastError;
private autocompleter;
private receivedYargsMsg;
private successHandler;
private errorHandler;
constructor(program: Program, prompt?: string);
/**
* @todo Add meaningful comments here.
*/
start(): Promise<void>;
setError(err: string): void;
gotYargsMsg(): void;
/**
* Emulates promise.then, but saves the callback instead to be executed on
* each command which resolves.
*/
then(cb: (value?: unknown) => void): this;
/**
* Emulates promise.catch, but saves the callback instead to be executed on
* each command which rejects.
*/
catch(cb: (reason?: any) => void): this;
/**
* @todo Add meaningful comments here.
*/
private completer;
/**
* @todo Add meaningful comments here.
*/
private eval;
}

@@ -8,3 +8,2 @@ "use strict";

const string_argv_1 = require("string-argv");
const ansi_colors_1 = require("ansi-colors");
const autocompleter_1 = require("./autocompleter");

@@ -19,5 +18,10 @@ function repl(program, prefix = '> ') {

this.prompt = prompt;
this.lastError = null;
this.receivedYargsMsg = false;
this.successHandler = () => { };
this.errorHandler = (reason) => console.error(reason);
this.autocompleter = autocompleter_1.autocompleter(program);
}
/**
* @todo Add meaningful comments here.
*/
async start() {

@@ -28,27 +32,57 @@ this.server = repl_1.default.start({

completer: this.completer.bind(this),
ignoreUndefined: true
ignoreUndefined: true,
});
}
setError(err) {
this.lastError = err;
gotYargsMsg() {
this.receivedYargsMsg = true;
}
/**
* Emulates promise.then, but saves the callback instead to be executed on
* each command which resolves.
*/
then(cb) {
this.successHandler = cb;
return this;
}
/**
* Emulates promise.catch, but saves the callback instead to be executed on
* each command which rejects.
*/
catch(cb) {
this.errorHandler = cb;
return this;
}
/**
* @todo Add meaningful comments here.
*/
async completer(line, cb) {
function addSpace(str) {
return `${str} `;
}
const argv = string_argv_1.parseArgsStringToArgv(line);
const current = argv.slice(-1).toString();
const completions = await this.autocompleter.completions(argv);
let hits = completions.filter(completion => completion.startsWith(current));
// Add trailing space to each hit
hits = hits.map(hit => `${hit} `);
const completions = (await this.autocompleter.completions(argv)).map(addSpace);
let hits = completions.filter((completion) => completion.startsWith(current));
// Show all completions if none found
cb(null, [hits.length ? hits : completions, current]);
}
/**
* @todo Add meaningful comments here.
*/
async eval(line, context, file, cb) {
this.lastError = null;
const result = await this.program.run(line.trim());
if (this.lastError) {
console.error(ansi_colors_1.red(this.lastError));
this.receivedYargsMsg = false;
try {
const result = await this.program.run(line.trim());
// Execute success handler only if we have not received a msg from yargs,
// which was probably a validation error.
this.receivedYargsMsg || this.successHandler(result);
}
cb(null, result);
catch (error) {
this.errorHandler(error);
}
// The result passed to this function is printed by the Node REPL server,
// but we don't want to use that, so we pass undefined instead.
cb(null, undefined);
}
}
exports.Repl = Repl;
{
"name": "bandersnatch",
"description": "",
"version": "1.0.0-alpha.4",
"version": "1.0.0-alpha.5",
"main": "lib/index.js",

@@ -14,3 +14,5 @@ "files": [

"test": "jest",
"start": "ts-node"
"start": "ts-node",
"doc:toc": "doctoc README.md",
"doc:todos": "leasot --exit-nicely --reporter markdown \"src/**/*.ts\" > TODO.md"
},

@@ -20,27 +22,27 @@ "author": "",

"dependencies": {
"@types/inquirer": "^6.5.0",
"@types/yargs": "^13.0.3",
"ansi-colors": "^4.1.1",
"inquirer": "^7.0.0",
"string-argv": "^0.3.1",
"yargs": "^15.0.2"
"@types/inquirer": "6.5.0",
"@types/yargs": "15.0.4",
"inquirer": "7.1.0",
"string-argv": "0.3.1",
"yargs": "15.3.1"
},
"devDependencies": {
"@types/jest": "^24.0.23",
"@types/node": "^12.12.17",
"doctoc": "^1.4.0",
"husky": "^3.1.0",
"jest": "^24.9.0",
"mock-argv": "^1.1.2",
"prettier": "^1.19.1",
"promise.prototype.finally": "^3.1.2",
"ts-jest": "^24.2.0",
"ts-node": "^8.5.4",
"typescript": "^3.7.3"
"@types/jest": "25.2.1",
"@types/node": "12.12.35",
"doctoc": "1.4.0",
"husky": "4.2.5",
"jest": "26.0.1",
"leasot": "10.3.0",
"mock-argv": "1.1.6",
"prettier": "2.0.5",
"promise.prototype.finally": "3.1.2",
"ts-jest": "25.5.0",
"ts-node": "8.10.1",
"typescript": "3.8.3"
},
"husky": {
"hooks": {
"pre-commit": "yarn doctoc . && git add README.md"
"pre-commit": "yarn doc:toc && yarn doc:todos"
}
}
}

@@ -15,14 +15,14 @@ # bandersnatch

- ➰ Built-in REPL
- 🌊 [Fluid](https://www.martinfowler.com/bliki/FluentInterface.html) syntax
- ➰ Built-in [REPL](https://en.wikipedia.org/wiki/Read–eval–print_loop)
- 💬 Prompts for missing arguments
- ➡ Autocompletes arguments, options and values
- 🤯 Fully typed
- ⚡ Uses the power of `yargs` & `inquirer`
- ⚡ Uses the power of `yargs` and `inquirer`
It's built in TypeScript and while it's of course possible to write your app
with JavaScript, you're missing out on some very handy type hints.
It's built-in TypeScript to provide you with some very handy type hints.
We don't have a generator, auto-updater and we don't make any decisions for you
(apart from using inquirer for prompts). This makes bandersnatch pretty easy and
intuitive to work with.
Bandersnatch is not designed to be used as a full CLI framework like oclif,
and tries to minimize the assumptions made about your program to make
bandersnatch easy and intuitive to work with.

@@ -34,3 +34,2 @@ ## Table of contents

- [Getting started](#getting-started)

@@ -41,2 +40,4 @@ - [Installation](#installation)

- [Prompt](#prompt)
- [Principles](#principles)
- [Output](#output)
- [API](#api)

@@ -49,6 +50,5 @@ - [`program(description)`](#programdescription)

- [`program.withVersion()`](#programwithversion)
- [`program.fail(function)`](#programfailfunction)
- [`program.eval(command)`](#programevalcommand)
- [`program.run(command)`](#programruncommand)
- [`program.repl()`](#programrepl)
- [`program.runOrRepl()`](#programrunorrepl)
- [`command(name, description)`](#commandname-description)

@@ -60,10 +60,2 @@ - [`command.argument(name, description, options)`](#commandargumentname-description-options)

- [`command.action(function)`](#commandactionfunction)
- [`runner`](#runner)
- [`runner.print(printer)`](#runnerprintprinter)
- [`runner.then(function)`](#runnerthenfunction)
- [`runner.catch(function)`](#runnercatchfunction)
- [`runner.print(printer)`](#runnerprintprinter-1)
- [`printer`](#printer)
- [`printer.write(string)`](#printerwritestring)
- [`printer.error(Error)`](#printererrorerror)
- [Bundle](#bundle)

@@ -87,3 +79,3 @@ - [Todo](#todo)

Now create a simple app `echo.ts`:
Now create a simple app `concat.ts`:

@@ -93,9 +85,7 @@ ```ts

const echo = command('echo', 'Echo something in the terminal')
.argument('words', 'Say some kind words', { variadic: true })
.action(args => args.words.map(word => `${word}!`).join(' '))
const concat = command('concat', 'Concatenate input')
.argument('input', 'List of inputs to concatenate', { variadic: true })
.action((args) => console.log(args.input.join(', '))
program()
.default(echo)
.run()
program().default(concat).run()
```

@@ -106,4 +96,4 @@

```bash
$ ts-node echo.ts Hello world
Hello! world!
$ ts-node concat.ts Hello world
Hello, world
```

@@ -126,3 +116,3 @@

.option('color', 'Enables colorized output', { type: 'boolean' })
.action(async args => {
.action(async (args) => {
const json = JSON.parse(args.json)

@@ -135,3 +125,3 @@ args.color

process.argv.slice(2).length ? app.run() : app.repl()
app.runOrRepl()
```

@@ -166,12 +156,12 @@

.argument('name', "What's your name?", {
prompt: true
prompt: true,
})
.argument('question', "What's your question?", {
prompt: true
prompt: true,
})
.action(args => `Hi ${args.name}, the answer to "${args.question}" is 42.`)
.action((args) => {
console.log(`Hi ${args.name}, the answer to "${args.question}" is 42.`)
})
program('Ask me anything')
.default(cmd)
.run()
program('Ask me anything').default(cmd).run()
```

@@ -183,4 +173,4 @@

$ ts-node ama.ts --name Joram
? What's your question? What is everything in ASCII?
Hi Joram, the answer to "What is everything in ASCII?" is 42.
? What's your question? What is the meaning of life?
Hi Joram, the answer to "What is the meaning of life?" is 42.
```

@@ -194,2 +184,22 @@

## Principles
In general, bandersnatch is designed to create [twelve-factor apps](https://12factor.net/).
### Output
Programs are encouraged to use the following conventions with regards to output,
based on the [POSIX standard](https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html).
- When a program is designed to be used in a scripting environment and its
output should be available as stdin for other programs, use stdout for
printing output and stderr for diagnostic output (e.g. progress and/or error
messages).
- When a program is designed to be used as a service (twelve-factor app), use
stdout/stderr as a logging mechanism for informative messages/error and
diagnostic messages.
Bandersnatch has no built-in method for writing to stdout/stderr. Node.js
provides [everything you need](https://nodejs.org/api/console.html).
## API

@@ -227,22 +237,13 @@

Adds `help` and `--help` to program which displays program usage information.
Adds `help` and `--help` to the program which displays program usage information.
#### `program.withVersion()`
Adds `version` and `--version` to program which displays program version from
Adds `version` and `--version` to the program which displays program version from
package.json.
#### `program.fail(function)`
#### `program.run(command)`
Use custom error handler. Function will be called with 4 arguments:
- Message (string) will contain internal message about e.g. missing arguments
- Error (Error) is only set when an error was explicitly thrown
- Args (array) contains program arguments
- Usage (string) contains usage information from --help
#### `program.eval(command)`
Uses process.argv or passed in command (string, optional) to match and execute
command. Returns runner instance.
command. Returns promise.

@@ -252,8 +253,8 @@ ```ts

.add(command(...))
.eval()
.run()
```
#### `program.run(command)`
#### `program.repl()`
Shorthand for `eval().print()`.
Start a read-eval-print loop.

@@ -263,8 +264,8 @@ ```ts

.add(command(...))
.run()
.repl()
```
#### `program.repl()`
#### `program.runOrRepl()`
Start a read-eval-print loop.
Invokes `run()` if arguments are passed in, `repl()` otherwise.

@@ -274,3 +275,3 @@ ```ts

.add(command(...))
.repl()
.runOrRepl()
```

@@ -282,4 +283,4 @@

- Name (string, optional) is used to invoke a command. When not used as default
command, name is required.
- Name (string, optional) is used to invoke a command. When not used as the
default command, a name is required.
- Description (string, optional) is used in --help output.

@@ -294,7 +295,7 @@

- Description (string, optional) is used in --help output.
- Options can be provided to change the behaviour of the
- Options can be provided to change the behavior of the
argument. Object with any of these keys:
- `optional` (boolean) makes this argument optional.
- `variadic` (boolean) eagerly take all remaining arguments and parse as array.
Only valid for last argument.
- `variadic` (boolean) eagerly take all remaining arguments and parse as an array.
Only valid for the last argument.
- ...

@@ -308,3 +309,3 @@

- Description (string, optional) is used in --help output.
- Options (OptionOptions) can be provided to change the behaviour of the
- Options (OptionOptions) can be provided to change the behavior of the
option. Object with any of these keys:

@@ -324,58 +325,5 @@ - `alias` (string or array of strings) alias(es) for the option key.

Function to execute when command is invoked. Is called with one argument: an
Function to execute when the command is invoked. Is called with one argument: an
object containing key/value pairs of parsed arguments and options.
### `runner`
Returned from `program().eval()`, can't be invoked directly.
#### `runner.print(printer)`
Prints resolved and rejected command executions to the terminal. Uses the
built-in printer if invoked without arguments.
```ts
const runner = program()
.default(
command().action(() => {
throw new Error('Test customer printer')
})
)
.eval()
runner.print({
write(str: any) {
str && console.log(str)
},
error(error: any) {
console.error(`${red('‼')} ${bgRed(error)}`)
}
})
```
#### `runner.then(function)`
Function is invoked when command handler resolves.
#### `runner.catch(function)`
Function is invoked when command handler rejects.
#### `runner.print(printer)`
Attaches a printer to the runner. Uses a default printer unless called with a
custom printer argument.
### `printer`
Used by runner, can't be invoked directly.
#### `printer.write(string)`
Handles output. Prints to stdout by default.
#### `printer.error(Error)`
Handles errors. Prints stack trace to stderr by default.
## Bundle

@@ -463,3 +411,3 @@

Next, we need to create a simple entrypoint `echo.js`, which can be run with
Next, we need to create a simple entry point `echo.js`, which can be run with
node:

@@ -559,3 +507,3 @@

Copyright (c) 2019 Joram van den Boezem. Licensed under the MIT license.
Copyright (c) 2020 Joram van den Boezem. Licensed under the MIT license.

@@ -562,0 +510,0 @@ ---

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc