lambda-layer-packager
Version:
A professional CLI tool designed to package Node.js modules into a zip file for AWS Lambda Layers, facilitating efficient deployment and management of serverless applications.
1,209 lines (1,175 loc) • 1.07 MB
JavaScript
import {EventEmitter as $7P9PB$EventEmitter} from "events";
import {spawn as $7P9PB$spawn, exec as $7P9PB$exec} from "child_process";
import * as $7P9PB$path from "path";
import * as $7P9PB$fs from "fs";
import * as $7P9PB$process from "process";
import * as $7P9PB$stream from "stream";
import * as $7P9PB$util from "util";
import * as $7P9PB$buffer from "buffer";
import * as $7P9PB$assert from "assert";
import * as $7P9PB$constants1 from "constants";
import {DeflateRaw as $7P9PB$DeflateRaw, createGzip as $7P9PB$createGzip} from "zlib";
import {StringDecoder as $7P9PB$StringDecoder} from "string_decoder";
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
var $parcel$global = globalThis;
function $parcel$interopDefault(a) {
return a && a.__esModule ? a.default : a;
}
var $parcel$modules = {};
var $parcel$inits = {};
var parcelRequire = $parcel$global["parcelRequire94c2"];
if (parcelRequire == null) {
parcelRequire = function(id) {
if (id in $parcel$modules) {
return $parcel$modules[id].exports;
}
if (id in $parcel$inits) {
var init = $parcel$inits[id];
delete $parcel$inits[id];
var module = {id: id, exports: {}};
$parcel$modules[id] = module;
init.call(module.exports, module, module.exports);
return module.exports;
}
var err = new Error("Cannot find module '" + id + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
};
parcelRequire.register = function register(id, init) {
$parcel$inits[id] = init;
};
$parcel$global["parcelRequire94c2"] = parcelRequire;
}
var parcelRegister = parcelRequire.register;
parcelRegister("4SHYO", function(module, exports) {
var $hATzO = parcelRequire("hATzO");
var $38de520d36fb05b7$require$Argument = $hATzO.Argument;
var $nnts3 = parcelRequire("nnts3");
var $38de520d36fb05b7$require$Command = $nnts3.Command;
var $5Kwvq = parcelRequire("5Kwvq");
var $38de520d36fb05b7$require$CommanderError = $5Kwvq.CommanderError;
var $38de520d36fb05b7$require$InvalidArgumentError = $5Kwvq.InvalidArgumentError;
var $5xqpG = parcelRequire("5xqpG");
var $38de520d36fb05b7$require$Help = $5xqpG.Help;
var $8wDLy = parcelRequire("8wDLy");
var $38de520d36fb05b7$require$Option = $8wDLy.Option;
// @ts-check
/**
* Expose the root command.
*/ exports = module.exports = new $38de520d36fb05b7$require$Command();
exports.program = exports; // More explicit access to global command.
// Implicit export of createArgument, createCommand, and createOption.
/**
* Expose classes
*/ exports.Argument = $38de520d36fb05b7$require$Argument;
exports.Command = $38de520d36fb05b7$require$Command;
exports.CommanderError = $38de520d36fb05b7$require$CommanderError;
exports.Help = $38de520d36fb05b7$require$Help;
exports.InvalidArgumentError = $38de520d36fb05b7$require$InvalidArgumentError;
exports.InvalidOptionArgumentError = $38de520d36fb05b7$require$InvalidArgumentError; // Deprecated
exports.Option = $38de520d36fb05b7$require$Option;
});
parcelRegister("hATzO", function(module, exports) {
$parcel$export(module.exports, "Argument", () => $ccf0e8d65c065218$export$84637ea037d2e218, (v) => $ccf0e8d65c065218$export$84637ea037d2e218 = v);
$parcel$export(module.exports, "humanReadableArgName", () => $ccf0e8d65c065218$export$6e65b3a729b8c0d8, (v) => $ccf0e8d65c065218$export$6e65b3a729b8c0d8 = v);
var $ccf0e8d65c065218$export$84637ea037d2e218;
var $ccf0e8d65c065218$export$6e65b3a729b8c0d8;
var $5Kwvq = parcelRequire("5Kwvq");
var $ccf0e8d65c065218$require$InvalidArgumentError = $5Kwvq.InvalidArgumentError;
// @ts-check
class $ccf0e8d65c065218$var$Argument {
/**
* Initialize a new command argument with the given name and description.
* The default is that the argument is required, and you can explicitly
* indicate this with <> around the name. Put [] around the name for an optional argument.
*
* @param {string} name
* @param {string} [description]
*/ constructor(name, description){
this.description = description || '';
this.variadic = false;
this.parseArg = undefined;
this.defaultValue = undefined;
this.defaultValueDescription = undefined;
this.argChoices = undefined;
switch(name[0]){
case '<':
this.required = true;
this._name = name.slice(1, -1);
break;
case '[':
this.required = false;
this._name = name.slice(1, -1);
break;
default:
this.required = true;
this._name = name;
break;
}
if (this._name.length > 3 && this._name.slice(-3) === '...') {
this.variadic = true;
this._name = this._name.slice(0, -3);
}
}
/**
* Return argument name.
*
* @return {string}
*/ name() {
return this._name;
}
/**
* @api private
*/ _concatValue(value, previous) {
if (previous === this.defaultValue || !Array.isArray(previous)) return [
value
];
return previous.concat(value);
}
/**
* Set the default value, and optionally supply the description to be displayed in the help.
*
* @param {any} value
* @param {string} [description]
* @return {Argument}
*/ default(value, description) {
this.defaultValue = value;
this.defaultValueDescription = description;
return this;
}
/**
* Set the custom handler for processing CLI command arguments into argument values.
*
* @param {Function} [fn]
* @return {Argument}
*/ argParser(fn) {
this.parseArg = fn;
return this;
}
/**
* Only allow argument value to be one of choices.
*
* @param {string[]} values
* @return {Argument}
*/ choices(values) {
this.argChoices = values.slice();
this.parseArg = (arg, previous)=>{
if (!this.argChoices.includes(arg)) throw new $ccf0e8d65c065218$require$InvalidArgumentError(`Allowed choices are ${this.argChoices.join(', ')}.`);
if (this.variadic) return this._concatValue(arg, previous);
return arg;
};
return this;
}
/**
* Make argument required.
*/ argRequired() {
this.required = true;
return this;
}
/**
* Make argument optional.
*/ argOptional() {
this.required = false;
return this;
}
}
/**
* Takes an argument and returns its human readable equivalent for help usage.
*
* @param {Argument} arg
* @return {string}
* @api private
*/ function $ccf0e8d65c065218$var$humanReadableArgName(arg) {
const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');
return arg.required ? '<' + nameOutput + '>' : '[' + nameOutput + ']';
}
$ccf0e8d65c065218$export$84637ea037d2e218 = $ccf0e8d65c065218$var$Argument;
$ccf0e8d65c065218$export$6e65b3a729b8c0d8 = $ccf0e8d65c065218$var$humanReadableArgName;
});
parcelRegister("5Kwvq", function(module, exports) {
$parcel$export(module.exports, "CommanderError", () => $42fa769743cb6497$export$e42852c0d9bd9ade, (v) => $42fa769743cb6497$export$e42852c0d9bd9ade = v);
$parcel$export(module.exports, "InvalidArgumentError", () => $42fa769743cb6497$export$9c711d4a95378233, (v) => $42fa769743cb6497$export$9c711d4a95378233 = v);
// @ts-check
/**
* CommanderError class
* @class
*/ var $42fa769743cb6497$export$e42852c0d9bd9ade;
var $42fa769743cb6497$export$9c711d4a95378233;
class $42fa769743cb6497$var$CommanderError extends Error {
/**
* Constructs the CommanderError class
* @param {number} exitCode suggested exit code which could be used with process.exit
* @param {string} code an id string representing the error
* @param {string} message human-readable description of the error
* @constructor
*/ constructor(exitCode, code, message){
super(message);
// properly capture stack trace in Node.js
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.code = code;
this.exitCode = exitCode;
this.nestedError = undefined;
}
}
/**
* InvalidArgumentError class
* @class
*/ class $42fa769743cb6497$var$InvalidArgumentError extends $42fa769743cb6497$var$CommanderError {
/**
* Constructs the InvalidArgumentError class
* @param {string} [message] explanation of why argument is invalid
* @constructor
*/ constructor(message){
super(1, 'commander.invalidArgument', message);
// properly capture stack trace in Node.js
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
}
}
$42fa769743cb6497$export$e42852c0d9bd9ade = $42fa769743cb6497$var$CommanderError;
$42fa769743cb6497$export$9c711d4a95378233 = $42fa769743cb6497$var$InvalidArgumentError;
});
parcelRegister("nnts3", function(module, exports) {
$parcel$export(module.exports, "Command", () => $04645b8ca176286a$export$cc7e12c76513e857, (v) => $04645b8ca176286a$export$cc7e12c76513e857 = v);
var $04645b8ca176286a$export$cc7e12c76513e857;
var $04645b8ca176286a$require$EventEmitter = $7P9PB$EventEmitter;
var $hATzO = parcelRequire("hATzO");
var $04645b8ca176286a$require$Argument = $hATzO.Argument;
var $04645b8ca176286a$require$humanReadableArgName = $hATzO.humanReadableArgName;
var $5Kwvq = parcelRequire("5Kwvq");
var $04645b8ca176286a$require$CommanderError = $5Kwvq.CommanderError;
var $5xqpG = parcelRequire("5xqpG");
var $04645b8ca176286a$require$Help = $5xqpG.Help;
var $8wDLy = parcelRequire("8wDLy");
var $04645b8ca176286a$require$Option = $8wDLy.Option;
var $04645b8ca176286a$require$splitOptionFlags = $8wDLy.splitOptionFlags;
var $04645b8ca176286a$require$DualOptions = $8wDLy.DualOptions;
var $8rXP9 = parcelRequire("8rXP9");
var $04645b8ca176286a$require$suggestSimilar = $8rXP9.suggestSimilar;
// @ts-check
class $04645b8ca176286a$var$Command extends $04645b8ca176286a$require$EventEmitter {
/**
* Initialize a new `Command`.
*
* @param {string} [name]
*/ constructor(name){
super();
/** @type {Command[]} */ this.commands = [];
/** @type {Option[]} */ this.options = [];
this.parent = null;
this._allowUnknownOption = false;
this._allowExcessArguments = true;
/** @type {Argument[]} */ this._args = [];
/** @type {string[]} */ this.args = []; // cli args with options removed
this.rawArgs = [];
this.processedArgs = []; // like .args but after custom processing and collecting variadic
this._scriptPath = null;
this._name = name || '';
this._optionValues = {};
this._optionValueSources = {}; // default, env, cli etc
this._storeOptionsAsProperties = false;
this._actionHandler = null;
this._executableHandler = false;
this._executableFile = null; // custom name for executable
this._executableDir = null; // custom search directory for subcommands
this._defaultCommandName = null;
this._exitCallback = null;
this._aliases = [];
this._combineFlagAndOptionalValue = true;
this._description = '';
this._summary = '';
this._argsDescription = undefined; // legacy
this._enablePositionalOptions = false;
this._passThroughOptions = false;
this._lifeCycleHooks = {}; // a hash of arrays
/** @type {boolean | string} */ this._showHelpAfterError = false;
this._showSuggestionAfterError = true;
// see .configureOutput() for docs
this._outputConfiguration = {
writeOut: (str)=>$7P9PB$process.stdout.write(str),
writeErr: (str)=>$7P9PB$process.stderr.write(str),
getOutHelpWidth: ()=>$7P9PB$process.stdout.isTTY ? $7P9PB$process.stdout.columns : undefined,
getErrHelpWidth: ()=>$7P9PB$process.stderr.isTTY ? $7P9PB$process.stderr.columns : undefined,
outputError: (str, write)=>write(str)
};
this._hidden = false;
this._hasHelpOption = true;
this._helpFlags = '-h, --help';
this._helpDescription = 'display help for command';
this._helpShortFlag = '-h';
this._helpLongFlag = '--help';
this._addImplicitHelpCommand = undefined; // Deliberately undefined, not decided whether true or false
this._helpCommandName = 'help';
this._helpCommandnameAndArgs = 'help [command]';
this._helpCommandDescription = 'display help for command';
this._helpConfiguration = {};
}
/**
* Copy settings that are useful to have in common across root command and subcommands.
*
* (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)
*
* @param {Command} sourceCommand
* @return {Command} `this` command for chaining
*/ copyInheritedSettings(sourceCommand) {
this._outputConfiguration = sourceCommand._outputConfiguration;
this._hasHelpOption = sourceCommand._hasHelpOption;
this._helpFlags = sourceCommand._helpFlags;
this._helpDescription = sourceCommand._helpDescription;
this._helpShortFlag = sourceCommand._helpShortFlag;
this._helpLongFlag = sourceCommand._helpLongFlag;
this._helpCommandName = sourceCommand._helpCommandName;
this._helpCommandnameAndArgs = sourceCommand._helpCommandnameAndArgs;
this._helpCommandDescription = sourceCommand._helpCommandDescription;
this._helpConfiguration = sourceCommand._helpConfiguration;
this._exitCallback = sourceCommand._exitCallback;
this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
this._allowExcessArguments = sourceCommand._allowExcessArguments;
this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
this._showHelpAfterError = sourceCommand._showHelpAfterError;
this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
return this;
}
/**
* Define a command.
*
* There are two styles of command: pay attention to where to put the description.
*
* @example
* // Command implemented using action handler (description is supplied separately to `.command`)
* program
* .command('clone <source> [destination]')
* .description('clone a repository into a newly created directory')
* .action((source, destination) => {
* console.log('clone command called');
* });
*
* // Command implemented using separate executable file (description is second parameter to `.command`)
* program
* .command('start <service>', 'start named service')
* .command('stop [service]', 'stop named service, or all if no name supplied');
*
* @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
* @param {Object|string} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
* @param {Object} [execOpts] - configuration options (for executable)
* @return {Command} returns new command for action handler, or `this` for executable command
*/ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
let desc = actionOptsOrExecDesc;
let opts = execOpts;
if (typeof desc === 'object' && desc !== null) {
opts = desc;
desc = null;
}
opts = opts || {};
const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
const cmd = this.createCommand(name);
if (desc) {
cmd.description(desc);
cmd._executableHandler = true;
}
if (opts.isDefault) this._defaultCommandName = cmd._name;
cmd._hidden = !!(opts.noHelp || opts.hidden); // noHelp is deprecated old name for hidden
cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor
if (args) cmd.arguments(args);
this.commands.push(cmd);
cmd.parent = this;
cmd.copyInheritedSettings(this);
if (desc) return this;
return cmd;
}
/**
* Factory routine to create a new unattached command.
*
* See .command() for creating an attached subcommand, which uses this routine to
* create the command. You can override createCommand to customise subcommands.
*
* @param {string} [name]
* @return {Command} new command
*/ createCommand(name) {
return new $04645b8ca176286a$var$Command(name);
}
/**
* You can customise the help with a subclass of Help by overriding createHelp,
* or by overriding Help properties using configureHelp().
*
* @return {Help}
*/ createHelp() {
return Object.assign(new $04645b8ca176286a$require$Help(), this.configureHelp());
}
/**
* You can customise the help by overriding Help properties using configureHelp(),
* or with a subclass of Help by overriding createHelp().
*
* @param {Object} [configuration] - configuration options
* @return {Command|Object} `this` command for chaining, or stored configuration
*/ configureHelp(configuration) {
if (configuration === undefined) return this._helpConfiguration;
this._helpConfiguration = configuration;
return this;
}
/**
* The default output goes to stdout and stderr. You can customise this for special
* applications. You can also customise the display of errors by overriding outputError.
*
* The configuration properties are all functions:
*
* // functions to change where being written, stdout and stderr
* writeOut(str)
* writeErr(str)
* // matching functions to specify width for wrapping help
* getOutHelpWidth()
* getErrHelpWidth()
* // functions based on what is being written out
* outputError(str, write) // used for displaying errors, and not used for displaying help
*
* @param {Object} [configuration] - configuration options
* @return {Command|Object} `this` command for chaining, or stored configuration
*/ configureOutput(configuration) {
if (configuration === undefined) return this._outputConfiguration;
Object.assign(this._outputConfiguration, configuration);
return this;
}
/**
* Display the help or a custom message after an error occurs.
*
* @param {boolean|string} [displayHelp]
* @return {Command} `this` command for chaining
*/ showHelpAfterError(displayHelp = true) {
if (typeof displayHelp !== 'string') displayHelp = !!displayHelp;
this._showHelpAfterError = displayHelp;
return this;
}
/**
* Display suggestion of similar commands for unknown commands, or options for unknown options.
*
* @param {boolean} [displaySuggestion]
* @return {Command} `this` command for chaining
*/ showSuggestionAfterError(displaySuggestion = true) {
this._showSuggestionAfterError = !!displaySuggestion;
return this;
}
/**
* Add a prepared subcommand.
*
* See .command() for creating an attached subcommand which inherits settings from its parent.
*
* @param {Command} cmd - new subcommand
* @param {Object} [opts] - configuration options
* @return {Command} `this` command for chaining
*/ addCommand(cmd, opts) {
if (!cmd._name) throw new Error(`Command passed to .addCommand() must have a name
- specify the name in Command constructor or using .name()`);
opts = opts || {};
if (opts.isDefault) this._defaultCommandName = cmd._name;
if (opts.noHelp || opts.hidden) cmd._hidden = true; // modifying passed command due to existing implementation
this.commands.push(cmd);
cmd.parent = this;
return this;
}
/**
* Factory routine to create a new unattached argument.
*
* See .argument() for creating an attached argument, which uses this routine to
* create the argument. You can override createArgument to return a custom argument.
*
* @param {string} name
* @param {string} [description]
* @return {Argument} new argument
*/ createArgument(name, description) {
return new $04645b8ca176286a$require$Argument(name, description);
}
/**
* Define argument syntax for command.
*
* The default is that the argument is required, and you can explicitly
* indicate this with <> around the name. Put [] around the name for an optional argument.
*
* @example
* program.argument('<input-file>');
* program.argument('[output-file]');
*
* @param {string} name
* @param {string} [description]
* @param {Function|*} [fn] - custom argument processing function
* @param {*} [defaultValue]
* @return {Command} `this` command for chaining
*/ argument(name, description, fn, defaultValue) {
const argument = this.createArgument(name, description);
if (typeof fn === 'function') argument.default(defaultValue).argParser(fn);
else argument.default(fn);
this.addArgument(argument);
return this;
}
/**
* Define argument syntax for command, adding multiple at once (without descriptions).
*
* See also .argument().
*
* @example
* program.arguments('<cmd> [env]');
*
* @param {string} names
* @return {Command} `this` command for chaining
*/ arguments(names) {
names.split(/ +/).forEach((detail)=>{
this.argument(detail);
});
return this;
}
/**
* Define argument syntax for command, adding a prepared argument.
*
* @param {Argument} argument
* @return {Command} `this` command for chaining
*/ addArgument(argument) {
const previousArgument = this._args.slice(-1)[0];
if (previousArgument && previousArgument.variadic) throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
this._args.push(argument);
return this;
}
/**
* Override default decision whether to add implicit help command.
*
* addHelpCommand() // force on
* addHelpCommand(false); // force off
* addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
*
* @return {Command} `this` command for chaining
*/ addHelpCommand(enableOrNameAndArgs, description) {
if (enableOrNameAndArgs === false) this._addImplicitHelpCommand = false;
else {
this._addImplicitHelpCommand = true;
if (typeof enableOrNameAndArgs === 'string') {
this._helpCommandName = enableOrNameAndArgs.split(' ')[0];
this._helpCommandnameAndArgs = enableOrNameAndArgs;
}
this._helpCommandDescription = description || this._helpCommandDescription;
}
return this;
}
/**
* @return {boolean}
* @api private
*/ _hasImplicitHelpCommand() {
if (this._addImplicitHelpCommand === undefined) return this.commands.length && !this._actionHandler && !this._findCommand('help');
return this._addImplicitHelpCommand;
}
/**
* Add hook for life cycle event.
*
* @param {string} event
* @param {Function} listener
* @return {Command} `this` command for chaining
*/ hook(event, listener) {
const allowedValues = [
'preSubcommand',
'preAction',
'postAction'
];
if (!allowedValues.includes(event)) throw new Error(`Unexpected value for event passed to hook : '${event}'.
Expecting one of '${allowedValues.join("', '")}'`);
if (this._lifeCycleHooks[event]) this._lifeCycleHooks[event].push(listener);
else this._lifeCycleHooks[event] = [
listener
];
return this;
}
/**
* Register callback to use as replacement for calling process.exit.
*
* @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing
* @return {Command} `this` command for chaining
*/ exitOverride(fn) {
if (fn) this._exitCallback = fn;
else this._exitCallback = (err)=>{
if (err.code !== 'commander.executeSubCommandAsync') throw err;
};
return this;
}
/**
* Call process.exit, and _exitCallback if defined.
*
* @param {number} exitCode exit code for using with process.exit
* @param {string} code an id string representing the error
* @param {string} message human-readable description of the error
* @return never
* @api private
*/ _exit(exitCode, code, message) {
if (this._exitCallback) this._exitCallback(new $04645b8ca176286a$require$CommanderError(exitCode, code, message));
$7P9PB$process.exit(exitCode);
}
/**
* Register callback `fn` for the command.
*
* @example
* program
* .command('serve')
* .description('start service')
* .action(function() {
* // do work here
* });
*
* @param {Function} fn
* @return {Command} `this` command for chaining
*/ action(fn) {
const listener = (args)=>{
// The .action callback takes an extra parameter which is the command or options.
const expectedArgsCount = this._args.length;
const actionArgs = args.slice(0, expectedArgsCount);
if (this._storeOptionsAsProperties) actionArgs[expectedArgsCount] = this; // backwards compatible "options"
else actionArgs[expectedArgsCount] = this.opts();
actionArgs.push(this);
return fn.apply(this, actionArgs);
};
this._actionHandler = listener;
return this;
}
/**
* Factory routine to create a new unattached option.
*
* See .option() for creating an attached option, which uses this routine to
* create the option. You can override createOption to return a custom option.
*
* @param {string} flags
* @param {string} [description]
* @return {Option} new option
*/ createOption(flags, description) {
return new $04645b8ca176286a$require$Option(flags, description);
}
/**
* Add an option.
*
* @param {Option} option
* @return {Command} `this` command for chaining
*/ addOption(option) {
const oname = option.name();
const name = option.attributeName();
// 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');
} else if (option.defaultValue !== undefined) this.setOptionValueWithSource(name, option.defaultValue, 'default');
// register the option
this.options.push(option);
// handler for cli and env supplied values
const handleOptionValue = (val, invalidValueMessage, valueSource)=>{
// 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);
} catch (err) {
if (err.code === 'commander.invalidArgument') {
const message = `${invalidValueMessage} ${err.message}`;
this.error(message, {
exitCode: err.exitCode,
code: err.code
});
}
throw err;
}
else if (val !== null && option.variadic) val = option._concatValue(val, oldValue);
// 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 val = ''; // not normal, parseArg might have failed or be a mock function for testing
}
this.setOptionValueWithSource(name, val, valueSource);
};
this.on('option:' + oname, (val)=>{
const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
handleOptionValue(val, invalidValueMessage, 'cli');
});
if (option.envVar) this.on('optionEnv:' + oname, (val)=>{
const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
handleOptionValue(val, invalidValueMessage, 'env');
});
return this;
}
/**
* Internal implementation shared by .option() and .requiredOption()
*
* @api private
*/ _optionEx(config, flags, description, fn, defaultValue) {
if (typeof flags === 'object' && flags instanceof $04645b8ca176286a$require$Option) throw new Error('To add an Option object use addOption() instead of option() or requiredOption()');
const option = this.createOption(flags, description);
option.makeOptionMandatory(!!config.mandatory);
if (typeof fn === 'function') option.default(defaultValue).argParser(fn);
else if (fn instanceof RegExp) {
// deprecated
const regex = fn;
fn = (val, def)=>{
const m = regex.exec(val);
return m ? m[0] : def;
};
option.default(defaultValue).argParser(fn);
} else option.default(fn);
return this.addOption(option);
}
/**
* Define option with `flags`, `description` and optional
* coercion `fn`.
*
* The `flags` string contains the short and/or long flags,
* separated by comma, a pipe or space. The following are all valid
* all will output this way when `--help` is used.
*
* "-p, --pepper"
* "-p|--pepper"
* "-p --pepper"
*
* @example
* // simple boolean defaulting to undefined
* program.option('-p, --pepper', 'add pepper');
*
* program.pepper
* // => undefined
*
* --pepper
* program.pepper
* // => true
*
* // simple boolean defaulting to true (unless non-negated option is also defined)
* program.option('-C, --no-cheese', 'remove cheese');
*
* program.cheese
* // => true
*
* --no-cheese
* program.cheese
* // => false
*
* // required argument
* program.option('-C, --chdir <path>', 'change the working directory');
*
* --chdir /tmp
* program.chdir
* // => "/tmp"
*
* // optional argument
* program.option('-c, --cheese [type]', 'add cheese [marble]');
*
* @param {string} flags
* @param {string} [description]
* @param {Function|*} [fn] - custom option processing function or default value
* @param {*} [defaultValue]
* @return {Command} `this` command for chaining
*/ option(flags, description, fn, defaultValue) {
return this._optionEx({}, flags, description, fn, defaultValue);
}
/**
* Add 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.
*
* @param {string} flags
* @param {string} [description]
* @param {Function|*} [fn] - custom option processing function or default value
* @param {*} [defaultValue]
* @return {Command} `this` command for chaining
*/ requiredOption(flags, description, fn, defaultValue) {
return this._optionEx({
mandatory: true
}, flags, description, fn, defaultValue);
}
/**
* Alter parsing of short flags with optional values.
*
* @example
* // for `.option('-f,--flag [value]'):
* program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
* program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
*
* @param {Boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
*/ combineFlagAndOptionalValue(combine = true) {
this._combineFlagAndOptionalValue = !!combine;
return this;
}
/**
* Allow unknown options on the command line.
*
* @param {Boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
* for unknown options.
*/ allowUnknownOption(allowUnknown = true) {
this._allowUnknownOption = !!allowUnknown;
return this;
}
/**
* Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
*
* @param {Boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
* for excess arguments.
*/ allowExcessArguments(allowExcess = true) {
this._allowExcessArguments = !!allowExcess;
return this;
}
/**
* Enable positional options. Positional means global options are specified before subcommands which lets
* subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
* The default behaviour is non-positional and global options may appear anywhere on the command line.
*
* @param {Boolean} [positional=true]
*/ enablePositionalOptions(positional = true) {
this._enablePositionalOptions = !!positional;
return this;
}
/**
* Pass through options that come after command-arguments rather than treat them as command-options,
* so actual command-options come before command-arguments. Turning this on for a subcommand requires
* positional options to have been enabled on the program (parent commands).
* The default behaviour is non-positional and options may appear before or after command-arguments.
*
* @param {Boolean} [passThrough=true]
* for unknown options.
*/ passThroughOptions(passThrough = true) {
this._passThroughOptions = !!passThrough;
if (!!this.parent && passThrough && !this.parent._enablePositionalOptions) throw new Error('passThroughOptions can not be used without turning on enablePositionalOptions for parent command(s)');
return this;
}
/**
* Whether to store option values as properties on command object,
* or store separately (specify false). In both cases the option values can be accessed using .opts().
*
* @param {boolean} [storeAsProperties=true]
* @return {Command} `this` command for chaining
*/ storeOptionsAsProperties(storeAsProperties = true) {
this._storeOptionsAsProperties = !!storeAsProperties;
if (this.options.length) throw new Error('call .storeOptionsAsProperties() before adding options');
return this;
}
/**
* Retrieve option value.
*
* @param {string} key
* @return {Object} value
*/ getOptionValue(key) {
if (this._storeOptionsAsProperties) return this[key];
return this._optionValues[key];
}
/**
* Store option value.
*
* @param {string} key
* @param {Object} value
* @return {Command} `this` command for chaining
*/ setOptionValue(key, value) {
return this.setOptionValueWithSource(key, value, undefined);
}
/**
* Store option value and where the value came from.
*
* @param {string} key
* @param {Object} value
* @param {string} source - expected values are default/config/env/cli/implied
* @return {Command} `this` command for chaining
*/ setOptionValueWithSource(key, value, source) {
if (this._storeOptionsAsProperties) this[key] = value;
else this._optionValues[key] = value;
this._optionValueSources[key] = source;
return this;
}
/**
* Get source of option value.
* Expected values are default | config | env | cli | implied
*
* @param {string} key
* @return {string}
*/ getOptionValueSource(key) {
return this._optionValueSources[key];
}
/**
* Get source of option value. See also .optsWithGlobals().
* Expected values are default | config | env | cli | implied
*
* @param {string} key
* @return {string}
*/ getOptionValueSourceWithGlobals(key) {
// global overwrites local, like optsWithGlobals
let source;
$04645b8ca176286a$var$getCommandAndParents(this).forEach((cmd)=>{
if (cmd.getOptionValueSource(key) !== undefined) source = cmd.getOptionValueSource(key);
});
return source;
}
/**
* Get user arguments from implied or explicit arguments.
* Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
*
* @api private
*/ _prepareUserArgs(argv, parseOptions) {
if (argv !== undefined && !Array.isArray(argv)) throw new Error('first parameter to parse must be array or undefined');
parseOptions = parseOptions || {};
// Default to using process.argv
if (argv === undefined) {
argv = $7P9PB$process.argv;
// @ts-ignore: unknown property
if ($7P9PB$process.versions && $7P9PB$process.versions.electron) parseOptions.from = 'electron';
}
this.rawArgs = argv.slice();
// make it a little easier for callers by supporting various argv conventions
let userArgs;
switch(parseOptions.from){
case undefined:
case 'node':
this._scriptPath = argv[1];
userArgs = argv.slice(2);
break;
case 'electron':
// @ts-ignore: unknown property
if ($7P9PB$process.defaultApp) {
this._scriptPath = argv[1];
userArgs = argv.slice(2);
} else userArgs = argv.slice(1);
break;
case 'user':
userArgs = argv.slice(0);
break;
default:
throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
}
// Find default name for program from arguments.
if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath);
this._name = this._name || 'program';
return userArgs;
}
/**
* Parse `argv`, setting options and invoking commands when defined.
*
* The default expectation is that the arguments are from node and have the application as argv[0]
* and the script being run in argv[1], with user parameters after that.
*
* @example
* program.parse(process.argv);
* program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
* program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
*
* @param {string[]} [argv] - optional, defaults to process.argv
* @param {Object} [parseOptions] - optionally specify style of options with from: node/user/electron
* @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
* @return {Command} `this` command for chaining
*/ parse(argv, parseOptions) {
const userArgs = this._prepareUserArgs(argv, parseOptions);
this._parseCommand([], userArgs);
return this;
}
/**
* Parse `argv`, setting options and invoking commands when defined.
*
* Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
*
* The default expectation is that the arguments are from node and have the application as argv[0]
* and the script being run in argv[1], with user parameters after that.
*
* @example
* await program.parseAsync(process.argv);
* await program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
* await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
*
* @param {string[]} [argv]
* @param {Object} [parseOptions]
* @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
* @return {Promise}
*/ async parseAsync(argv, parseOptions) {
const userArgs = this._prepareUserArgs(argv, parseOptions);
await this._parseCommand([], userArgs);
return this;
}
/**
* Execute a sub-command executable.
*
* @api private
*/ _executeSubCommand(subcommand, args) {
args = args.slice();
let launchWithNode = false; // Use node for source targets so do not need to get permissions correct, and on Windows.
const sourceExt = [
'.js',
'.ts',
'.tsx',
'.mjs',
'.cjs'
];
function findFile(baseDir, baseName) {
// Look for specified file
const localBin = $7P9PB$resolve(baseDir, baseName);
if ($7P9PB$existsSync(localBin)) return localBin;
// Stop looking if candidate already has an expected extension.
if (sourceExt.includes($7P9PB$extname(baseName))) return undefined;
// Try all the extensions.
const foundExt = sourceExt.find((ext)=>$7P9PB$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();
this._checkForConflictingOptions();
// 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 = $7P9PB$realpathSync(this._scriptPath);
} catch (err) {
resolvedScriptPath = this._scriptPath;
}
executableDir = $7P9PB$resolve($7P9PB$dirname(resolvedScriptPath), executableDir);
}
// Look for a local file in preference to a command in PATH.
if (executableDir) {
let localFile = findFile(executableDir, executableFile);
// Legacy search using prefix of script name instead of command name
if (!localFile && !subcommand._executableFile && this._scriptPath) {
const legacyName = $7P9PB$basename(this._scriptPath, $7P9PB$extname(this._scriptPath));
if (legacyName !== this._name) localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
}
executableFile = localFile || executableFile;
}
launchWithNode = sourceExt.includes($7P9PB$extname(executableFile));
let proc;
if ($7P9PB$process.platform !== 'win32') {
if (launchWithNode) {
args.unshift(executableFile);
// add executable arguments to spawn
args = $04645b8ca176286a$var$incrementNodeInspectorPort($7P9PB$process.execArgv).concat(args);
proc = $7P9PB$spawn($7P9PB$process.argv[0], args, {
stdio: 'inherit'
});
} else proc = $7P9PB$spawn(executableFile, args, {
stdio: 'inherit'
});
} else {
args.unshift(executableFile);
// add executable arguments to spawn
args = $04645b8ca176286a$var$incrementNodeInspectorPort($7P9PB$process.execArgv).concat(args);
proc = $7P9PB$spawn($7P9PB$process.execPath, args, {
stdio: 'inherit'
});
}
if (!proc.killed) {
const signals = [
'SIGUSR1',
'SIGUSR2',
'SIGTERM',
'SIGINT',
'SIGHUP'
];
signals.forEach((signal)=>{
// @ts-ignore
$7P9PB$process.on(signal, ()=>{
if (proc.killed === false && proc.exitCode === null) proc.kill(signal);
});
});
}
// By default terminate process when spawned process terminates.
// Suppressing the exit if exitCallback defined is a bit messy and of limited use, but does allow process to stay running!
const exitCallback = this._exitCallback;
if (!exitCallback) proc.on('close', $7P9PB$process.exit.bind($7P9PB$process));
else proc.on('close', ()=>{
exitCallback(new $04645b8ca176286a$require$CommanderError($7P9PB$process.exitCode || 0, 'commander.executeSubCommandAsync', '(close)'));
});
proc.on('error', (err)=>{
// @ts-ignore
if (err.code === 'ENOENT') {
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 or path
- ${executableDirMessage}`;
throw new Error(executableMissing);
// @ts-ignore
} else if (err.code === 'EACCES') throw new Error(`'${executableFile}' not executable`);
if (!exitCallback) $7P9PB$process.exit(1);
else {
const wrappedError = new $04645b8ca176286a$require$CommanderError(1, 'commander.executeSubCommandAsync', '(error)');
wrappedError.nestedError = err;
exitCallback(wrappedError);
}
});
// Store the reference to the child process
this.runningCommand = proc;
}
/**
* @api private
*/ _dispatchSubcommand(commandName, operands, unknown) {
const subCommand = this._findCommand(commandName);
if (!subCommand) this.help({
error: true
});
let hookResult;
hookResult = this._chainOrCallSubCommandHook(hookResult, subCommand, 'preSubcommand');
hookResult = this._chainOrCall(hookResult, ()=>{
if (subCommand._executableHandler) this._executeSubCommand(subCommand, operands.concat(unknown));
else return subCommand._parseCommand(operands, unknown);
});
return hookResult;
}
/**
* Check this.args against expected this._args.
*
* @api private
*/ _checkNumberOfArguments() {
// too few
this._args.forEach((arg, i)=>{
if (arg.required && this.args[i] == null) this.missingArgument(arg.name());
});
// too many
if (this._args.length > 0 && this._args[this._args.length - 1].variadic) return;
if (this.args.length > this._args.length) this._excessArguments(this.args);
}
/**
* Process this.args using this._args and save as this.processedArgs!
*
* @api private
*/ _processArguments() {
const myParseArg = (argument, value, previous)=>{
// Extra processing for nice error message on parsing failure.
let parsedValue = value;
if (value !== null && argument.parseArg) try {
parsedValue = argument.parseArg(value, previous);
} catch (err) {
if (err.code === 'commander.invalidArgument') {
const message = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'. ${err.message}`;
this.error(message, {
exitCode: err.exitCode,
code: err.code
});
}
throw err;
}
return parsedValue;
};
this._checkNumberOfArguments();
const processedArgs = [];
this._args.forEach((declaredArg, index)=>{
let value = declaredArg.defaultValue;
if (declaredArg.variadic) {
// Collect together remaining arguments for passing together as an array.
if (index < this.args.length) {
value = this.args.slice(index);
if (declaredArg.parseArg) value = value.reduce((processed, v)=>{
return myParseArg(declaredArg, v, processed);
}, declaredArg.defaultValue);
} else if (value === undefined) value = [];
} else if (index < this.args.length) {
value = this.args[index];
if (declaredArg.parseArg) value = myParseArg(declaredArg, value, declaredArg.defaultValue);
}
processedArgs[index] = value;
});
this.processedArgs = processedArgs;
}
/**
* Once we have a promise we chain, but call synchronously until then.
*
* @param {Promise|undefined} promise
* @par