Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Option Constructor using config file #1642

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions lib/option.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,30 @@ class Option {
this.argChoices = undefined;
}

constructor(config) { // Config object that contains flags and description?
this.flags = config['flags'];
this.description = config['description'] || '';

this.required = flags.includes('<'); // A value must be supplied when the option is specified.
this.optional = flags.includes('['); // A value is optional when the option is specified.
// variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument
this.variadic = /\w\.\.\.[>\]]$/.test(flags); // The option can take multiple values.
this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.
const optionFlags = splitOptionFlags(flags);
this.short = optionFlags.shortFlag;
this.long = optionFlags.longFlag;
this.negate = false;
if (this.long) {
this.negate = this.long.startsWith('--no-');
}
this.defaultValue = undefined;
this.defaultValueDescription = undefined;
this.envVar = undefined;
this.parseArg = undefined;
this.hidden = false;
this.argChoices = undefined;
}

/**
* Set the default value, and optionally supply the description to be displayed in the help.
*
Expand Down
125 changes: 97 additions & 28 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class Argument {
* Make argument optional.
*/
argOptional(): this;
}
}

export class Option {
flags: string;
Expand All @@ -94,6 +94,8 @@ export class Option {

constructor(flags: string, description?: string);

constructor(config: { flags: string; description?: string });

/**
* Set the default value, and optionally supply the description to be displayed in the help.
*/
Expand Down Expand Up @@ -188,20 +190,27 @@ export class Help {
* Wrap the given string to width characters per line, with lines after the first indented.
* Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
*/
wrap(str: string, width: number, indent: number, minColumnWidth?: number): string;
wrap(
str: string,
width: number,
indent: number,
minColumnWidth?: number
): string;

/** Generate the built-in help text. */
formatHelp(cmd: Command, helper: Help): string;
}
export type HelpConfiguration = Partial<Help>;

export interface ParseOptions {
from: 'node' | 'electron' | 'user';
from: "node" | "electron" | "user";
}
export interface HelpContext { // optional parameter for .help() and .outputHelp()
export interface HelpContext {
// optional parameter for .help() and .outputHelp()
error: boolean;
}
export interface AddHelpTextContext { // passed to text function used with .addHelpText()
export interface AddHelpTextContext {
// passed to text function used with .addHelpText()
error: boolean;
command: Command;
}
Expand All @@ -211,12 +220,11 @@ export interface OutputConfiguration {
getOutHelpWidth?(): number;
getErrHelpWidth?(): number;
outputError?(str: string, write: (str: string) => void): void;

}

export type AddHelpTextPosition = 'beforeAll' | 'before' | 'after' | 'afterAll';
export type HookEvent = 'preAction' | 'postAction';
export type OptionValueSource = 'default' | 'env' | 'config' | 'cli';
export type AddHelpTextPosition = "beforeAll" | "before" | "after" | "afterAll";
export type HookEvent = "preAction" | "postAction";
export type OptionValueSource = "default" | "env" | "config" | "cli";

export interface OptionValues {
[key: string]: any;
Expand Down Expand Up @@ -260,7 +268,10 @@ export class Command {
* @param opts - configuration options
* @returns new command
*/
command(nameAndArgs: string, opts?: CommandOptions): ReturnType<this['createCommand']>;
command(
nameAndArgs: string,
opts?: CommandOptions
): ReturnType<this["createCommand"]>;
/**
* Define a command, implemented in a separate executable file.
*
Expand All @@ -279,7 +290,11 @@ export class Command {
* @param opts - configuration options
* @returns `this` command for chaining
*/
command(nameAndArgs: string, description: string, opts?: ExecutableCommandOptions): this;
command(
nameAndArgs: string,
description: string,
opts?: ExecutableCommandOptions
): this;

/**
* Factory routine to create a new unattached command.
Expand Down Expand Up @@ -320,8 +335,13 @@ export class Command {
*
* @returns `this` command for chaining
*/
argument<T>(flags: string, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): this;
argument(name: string, description?: string, defaultValue?: unknown): this;
argument<T>(
flags: string,
description: string,
fn: (value: string, previous: T) => T,
defaultValue?: T
): this;
argument(name: string, description?: string, defaultValue?: unknown): this;

/**
* Define argument syntax for command, adding a prepared argument.
Expand Down Expand Up @@ -356,17 +376,26 @@ export class Command {
*
* @returns `this` command for chaining
*/
addHelpCommand(enableOrNameAndArgs?: string | boolean, description?: string): this;
addHelpCommand(
enableOrNameAndArgs?: string | boolean,
description?: string
): this;

/**
* Add hook for life cycle event.
*/
hook(event: HookEvent, listener: (thisCommand: Command, actionCommand: Command) => void | Promise<void>): this;
hook(
event: HookEvent,
listener: (
thisCommand: Command,
actionCommand: Command
) => void | Promise<void>
): this;

/**
* Register callback to use as replacement for calling process.exit.
*/
exitOverride(callback?: (err: CommanderError) => never|void): this;
exitOverride(callback?: (err: CommanderError) => never | void): this;

/**
* You can customise the help with a subclass of Help by overriding createHelp,
Expand Down Expand Up @@ -419,7 +448,7 @@ export class Command {
*/
showSuggestionAfterError(displaySuggestion?: boolean): this;

/**
/**
* Register callback `fn` for the command.
*
* @example
Expand Down Expand Up @@ -480,21 +509,49 @@ export class Command {
*
* @returns `this` command for chaining
*/
option(flags: string, description?: string, defaultValue?: string | boolean): this;
option<T>(flags: string, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): this;
option(
flags: string,
description?: string,
defaultValue?: string | boolean
): this;
option<T>(
flags: string,
description: string,
fn: (value: string, previous: T) => T,
defaultValue?: T
): this;
/** @deprecated since v7, instead use choices or a custom function */
option(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean): this;
option(
flags: string,
description: string,
regexp: RegExp,
defaultValue?: string | boolean
): this;

/**
* Define a required option, which must have a value after parsing. This usually means
* the option must be specified on the command line. (Otherwise the same as .option().)
*
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
*/
requiredOption(flags: string, description?: string, defaultValue?: string | boolean): this;
requiredOption<T>(flags: string, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): this;
requiredOption(
flags: string,
description?: string,
defaultValue?: string | boolean
): this;
requiredOption<T>(
flags: string,
description: string,
fn: (value: string, previous: T) => T,
defaultValue?: T
): this;
/** @deprecated since v7, instead use choices or a custom function */
requiredOption(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean): this;
requiredOption(
flags: string,
description: string,
regexp: RegExp,
defaultValue?: string | boolean
): this;

/**
* Factory routine to create a new unattached option.
Expand All @@ -519,7 +576,9 @@ export class Command {
* @returns `this` command for chaining
*/
storeOptionsAsProperties<T extends OptionValues>(): this & T;
storeOptionsAsProperties<T extends OptionValues>(storeAsProperties: true): this & T;
storeOptionsAsProperties<T extends OptionValues>(
storeAsProperties: true
): this & T;
storeOptionsAsProperties(storeAsProperties?: boolean): this;

/**
Expand All @@ -535,14 +594,18 @@ export class Command {
/**
* Store option value and where the value came from.
*/
setOptionValueWithSource(key: string, value: unknown, source: OptionValueSource): this;
setOptionValueWithSource(
key: string,
value: unknown,
source: OptionValueSource
): this;

/**
* Retrieve option value source.
*/
getOptionValueSource(key: string): OptionValueSource;

/**
/**
* Alter parsing of short flags with optional values.
*
* @example
Expand Down Expand Up @@ -652,7 +715,10 @@ export class Command {

description(str: string): this;
/** @deprecated since v8, instead use .argument to add command argument with description */
description(str: string, argsDescription: {[argName: string]: string}): this;
description(
str: string,
argsDescription: { [argName: string]: string }
): this;
/**
* Get the description.
*/
Expand Down Expand Up @@ -744,7 +810,10 @@ export class Command {
* and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
*/
addHelpText(position: AddHelpTextPosition, text: string): this;
addHelpText(position: AddHelpTextPosition, text: (context: AddHelpTextContext) => string): this;
addHelpText(
position: AddHelpTextPosition,
text: (context: AddHelpTextContext) => string
): this;

/**
* Add a listener (callback) for when events occur. (Implemented using EventEmitter.)
Expand Down
Loading