commander
Advanced tools
Comparing version 8.3.0 to 9.0.0-0
@@ -93,3 +93,3 @@ const { InvalidArgumentError } = require('./error.js'); | ||
/** | ||
* Only allow option value to be one of choices. | ||
* Only allow argument value to be one of choices. | ||
* | ||
@@ -115,3 +115,3 @@ * @param {string[]} values | ||
/** | ||
* Make option-argument required. | ||
* Make argument required. | ||
*/ | ||
@@ -124,3 +124,3 @@ argRequired() { | ||
/** | ||
* Make option-argument optional. | ||
* Make argument optional. | ||
*/ | ||
@@ -127,0 +127,0 @@ argOptional() { |
@@ -44,2 +44,3 @@ const EventEmitter = require('events').EventEmitter; | ||
this._executableFile = null; // custom name for executable | ||
this._executableDir = null; // custom search directory for subcommands | ||
this._defaultCommandName = null; | ||
@@ -56,3 +57,3 @@ this._exitCallback = null; | ||
this._showHelpAfterError = false; | ||
this._showSuggestionAfterError = false; | ||
this._showSuggestionAfterError = true; | ||
@@ -263,15 +264,6 @@ // see .configureOutput() for docs | ||
addCommand(cmd, opts) { | ||
if (!cmd._name) throw new Error('Command passed to .addCommand() must have a name'); | ||
// To keep things simple, block automatic name generation for deeply nested executables. | ||
// Fail fast and detect when adding rather than later when parsing. | ||
function checkExplicitNames(commandArray) { | ||
commandArray.forEach((cmd) => { | ||
if (cmd._executableHandler && !cmd._executableFile) { | ||
throw new Error(`Must specify executableFile for deeply nested executable: ${cmd.name()}`); | ||
} | ||
checkExplicitNames(cmd.commands); | ||
}); | ||
if (!cmd._name) { | ||
throw new Error(`Command passed to .addCommand() must have a name | ||
- specify the name in Command constructor or using .name()`); | ||
} | ||
checkExplicitNames(cmd.commands); | ||
@@ -522,15 +514,11 @@ opts = opts || {}; | ||
let defaultValue = option.defaultValue; | ||
// preassign default value for --no-*, [optional], <required>, or plain flag if boolean value | ||
if (option.negate || option.optional || option.required || typeof defaultValue === 'boolean') { | ||
// when --no-foo we make sure default is true, unless a --foo option is already defined | ||
if (option.negate) { | ||
const positiveLongFlag = option.long.replace(/^--no-/, '--'); | ||
defaultValue = this._findOption(positiveLongFlag) ? this.getOptionValue(name) : true; | ||
// store default value | ||
if (option.negate) { | ||
// --no-foo is special and defaults foo to true, unless a --foo option is already defined | ||
const positiveLongFlag = option.long.replace(/^--no-/, '--'); | ||
if (!this._findOption(positiveLongFlag)) { | ||
this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, 'default'); | ||
} | ||
// preassign only if we have a default | ||
if (defaultValue !== undefined) { | ||
this.setOptionValueWithSource(name, defaultValue, 'default'); | ||
} | ||
} else if (option.defaultValue !== undefined) { | ||
this.setOptionValueWithSource(name, option.defaultValue, 'default'); | ||
} | ||
@@ -543,9 +531,13 @@ | ||
const handleOptionValue = (val, invalidValueMessage, valueSource) => { | ||
// Note: using closure to access lots of lexical scoped variables. | ||
const oldValue = this.getOptionValue(name); | ||
// val is null for optional option used without an optional-argument. | ||
// val is undefined for boolean and negated option. | ||
if (val == null && option.presetArg !== undefined) { | ||
val = option.presetArg; | ||
} | ||
// custom processing | ||
const oldValue = this.getOptionValue(name); | ||
if (val !== null && option.parseArg) { | ||
try { | ||
val = option.parseArg(val, oldValue === undefined ? defaultValue : oldValue); | ||
val = option.parseArg(val, oldValue); | ||
} catch (err) { | ||
@@ -562,14 +554,13 @@ if (err.code === 'commander.invalidArgument') { | ||
// unassigned or boolean value | ||
if (typeof oldValue === 'boolean' || typeof oldValue === 'undefined') { | ||
// if no value, negate false, and we have a default, then use it! | ||
if (val == null) { | ||
this.setOptionValueWithSource(name, option.negate ? false : defaultValue || true, valueSource); | ||
// Fill-in appropriate missing values. Long winded but easy to follow. | ||
if (val == null) { | ||
if (option.negate) { | ||
val = false; | ||
} else if (option.isBoolean() || option.optional) { | ||
val = true; | ||
} else { | ||
this.setOptionValueWithSource(name, val, valueSource); | ||
val = ''; // not normal, parseArg might have failed or be a mock function for testing | ||
} | ||
} else if (val !== null) { | ||
// reassign | ||
this.setOptionValueWithSource(name, option.negate ? false : val, valueSource); | ||
} | ||
this.setOptionValueWithSource(name, val, valueSource); | ||
}; | ||
@@ -598,2 +589,5 @@ | ||
_optionEx(config, flags, description, fn, defaultValue) { | ||
if (typeof flags === 'object' && flags instanceof Option) { | ||
throw new Error('To add an Option object use addOption() instead of option() or requiredOption()'); | ||
} | ||
const option = this.createOption(flags, description); | ||
@@ -830,4 +824,4 @@ option.makeOptionMandatory(!!config.mandatory); | ||
/** | ||
* Get user arguments implied or explicit arguments. | ||
* Side-effects: set _scriptPath if args included application, and use that to set implicit command name. | ||
* Get user arguments from implied or explicit arguments. | ||
* Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches. | ||
* | ||
@@ -876,8 +870,6 @@ * @api private | ||
} | ||
if (!this._scriptPath && require.main) { | ||
this._scriptPath = require.main.filename; | ||
} | ||
// Guess name, used in usage in help. | ||
this._name = this._name || (this._scriptPath && path.basename(this._scriptPath, path.extname(this._scriptPath))); | ||
// Find default name for program from arguments. | ||
if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath); | ||
this._name = this._name || 'program'; | ||
@@ -948,44 +940,53 @@ return userArgs; | ||
function findFile(baseDir, baseName) { | ||
// Look for specified file | ||
const localBin = path.resolve(baseDir, baseName); | ||
if (fs.existsSync(localBin)) return localBin; | ||
// Stop looking if candidate already has an expected extension. | ||
if (sourceExt.includes(path.extname(baseName))) return undefined; | ||
// Try all the extensions. | ||
const foundExt = sourceExt.find(ext => fs.existsSync(`${localBin}${ext}`)); | ||
if (foundExt) return `${localBin}${foundExt}`; | ||
return undefined; | ||
} | ||
// Not checking for help first. Unlikely to have mandatory and executable, and can't robustly test for help flags in external command. | ||
this._checkForMissingMandatoryOptions(); | ||
// Want the entry script as the reference for command name and directory for searching for other files. | ||
let scriptPath = this._scriptPath; | ||
// Fallback in case not set, due to how Command created or called. | ||
if (!scriptPath && require.main) { | ||
scriptPath = require.main.filename; | ||
// executableFile and executableDir might be full path, or just a name | ||
let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`; | ||
let executableDir = this._executableDir || ''; | ||
if (this._scriptPath) { | ||
let resolvedScriptPath; // resolve possible symlink for installed npm binary | ||
try { | ||
resolvedScriptPath = fs.realpathSync(this._scriptPath); | ||
} catch (err) { | ||
resolvedScriptPath = this._scriptPath; | ||
} | ||
executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir); | ||
} | ||
let baseDir; | ||
try { | ||
const resolvedLink = fs.realpathSync(scriptPath); | ||
baseDir = path.dirname(resolvedLink); | ||
} catch (e) { | ||
baseDir = '.'; // dummy, probably not going to find executable! | ||
} | ||
// Look for a local file in preference to a command in PATH. | ||
if (executableDir) { | ||
let localFile = findFile(executableDir, executableFile); | ||
// name of the subcommand, like `pm-install` | ||
let bin = path.basename(scriptPath, path.extname(scriptPath)) + '-' + subcommand._name; | ||
if (subcommand._executableFile) { | ||
bin = subcommand._executableFile; | ||
} | ||
const localBin = path.join(baseDir, bin); | ||
if (fs.existsSync(localBin)) { | ||
// prefer local `./<bin>` to bin in the $PATH | ||
bin = localBin; | ||
} else { | ||
// Look for source files. | ||
sourceExt.forEach((ext) => { | ||
if (fs.existsSync(`${localBin}${ext}`)) { | ||
bin = `${localBin}${ext}`; | ||
// Legacy search using prefix of script name instead of command name | ||
if (!localFile && !subcommand._executableFile && this._scriptPath) { | ||
const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath)); | ||
if (legacyName !== this._name) { | ||
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`); | ||
} | ||
}); | ||
} | ||
executableFile = localFile || executableFile; | ||
} | ||
launchWithNode = sourceExt.includes(path.extname(bin)); | ||
launchWithNode = sourceExt.includes(path.extname(executableFile)); | ||
let proc; | ||
if (process.platform !== 'win32') { | ||
if (launchWithNode) { | ||
args.unshift(bin); | ||
args.unshift(executableFile); | ||
// add executable arguments to spawn | ||
@@ -996,6 +997,6 @@ args = incrementNodeInspectorPort(process.execArgv).concat(args); | ||
} else { | ||
proc = childProcess.spawn(bin, args, { stdio: 'inherit' }); | ||
proc = childProcess.spawn(executableFile, args, { stdio: 'inherit' }); | ||
} | ||
} else { | ||
args.unshift(bin); | ||
args.unshift(executableFile); | ||
// add executable arguments to spawn | ||
@@ -1006,11 +1007,13 @@ args = incrementNodeInspectorPort(process.execArgv).concat(args); | ||
const signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP']; | ||
signals.forEach((signal) => { | ||
// @ts-ignore | ||
process.on(signal, () => { | ||
if (proc.killed === false && proc.exitCode === null) { | ||
proc.kill(signal); | ||
} | ||
if (!proc.killed) { // testing mainly to avoid leak warnings during unit tests with mocked spawn | ||
const signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP']; | ||
signals.forEach((signal) => { | ||
// @ts-ignore | ||
process.on(signal, () => { | ||
if (proc.killed === false && proc.exitCode === null) { | ||
proc.kill(signal); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
@@ -1030,9 +1033,13 @@ // By default terminate process when spawned process terminates. | ||
if (err.code === 'ENOENT') { | ||
const executableMissing = `'${bin}' does not exist | ||
const executableDirMessage = executableDir | ||
? `searched for local subcommand relative to directory '${executableDir}'` | ||
: 'no directory for search for local subcommand, use .executableDir() to supply a custom directory'; | ||
const executableMissing = `'${executableFile}' does not exist | ||
- if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead | ||
- if the default executable name is not suitable, use the executableFile option to supply a custom name`; | ||
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path | ||
- ${executableDirMessage}`; | ||
throw new Error(executableMissing); | ||
// @ts-ignore | ||
} else if (err.code === 'EACCES') { | ||
throw new Error(`'${bin}' not executable`); | ||
throw new Error(`'${executableFile}' not executable`); | ||
} | ||
@@ -1241,3 +1248,7 @@ if (!exitCallback) { | ||
actionResult = this._chainOrCall(actionResult, () => this._actionHandler(this.processedArgs)); | ||
if (this.parent) this.parent.emit(commandEvent, operands, unknown); // legacy | ||
if (this.parent) { | ||
actionResult = this._chainOrCall(actionResult, () => { | ||
this.parent.emit(commandEvent, operands, unknown); // legacy | ||
}); | ||
} | ||
actionResult = this._chainOrCallHooks(actionResult, 'postAction'); | ||
@@ -1726,3 +1737,3 @@ return actionResult; | ||
/** | ||
* Get or set the name of the command | ||
* Get or set the name of the command. | ||
* | ||
@@ -1740,2 +1751,39 @@ * @param {string} [str] | ||
/** | ||
* Set the name of the command from script filename, such as process.argv[1], | ||
* or require.main.filename, or __filename. | ||
* | ||
* (Used internally and public although not documented in README.) | ||
* | ||
* @example | ||
* program.nameFromFilename(require.main.filename); | ||
* | ||
* @param {string} filename | ||
* @return {Command} | ||
*/ | ||
nameFromFilename(filename) { | ||
this._name = path.basename(filename, path.extname(filename)); | ||
return this; | ||
} | ||
/** | ||
* Get or set the directory for searching for executable subcommands of this command. | ||
* | ||
* @example | ||
* program.executableDir(__dirname); | ||
* // or | ||
* program.executableDir('subcommands'); | ||
* | ||
* @param {string} [path] | ||
* @return {string|Command} | ||
*/ | ||
executableDir(path) { | ||
if (path === undefined) return this._executableDir; | ||
this._executableDir = path; | ||
return this; | ||
}; | ||
/** | ||
* Return program help documentation. | ||
@@ -1742,0 +1790,0 @@ * |
@@ -238,5 +238,4 @@ const { humanReadableArgName } = require('./argument.js'); | ||
const extraInfo = []; | ||
// Some of these do not make sense for negated boolean and suppress for backwards compatibility. | ||
if (option.argChoices && !option.negate) { | ||
if (option.argChoices) { | ||
extraInfo.push( | ||
@@ -246,5 +245,15 @@ // use stringify to match the display of the default value | ||
} | ||
if (option.defaultValue !== undefined && !option.negate) { | ||
extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`); | ||
if (option.defaultValue !== undefined) { | ||
// default for boolean and negated more for programmer than end user, | ||
// but show true/false for boolean option as may be for hand-rolled env or config processing. | ||
const showDefault = option.required || option.optional || | ||
(option.isBoolean() && typeof option.defaultValue === 'boolean'); | ||
if (showDefault) { | ||
extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`); | ||
} | ||
} | ||
// preset for boolean and negated are more for programmer than end user | ||
if (option.presetArg !== undefined && option.optional) { | ||
extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`); | ||
} | ||
if (option.envVar !== undefined) { | ||
@@ -251,0 +260,0 @@ extraInfo.push(`env: ${option.envVar}`); |
@@ -31,2 +31,3 @@ const { InvalidArgumentError } = require('./error.js'); | ||
this.defaultValueDescription = undefined; | ||
this.presetArg = undefined; | ||
this.envVar = undefined; | ||
@@ -53,2 +54,19 @@ this.parseArg = undefined; | ||
/** | ||
* Preset to use when option used without option-argument, especially optional but also boolean and negated. | ||
* The custom processing (parseArg) is called. | ||
* | ||
* @example | ||
* new Option('--color').default('GREYSCALE').preset('RGB'); | ||
* new Option('--donate [amount]').preset('20').argParser(parseFloat); | ||
* | ||
* @param {any} arg | ||
* @return {Option} | ||
*/ | ||
preset(arg) { | ||
this.presetArg = arg; | ||
return this; | ||
}; | ||
/** | ||
* Set environment variable to check for option value. | ||
@@ -171,2 +189,15 @@ * Priority order of option values is default < env < cli | ||
}; | ||
/** | ||
* Return whether a boolean option. | ||
* | ||
* Options are one of boolean, negated, required argument, or optional argument. | ||
* | ||
* @return {boolean} | ||
* @api private | ||
*/ | ||
isBoolean() { | ||
return !this.required && !this.optional && !this.negate; | ||
}; | ||
} | ||
@@ -173,0 +204,0 @@ |
{ | ||
"name": "commander", | ||
"version": "8.3.0", | ||
"version": "9.0.0-0", | ||
"description": "the complete solution for node.js command-line programs", | ||
@@ -30,3 +30,2 @@ "keywords": [ | ||
}, | ||
"main": "./index.js", | ||
"files": [ | ||
@@ -40,6 +39,13 @@ "index.js", | ||
"type": "commonjs", | ||
"dependencies": {}, | ||
"main": "./index.js", | ||
"exports": { | ||
".": { | ||
"require": "./index.js", | ||
"import": "./esm.mjs" | ||
}, | ||
"./esm.mjs": "./esm.mjs" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^26.0.23", | ||
"@types/node": "^14.17.3", | ||
"@types/jest": "^27.0.3", | ||
"@types/node": "^16.11.15", | ||
"@typescript-eslint/eslint-plugin": "^4.27.0", | ||
@@ -68,5 +74,5 @@ "@typescript-eslint/parser": "^4.27.0", | ||
"engines": { | ||
"node": ">= 12" | ||
"node": "^12.20.0 || >=14" | ||
}, | ||
"support": true | ||
} |
@@ -35,3 +35,4 @@ # Commander.js | ||
- [Display help from code](#display-help-from-code) | ||
- [.usage and .name](#usage-and-name) | ||
- [.name](#name) | ||
- [.usage](#usage) | ||
- [.helpOption(flags, description)](#helpoptionflags-description) | ||
@@ -69,4 +70,4 @@ - [.addHelpCommand()](#addhelpcommand) | ||
```js | ||
// CommonJS (.cjs) | ||
const { program } = require('commander'); | ||
program.version('0.0.1'); | ||
``` | ||
@@ -77,19 +78,15 @@ | ||
```js | ||
// CommonJS (.cjs) | ||
const { Command } = require('commander'); | ||
const program = new Command(); | ||
program.version('0.0.1'); | ||
``` | ||
For named imports in ECMAScript modules, import from `commander/esm.mjs`. | ||
```js | ||
// index.mjs | ||
import { Command } from 'commander/esm.mjs'; | ||
// ECMAScript (.mjs) | ||
import { Command } from 'commander'; | ||
const program = new Command(); | ||
``` | ||
And in TypeScript: | ||
```ts | ||
// index.ts | ||
// TypeScript (.ts) | ||
import { Command } from 'commander'; | ||
@@ -155,3 +152,3 @@ const program = new Command(); | ||
You can specify a default value for an option which takes a value. | ||
You can specify a default value for an option. | ||
@@ -182,3 +179,3 @@ Example file: [options-defaults.js](./examples/options-defaults.js) | ||
If you define `--foo` first, adding `--no-foo` does not change the default value from what it would | ||
otherwise be. You can specify a default boolean value for a boolean option and it can be overridden on command line. | ||
otherwise be. | ||
@@ -323,3 +320,4 @@ Example file: [options-negatable.js](./examples/options-negatable.js) | ||
.addOption(new Option('-d, --drink <size>', 'drink size').choices(['small', 'medium', 'large'])) | ||
.addOption(new Option('-p, --port <number>', 'port number').env('PORT')); | ||
.addOption(new Option('-p, --port <number>', 'port number').env('PORT')) | ||
.addOption(new Option('--donate [amount]', 'optional donation in dollars').preset('20').argParser(parseFloat)); | ||
``` | ||
@@ -335,2 +333,3 @@ | ||
-p, --port <number> port number (env: PORT) | ||
--donate [amount] optional donation in dollars (preset: 20) | ||
-h, --help display help for command | ||
@@ -341,4 +340,4 @@ | ||
$ PORT=80 extra | ||
Options: { timeout: 60, port: '80' } | ||
$ PORT=80 extra --donate | ||
Options: { timeout: 60, donate: 20, port: '80' } | ||
``` | ||
@@ -566,4 +565,5 @@ | ||
When `.command()` is invoked with a description argument, this tells Commander that you're going to use stand-alone executables for subcommands. | ||
Commander will search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-subcommand`, like `pm-install`, `pm-search`. | ||
You can specify a custom name with the `executableFile` configuration option. | ||
Commander will search the files in the directory of the entry script for a file with the name combination `command-subcommand`, like `pm-install` or `pm-search` in the example below. The search includes trying common file extensions, like `.js`. | ||
You may specify a custom name (and path) with the `executableFile` configuration option. | ||
You may specify a custom search directory for subcommands with `.executableDir()`. | ||
@@ -576,2 +576,3 @@ You handle the options for an executable (sub)command in the executable, and don't declare them at the top-level. | ||
program | ||
.name('pm') | ||
.version('0.1.0') | ||
@@ -726,8 +727,23 @@ .command('install [name]', 'install one or more packages') | ||
### .usage and .name | ||
### .name | ||
These allow you to customise the usage description in the first line of the help. The name is otherwise | ||
deduced from the (full) program arguments. Given: | ||
The command name appears in the help, and is also used for locating stand-alone executable subcommands. | ||
You may specify the program name using `.name()` or in the Command constructor. For the program, Commander will | ||
fallback to using the script name from the full arguments passed into `.parse()`. However, the script name varies | ||
depending on how your program is launched so you may wish to specify it explicitly. | ||
```js | ||
program.name('pizza'); | ||
const pm = new Command('pm'); | ||
``` | ||
Subcommands get a name when specified using `.command()`. If you create the subcommand yourself to use with `.addCommand()`, | ||
then set the name using `.name()` or in the Command constructor. | ||
### .usage | ||
This allows you to customise the usage description in the first line of the help. Given: | ||
```js | ||
program | ||
@@ -746,3 +762,3 @@ .name("my-command") | ||
By default every command has a help option. Override the default help flags and description. Pass false to disable the built-in help option. | ||
By default every command has a help option. You may change the default help flags and description. Pass false to disable the built-in help option. | ||
@@ -984,2 +1000,3 @@ ```js | ||
program | ||
.name('deploy') | ||
.version('0.0.1') | ||
@@ -1019,4 +1036,4 @@ .option('-c, --config <path>', 'set config path', './deploy.conf'); | ||
The current version of Commander is fully supported on Long Term Support versions of node, and requires at least node v12. | ||
(For older versions of node, use an older version of Commander. Commander version 2.x has the widest support.) | ||
The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v12.20.0. | ||
(For older versions of Node.js, use an older version of Commander.) | ||
@@ -1023,0 +1040,0 @@ The main forum for free and community support is the project [Issues](https://github.com/tj/commander.js/issues) on GitHub. |
@@ -67,3 +67,3 @@ // Type definitions for commander | ||
/** | ||
* Make option-argument required. | ||
* Make argument required. | ||
*/ | ||
@@ -73,3 +73,3 @@ argRequired(): this; | ||
/** | ||
* Make option-argument optional. | ||
* Make argument optional. | ||
*/ | ||
@@ -105,2 +105,14 @@ argOptional(): this; | ||
/** | ||
* Preset to use when option used without option-argument, especially optional but also boolean and negated. | ||
* The custom processing (parseArg) is called. | ||
* | ||
* @example | ||
* ```ts | ||
* new Option('--color').default('GREYSCALE').preset('RGB'); | ||
* new Option('--donate [amount]').preset('20').argParser(parseFloat); | ||
* ``` | ||
*/ | ||
preset(arg: unknown): this; | ||
/** | ||
* Set environment variable to check for option value. | ||
@@ -146,2 +158,10 @@ * Priority order of option values is default < env < cli | ||
attributeName(): string; | ||
/** | ||
* Return whether a boolean option. | ||
* | ||
* Options are one of boolean, negated, required argument, or optional argument. | ||
*/ | ||
isBoolean(): boolean; | ||
} | ||
@@ -714,2 +734,35 @@ | ||
/** | ||
* Set the name of the command from script filename, such as process.argv[1], | ||
* or require.main.filename, or __filename. | ||
* | ||
* (Used internally and public although not documented in README.) | ||
* | ||
* @example | ||
* ```ts | ||
* program.nameFromFilename(require.main.filename); | ||
* ``` | ||
* | ||
* @returns `this` command for chaining | ||
*/ | ||
nameFromFilename(filename: string): this; | ||
/** | ||
* Set the directory for searching for executable subcommands of this command. | ||
* | ||
* @example | ||
* ```ts | ||
* program.executableDir(__dirname); | ||
* // or | ||
* program.executableDir('subcommands'); | ||
* ``` | ||
* | ||
* @returns `this` command for chaining | ||
*/ | ||
executableDir(path: string): this; | ||
/** | ||
* Get the executable search directory. | ||
*/ | ||
executableDir(): string; | ||
/** | ||
* Output help information for this command. | ||
@@ -716,0 +769,0 @@ * |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
156195
3373
1033
2