UNPKG

storypointer

Version:
1,477 lines (1,470 loc) 1.11 MB
#!/usr/bin/env node "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all3) => { for (var name in all3) __defProp(target, name, { get: all3[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // node_modules/dotenv/package.json var require_package = __commonJS({ "node_modules/dotenv/package.json"(exports2, module2) { module2.exports = { name: "dotenv", version: "17.0.1", description: "Loads environment variables from .env file", main: "lib/main.js", types: "lib/main.d.ts", exports: { ".": { types: "./lib/main.d.ts", require: "./lib/main.js", default: "./lib/main.js" }, "./config": "./config.js", "./config.js": "./config.js", "./lib/env-options": "./lib/env-options.js", "./lib/env-options.js": "./lib/env-options.js", "./lib/cli-options": "./lib/cli-options.js", "./lib/cli-options.js": "./lib/cli-options.js", "./package.json": "./package.json" }, scripts: { "dts-check": "tsc --project tests/types/tsconfig.json", lint: "standard", pretest: "npm run lint && npm run dts-check", test: "tap run --allow-empty-coverage --disable-coverage --timeout=60000", "test:coverage": "tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov", prerelease: "npm test", release: "standard-version" }, repository: { type: "git", url: "git://github.com/motdotla/dotenv.git" }, homepage: "https://github.com/motdotla/dotenv#readme", funding: "https://dotenvx.com", keywords: [ "dotenv", "env", ".env", "environment", "variables", "config", "settings" ], readmeFilename: "README.md", license: "BSD-2-Clause", devDependencies: { "@types/node": "^18.11.3", decache: "^4.6.2", sinon: "^14.0.1", standard: "^17.0.0", "standard-version": "^9.5.0", tap: "^19.2.0", typescript: "^4.8.4" }, engines: { node: ">=12" }, browser: { fs: false } }; } }); // node_modules/dotenv/lib/main.js var require_main = __commonJS({ "node_modules/dotenv/lib/main.js"(exports2, module2) { var fs = require("fs"); var path2 = require("path"); var os4 = require("os"); var crypto2 = require("crypto"); var packageJson = require_package(); var version = packageJson.version; var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg; function parse(src) { const obj = {}; let lines = src.toString(); lines = lines.replace(/\r\n?/mg, "\n"); let match; while ((match = LINE.exec(lines)) != null) { const key = match[1]; let value = match[2] || ""; value = value.trim(); const maybeQuote = value[0]; value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2"); if (maybeQuote === '"') { value = value.replace(/\\n/g, "\n"); value = value.replace(/\\r/g, "\r"); } obj[key] = value; } return obj; } function _parseVault(options) { options = options || {}; const vaultPath = _vaultPath(options); options.path = vaultPath; const result = DotenvModule.configDotenv(options); if (!result.parsed) { const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`); err.code = "MISSING_DATA"; throw err; } const keys = _dotenvKey(options).split(","); const length = keys.length; let decrypted; for (let i = 0; i < length; i++) { try { const key = keys[i].trim(); const attrs = _instructions(result, key); decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key); break; } catch (error) { if (i + 1 >= length) { throw error; } } } return DotenvModule.parse(decrypted); } function _warn(message) { console.error(`[dotenv@${version}][WARN] ${message}`); } function _debug(message) { console.log(`[dotenv@${version}][DEBUG] ${message}`); } function _log(message) { console.log(`[dotenv@${version}] ${message}`); } function _dotenvKey(options) { if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) { return options.DOTENV_KEY; } if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) { return process.env.DOTENV_KEY; } return ""; } function _instructions(result, dotenvKey) { let uri; try { uri = new URL(dotenvKey); } catch (error) { if (error.code === "ERR_INVALID_URL") { const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development"); err.code = "INVALID_DOTENV_KEY"; throw err; } throw error; } const key = uri.password; if (!key) { const err = new Error("INVALID_DOTENV_KEY: Missing key part"); err.code = "INVALID_DOTENV_KEY"; throw err; } const environment = uri.searchParams.get("environment"); if (!environment) { const err = new Error("INVALID_DOTENV_KEY: Missing environment part"); err.code = "INVALID_DOTENV_KEY"; throw err; } const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`; const ciphertext = result.parsed[environmentKey]; if (!ciphertext) { const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`); err.code = "NOT_FOUND_DOTENV_ENVIRONMENT"; throw err; } return { ciphertext, key }; } function _vaultPath(options) { let possibleVaultPath = null; if (options && options.path && options.path.length > 0) { if (Array.isArray(options.path)) { for (const filepath of options.path) { if (fs.existsSync(filepath)) { possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`; } } } else { possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`; } } else { possibleVaultPath = path2.resolve(process.cwd(), ".env.vault"); } if (fs.existsSync(possibleVaultPath)) { return possibleVaultPath; } return null; } function _resolveHome(envPath) { return envPath[0] === "~" ? path2.join(os4.homedir(), envPath.slice(1)) : envPath; } function _configVault(options) { const debug = Boolean(options && options.debug); const quiet = Boolean(options && options.quiet); if (debug || !quiet) { _log("Loading env from encrypted .env.vault"); } const parsed = DotenvModule._parseVault(options); let processEnv = process.env; if (options && options.processEnv != null) { processEnv = options.processEnv; } DotenvModule.populate(processEnv, parsed, options); return { parsed }; } function configDotenv(options) { const dotenvPath = path2.resolve(process.cwd(), ".env"); let encoding = "utf8"; const debug = Boolean(options && options.debug); const quiet = Boolean(options && options.quiet); if (options && options.encoding) { encoding = options.encoding; } else { if (debug) { _debug("No encoding is specified. UTF-8 is used by default"); } } let optionPaths = [dotenvPath]; if (options && options.path) { if (!Array.isArray(options.path)) { optionPaths = [_resolveHome(options.path)]; } else { optionPaths = []; for (const filepath of options.path) { optionPaths.push(_resolveHome(filepath)); } } } let lastError; const parsedAll = {}; for (const path3 of optionPaths) { try { const parsed = DotenvModule.parse(fs.readFileSync(path3, { encoding })); DotenvModule.populate(parsedAll, parsed, options); } catch (e) { if (debug) { _debug(`Failed to load ${path3} ${e.message}`); } lastError = e; } } let processEnv = process.env; if (options && options.processEnv != null) { processEnv = options.processEnv; } const populated = DotenvModule.populate(processEnv, parsedAll, options); if (debug || !quiet) { const keysCount = Object.keys(populated).length; const shortPaths = []; for (const filePath of optionPaths) { try { const relative = path2.relative(process.cwd(), filePath); shortPaths.push(relative); } catch (e) { if (debug) { _debug(`Failed to load ${filePath} ${e.message}`); } lastError = e; } } _log(`injecting env (${keysCount}) from ${shortPaths.join(",")} \u2013 [tip] encrypt with dotenvx: https://dotenvx.com`); } if (lastError) { return { parsed: parsedAll, error: lastError }; } else { return { parsed: parsedAll }; } } function config(options) { if (_dotenvKey(options).length === 0) { return DotenvModule.configDotenv(options); } const vaultPath = _vaultPath(options); if (!vaultPath) { _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`); return DotenvModule.configDotenv(options); } return DotenvModule._configVault(options); } function decrypt(encrypted, keyStr) { const key = Buffer.from(keyStr.slice(-64), "hex"); let ciphertext = Buffer.from(encrypted, "base64"); const nonce = ciphertext.subarray(0, 12); const authTag = ciphertext.subarray(-16); ciphertext = ciphertext.subarray(12, -16); try { const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce); aesgcm.setAuthTag(authTag); return `${aesgcm.update(ciphertext)}${aesgcm.final()}`; } catch (error) { const isRange = error instanceof RangeError; const invalidKeyLength = error.message === "Invalid key length"; const decryptionFailed = error.message === "Unsupported state or unable to authenticate data"; if (isRange || invalidKeyLength) { const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)"); err.code = "INVALID_DOTENV_KEY"; throw err; } else if (decryptionFailed) { const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY"); err.code = "DECRYPTION_FAILED"; throw err; } else { throw error; } } } function populate(processEnv, parsed, options = {}) { const debug = Boolean(options && options.debug); const override = Boolean(options && options.override); const populated = {}; if (typeof parsed !== "object") { const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate"); err.code = "OBJECT_REQUIRED"; throw err; } for (const key of Object.keys(parsed)) { if (Object.prototype.hasOwnProperty.call(processEnv, key)) { if (override === true) { processEnv[key] = parsed[key]; populated[key] = parsed[key]; } if (debug) { if (override === true) { _debug(`"${key}" is already defined and WAS overwritten`); } else { _debug(`"${key}" is already defined and was NOT overwritten`); } } } else { processEnv[key] = parsed[key]; populated[key] = parsed[key]; } } return populated; } var DotenvModule = { configDotenv, _configVault, _parseVault, config, decrypt, parse, populate }; module2.exports.configDotenv = DotenvModule.configDotenv; module2.exports._configVault = DotenvModule._configVault; module2.exports._parseVault = DotenvModule._parseVault; module2.exports.config = DotenvModule.config; module2.exports.decrypt = DotenvModule.decrypt; module2.exports.parse = DotenvModule.parse; module2.exports.populate = DotenvModule.populate; module2.exports = DotenvModule; } }); // node_modules/commander/lib/error.js var require_error = __commonJS({ "node_modules/commander/lib/error.js"(exports2) { var CommanderError2 = class 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(exitCode, code, message) { super(message); Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; this.code = code; this.exitCode = exitCode; this.nestedError = void 0; } }; var InvalidArgumentError2 = class extends CommanderError2 { /** * Constructs the InvalidArgumentError class * @param {string} [message] explanation of why argument is invalid */ constructor(message) { super(1, "commander.invalidArgument", message); Error.captureStackTrace(this, this.constructor); this.name = this.constructor.name; } }; exports2.CommanderError = CommanderError2; exports2.InvalidArgumentError = InvalidArgumentError2; } }); // node_modules/commander/lib/argument.js var require_argument = __commonJS({ "node_modules/commander/lib/argument.js"(exports2) { var { InvalidArgumentError: InvalidArgumentError2 } = require_error(); var Argument2 = class { /** * 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 = void 0; this.defaultValue = void 0; this.defaultValueDescription = void 0; this.argChoices = void 0; 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; } /** * @package */ _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 {*} 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 InvalidArgumentError2( `Allowed choices are ${this.argChoices.join(", ")}.` ); } if (this.variadic) { return this._concatValue(arg, previous); } return arg; }; return this; } /** * Make argument required. * * @returns {Argument} */ argRequired() { this.required = true; return this; } /** * Make argument optional. * * @returns {Argument} */ argOptional() { this.required = false; return this; } }; function humanReadableArgName(arg) { const nameOutput = arg.name() + (arg.variadic === true ? "..." : ""); return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]"; } exports2.Argument = Argument2; exports2.humanReadableArgName = humanReadableArgName; } }); // node_modules/commander/lib/help.js var require_help = __commonJS({ "node_modules/commander/lib/help.js"(exports2) { var { humanReadableArgName } = require_argument(); var Help2 = class { constructor() { this.helpWidth = void 0; this.minWidthToWrap = 40; this.sortSubcommands = false; this.sortOptions = false; this.showGlobalOptions = false; } /** * prepareContext is called by Commander after applying overrides from `Command.configureHelp()` * and just before calling `formatHelp()`. * * Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses. * * @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions */ prepareContext(contextOptions) { this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80; } /** * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one. * * @param {Command} cmd * @returns {Command[]} */ visibleCommands(cmd) { const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden); const helpCommand = cmd._getHelpCommand(); if (helpCommand && !helpCommand._hidden) { visibleCommands.push(helpCommand); } if (this.sortSubcommands) { visibleCommands.sort((a, b) => { return a.name().localeCompare(b.name()); }); } return visibleCommands; } /** * Compare options for sort. * * @param {Option} a * @param {Option} b * @returns {number} */ compareOptions(a, b) { const getSortKey = (option) => { return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, ""); }; return getSortKey(a).localeCompare(getSortKey(b)); } /** * Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one. * * @param {Command} cmd * @returns {Option[]} */ visibleOptions(cmd) { const visibleOptions = cmd.options.filter((option) => !option.hidden); const helpOption = cmd._getHelpOption(); if (helpOption && !helpOption.hidden) { const removeShort = helpOption.short && cmd._findOption(helpOption.short); const removeLong = helpOption.long && cmd._findOption(helpOption.long); if (!removeShort && !removeLong) { visibleOptions.push(helpOption); } else if (helpOption.long && !removeLong) { visibleOptions.push( cmd.createOption(helpOption.long, helpOption.description) ); } else if (helpOption.short && !removeShort) { visibleOptions.push( cmd.createOption(helpOption.short, helpOption.description) ); } } if (this.sortOptions) { visibleOptions.sort(this.compareOptions); } return visibleOptions; } /** * Get an array of the visible global options. (Not including help.) * * @param {Command} cmd * @returns {Option[]} */ visibleGlobalOptions(cmd) { if (!this.showGlobalOptions) return []; const globalOptions = []; for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) { const visibleOptions = ancestorCmd.options.filter( (option) => !option.hidden ); globalOptions.push(...visibleOptions); } if (this.sortOptions) { globalOptions.sort(this.compareOptions); } return globalOptions; } /** * Get an array of the arguments if any have a description. * * @param {Command} cmd * @returns {Argument[]} */ visibleArguments(cmd) { if (cmd._argsDescription) { cmd.registeredArguments.forEach((argument) => { argument.description = argument.description || cmd._argsDescription[argument.name()] || ""; }); } if (cmd.registeredArguments.find((argument) => argument.description)) { return cmd.registeredArguments; } return []; } /** * Get the command term to show in the list of subcommands. * * @param {Command} cmd * @returns {string} */ subcommandTerm(cmd) { const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" "); return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + // simplistic check for non-help option (args ? " " + args : ""); } /** * Get the option term to show in the list of options. * * @param {Option} option * @returns {string} */ optionTerm(option) { return option.flags; } /** * Get the argument term to show in the list of arguments. * * @param {Argument} argument * @returns {string} */ argumentTerm(argument) { return argument.name(); } /** * Get the longest command term length. * * @param {Command} cmd * @param {Help} helper * @returns {number} */ longestSubcommandTermLength(cmd, helper) { return helper.visibleCommands(cmd).reduce((max, command) => { return Math.max( max, this.displayWidth( helper.styleSubcommandTerm(helper.subcommandTerm(command)) ) ); }, 0); } /** * Get the longest option term length. * * @param {Command} cmd * @param {Help} helper * @returns {number} */ longestOptionTermLength(cmd, helper) { return helper.visibleOptions(cmd).reduce((max, option) => { return Math.max( max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))) ); }, 0); } /** * Get the longest global option term length. * * @param {Command} cmd * @param {Help} helper * @returns {number} */ longestGlobalOptionTermLength(cmd, helper) { return helper.visibleGlobalOptions(cmd).reduce((max, option) => { return Math.max( max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))) ); }, 0); } /** * Get the longest argument term length. * * @param {Command} cmd * @param {Help} helper * @returns {number} */ longestArgumentTermLength(cmd, helper) { return helper.visibleArguments(cmd).reduce((max, argument) => { return Math.max( max, this.displayWidth( helper.styleArgumentTerm(helper.argumentTerm(argument)) ) ); }, 0); } /** * Get the command usage to be displayed at the top of the built-in help. * * @param {Command} cmd * @returns {string} */ commandUsage(cmd) { let cmdName = cmd._name; if (cmd._aliases[0]) { cmdName = cmdName + "|" + cmd._aliases[0]; } let ancestorCmdNames = ""; for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) { ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames; } return ancestorCmdNames + cmdName + " " + cmd.usage(); } /** * Get the description for the command. * * @param {Command} cmd * @returns {string} */ commandDescription(cmd) { return cmd.description(); } /** * Get the subcommand summary to show in the list of subcommands. * (Fallback to description for backwards compatibility.) * * @param {Command} cmd * @returns {string} */ subcommandDescription(cmd) { return cmd.summary() || cmd.description(); } /** * Get the option description to show in the list of options. * * @param {Option} option * @return {string} */ optionDescription(option) { const extraInfo = []; if (option.argChoices) { extraInfo.push( // use stringify to match the display of the default value `choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}` ); } if (option.defaultValue !== void 0) { const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean"; if (showDefault) { extraInfo.push( `default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}` ); } } if (option.presetArg !== void 0 && option.optional) { extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`); } if (option.envVar !== void 0) { extraInfo.push(`env: ${option.envVar}`); } if (extraInfo.length > 0) { const extraDescription = `(${extraInfo.join(", ")})`; if (option.description) { return `${option.description} ${extraDescription}`; } return extraDescription; } return option.description; } /** * Get the argument description to show in the list of arguments. * * @param {Argument} argument * @return {string} */ argumentDescription(argument) { const extraInfo = []; if (argument.argChoices) { extraInfo.push( // use stringify to match the display of the default value `choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}` ); } if (argument.defaultValue !== void 0) { extraInfo.push( `default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}` ); } if (extraInfo.length > 0) { const extraDescription = `(${extraInfo.join(", ")})`; if (argument.description) { return `${argument.description} ${extraDescription}`; } return extraDescription; } return argument.description; } /** * Format a list of items, given a heading and an array of formatted items. * * @param {string} heading * @param {string[]} items * @param {Help} helper * @returns string[] */ formatItemList(heading, items, helper) { if (items.length === 0) return []; return [helper.styleTitle(heading), ...items, ""]; } /** * Group items by their help group heading. * * @param {Command[] | Option[]} unsortedItems * @param {Command[] | Option[]} visibleItems * @param {Function} getGroup * @returns {Map<string, Command[] | Option[]>} */ groupItems(unsortedItems, visibleItems, getGroup) { const result = /* @__PURE__ */ new Map(); unsortedItems.forEach((item) => { const group = getGroup(item); if (!result.has(group)) result.set(group, []); }); visibleItems.forEach((item) => { const group = getGroup(item); if (!result.has(group)) { result.set(group, []); } result.get(group).push(item); }); return result; } /** * Generate the built-in help text. * * @param {Command} cmd * @param {Help} helper * @returns {string} */ formatHelp(cmd, helper) { const termWidth = helper.padWidth(cmd, helper); const helpWidth = helper.helpWidth ?? 80; function callFormatItem(term, description) { return helper.formatItem(term, termWidth, description, helper); } let output = [ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`, "" ]; const commandDescription = helper.commandDescription(cmd); if (commandDescription.length > 0) { output = output.concat([ helper.boxWrap( helper.styleCommandDescription(commandDescription), helpWidth ), "" ]); } const argumentList = helper.visibleArguments(cmd).map((argument) => { return callFormatItem( helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)) ); }); output = output.concat( this.formatItemList("Arguments:", argumentList, helper) ); const optionGroups = this.groupItems( cmd.options, helper.visibleOptions(cmd), (option) => option.helpGroupHeading ?? "Options:" ); optionGroups.forEach((options, group) => { const optionList = options.map((option) => { return callFormatItem( helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)) ); }); output = output.concat(this.formatItemList(group, optionList, helper)); }); if (helper.showGlobalOptions) { const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => { return callFormatItem( helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)) ); }); output = output.concat( this.formatItemList("Global Options:", globalOptionList, helper) ); } const commandGroups = this.groupItems( cmd.commands, helper.visibleCommands(cmd), (sub) => sub.helpGroup() || "Commands:" ); commandGroups.forEach((commands, group) => { const commandList = commands.map((sub) => { return callFormatItem( helper.styleSubcommandTerm(helper.subcommandTerm(sub)), helper.styleSubcommandDescription(helper.subcommandDescription(sub)) ); }); output = output.concat(this.formatItemList(group, commandList, helper)); }); return output.join("\n"); } /** * Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations. * * @param {string} str * @returns {number} */ displayWidth(str) { return stripColor(str).length; } /** * Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc. * * @param {string} str * @returns {string} */ styleTitle(str) { return str; } styleUsage(str) { return str.split(" ").map((word) => { if (word === "[options]") return this.styleOptionText(word); if (word === "[command]") return this.styleSubcommandText(word); if (word[0] === "[" || word[0] === "<") return this.styleArgumentText(word); return this.styleCommandText(word); }).join(" "); } styleCommandDescription(str) { return this.styleDescriptionText(str); } styleOptionDescription(str) { return this.styleDescriptionText(str); } styleSubcommandDescription(str) { return this.styleDescriptionText(str); } styleArgumentDescription(str) { return this.styleDescriptionText(str); } styleDescriptionText(str) { return str; } styleOptionTerm(str) { return this.styleOptionText(str); } styleSubcommandTerm(str) { return str.split(" ").map((word) => { if (word === "[options]") return this.styleOptionText(word); if (word[0] === "[" || word[0] === "<") return this.styleArgumentText(word); return this.styleSubcommandText(word); }).join(" "); } styleArgumentTerm(str) { return this.styleArgumentText(str); } styleOptionText(str) { return str; } styleArgumentText(str) { return str; } styleSubcommandText(str) { return str; } styleCommandText(str) { return str; } /** * Calculate the pad width from the maximum term length. * * @param {Command} cmd * @param {Help} helper * @returns {number} */ padWidth(cmd, helper) { return Math.max( helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper) ); } /** * Detect manually wrapped and indented strings by checking for line break followed by whitespace. * * @param {string} str * @returns {boolean} */ preformatted(str) { return /\n[^\S\r\n]/.test(str); } /** * Format the "item", which consists of a term and description. Pad the term and wrap the description, indenting the following lines. * * So "TTT", 5, "DDD DDDD DD DDD" might be formatted for this.helpWidth=17 like so: * TTT DDD DDDD * DD DDD * * @param {string} term * @param {number} termWidth * @param {string} description * @param {Help} helper * @returns {string} */ formatItem(term, termWidth, description, helper) { const itemIndent = 2; const itemIndentStr = " ".repeat(itemIndent); if (!description) return itemIndentStr + term; const paddedTerm = term.padEnd( termWidth + term.length - helper.displayWidth(term) ); const spacerWidth = 2; const helpWidth = this.helpWidth ?? 80; const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent; let formattedDescription; if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) { formattedDescription = description; } else { const wrappedDescription = helper.boxWrap(description, remainingWidth); formattedDescription = wrappedDescription.replace( /\n/g, "\n" + " ".repeat(termWidth + spacerWidth) ); } return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, ` ${itemIndentStr}`); } /** * Wrap a string at whitespace, preserving existing line breaks. * Wrapping is skipped if the width is less than `minWidthToWrap`. * * @param {string} str * @param {number} width * @returns {string} */ boxWrap(str, width) { if (width < this.minWidthToWrap) return str; const rawLines = str.split(/\r\n|\n/); const chunkPattern = /[\s]*[^\s]+/g; const wrappedLines = []; rawLines.forEach((line) => { const chunks = line.match(chunkPattern); if (chunks === null) { wrappedLines.push(""); return; } let sumChunks = [chunks.shift()]; let sumWidth = this.displayWidth(sumChunks[0]); chunks.forEach((chunk) => { const visibleWidth = this.displayWidth(chunk); if (sumWidth + visibleWidth <= width) { sumChunks.push(chunk); sumWidth += visibleWidth; return; } wrappedLines.push(sumChunks.join("")); const nextChunk = chunk.trimStart(); sumChunks = [nextChunk]; sumWidth = this.displayWidth(nextChunk); }); wrappedLines.push(sumChunks.join("")); }); return wrappedLines.join("\n"); } }; function stripColor(str) { const sgrPattern = /\x1b\[\d*(;\d*)*m/g; return str.replace(sgrPattern, ""); } exports2.Help = Help2; exports2.stripColor = stripColor; } }); // node_modules/commander/lib/option.js var require_option = __commonJS({ "node_modules/commander/lib/option.js"(exports2) { var { InvalidArgumentError: InvalidArgumentError2 } = require_error(); var Option2 = class { /** * Initialize a new `Option` with the given `flags` and `description`. * * @param {string} flags * @param {string} [description] */ constructor(flags, description) { this.flags = flags; this.description = description || ""; this.required = flags.includes("<"); this.optional = flags.includes("["); this.variadic = /\w\.\.\.[>\]]$/.test(flags); this.mandatory = false; 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 = void 0; this.defaultValueDescription = void 0; this.presetArg = void 0; this.envVar = void 0; this.parseArg = void 0; this.hidden = false; this.argChoices = void 0; this.conflictsWith = []; this.implied = void 0; this.helpGroupHeading = void 0; } /** * Set the default value, and optionally supply the description to be displayed in the help. * * @param {*} value * @param {string} [description] * @return {Option} */ default(value, description) { this.defaultValue = value; this.defaultValueDescription = description; return this; } /** * 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 {*} arg * @return {Option} */ preset(arg) { this.presetArg = arg; return this; } /** * Add option name(s) that conflict with this option. * An error will be displayed if conflicting options are found during parsing. * * @example * new Option('--rgb').conflicts('cmyk'); * new Option('--js').conflicts(['ts', 'jsx']); * * @param {(string | string[])} names * @return {Option} */ conflicts(names) { this.conflictsWith = this.conflictsWith.concat(names); return this; } /** * Specify implied option values for when this option is set and the implied options are not. * * The custom processing (parseArg) is not called on the implied values. * * @example * program * .addOption(new Option('--log', 'write logging information to file')) * .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' })); * * @param {object} impliedOptionValues * @return {Option} */ implies(impliedOptionValues) { let newImplied = impliedOptionValues; if (typeof impliedOptionValues === "string") { newImplied = { [impliedOptionValues]: true }; } this.implied = Object.assign(this.implied || {}, newImplied); return this; } /** * Set environment variable to check for option value. * * An environment variable is only used if when processed the current option value is * undefined, or the source of the current value is 'default' or 'config' or 'env'. * * @param {string} name * @return {Option} */ env(name) { this.envVar = name; return this; } /** * Set the custom handler for processing CLI option arguments into option values. * * @param {Function} [fn] * @return {Option} */ argParser(fn) { this.parseArg = fn; return this; } /** * Whether the option is mandatory and must have a value after parsing. * * @param {boolean} [mandatory=true] * @return {Option} */ makeOptionMandatory(mandatory = true) { this.mandatory = !!mandatory; return this; } /** * Hide option in help. * * @param {boolean} [hide=true] * @return {Option} */ hideHelp(hide = true) { this.hidden = !!hide; return this; } /** * @package */ _concatValue(value, previous) { if (previous === this.defaultValue || !Array.isArray(previous)) { return [value]; } return previous.concat(value); } /** * Only allow option value to be one of choices. * * @param {string[]} values * @return {Option} */ choices(values) { this.argChoices = values.slice(); this.parseArg = (arg, previous) => { if (!this.argChoices.includes(arg)) { throw new InvalidArgumentError2( `Allowed choices are ${this.argChoices.join(", ")}.` ); } if (this.variadic) { return this._concatValue(arg, previous); } return arg; }; return this; } /** * Return option name. * * @return {string} */ name() { if (this.long) { return this.long.replace(/^--/, ""); } return this.short.replace(/^-/, ""); } /** * Return option name, in a camelcase format that can be used * as an object attribute key. * * @return {string} */ attributeName() { if (this.negate) { return camelcase(this.name().replace(/^no-/, "")); } return camelcase(this.name()); } /** * Set the help group heading. * * @param {string} heading * @return {Option} */ helpGroup(heading) { this.helpGroupHeading = heading; return this; } /** * Check if `arg` matches the short or long flag. * * @param {string} arg * @return {boolean} * @package */ is(arg) { return this.short === arg || this.long === arg; } /** * Return whether a boolean option. * * Options are one of boolean, negated, required argument, or optional argument. * * @return {boolean} * @package */ isBoolean() { return !this.required && !this.optional && !this.negate; } }; var DualOptions = class { /** * @param {Option[]} options */ constructor(options) { this.positiveOptions = /* @__PURE__ */ new Map(); this.negativeOptions = /* @__PURE__ */ new Map(); this.dualOptions = /* @__PURE__ */ new Set(); options.forEach((option) => { if (option.negate) { this.negativeOptions.set(option.attributeName(), option); } else { this.positiveOptions.set(option.attributeName(), option); } }); this.negativeOptions.forEach((value, key) => { if (this.positiveOptions.has(key)) { this.dualOptions.add(key); } }); } /** * Did the value come from the option, and not from possible matching dual option? * * @param {*} value * @param {Option} option * @returns {boolean} */ valueFromOption(value, option) { const optionKey = option.attributeName(); if (!this.dualOptions.has(optionKey)) return true; const preset = this.negativeOptions.get(optionKey).presetArg; const negativeValue = preset !== void 0 ? preset : false; return option.negate === (negativeValue === value); } }; function camelcase(str) { return str.split("-").reduce((str2, word) => { return str2 + word[0].toUpperCase() + word.slice(1); }); } function splitOptionFlags(flags) { let shortFlag; let longFlag; const shortFlagExp = /^-[^-]$/; const longFlagExp = /^--[^-]/; const flagParts = flags.split(/[ |,]+/).concat("guard"); if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift(); if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift(); if (!shortFlag && shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift(); if (!shortFlag && longFlagExp.test(flagParts[0])) { shortFlag = longFlag; longFlag = flagParts.shift(); } if (flagParts[0].startsWith("-")) { const unsupportedFlag = flagParts[0]; const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`; if (/^-[^-][^-]/.test(unsupportedFlag)) throw new Error( `${baseError} - a short flag is a single dash and a single character - either use a single dash and a single character (for a short flag) - or use a double dash for a long option (and can have two, like '--ws, --workspace')` ); if (shortFlagExp.test(unsupportedFlag)) throw new Error(`${baseError} - too many short flags`); if (longFlagExp.test(unsupportedFlag)) throw new Error(`${baseError} - too many long flags`); throw new Error(`${baseError} - unrecognised flag format`); } if (shortFlag === void 0 && longFlag === void 0) throw new Error( `option creation failed due to no flags found in '${flags}'.` ); return { shortFlag, longFlag }; } exports2.Option = Option2; exports2.DualOptions = DualOptions; } }); // node_modules/commander/lib/suggestSimilar.js var require_suggestSimilar = __commonJS({ "node_modules/commander/lib/suggestSimilar.js"(exports2) { var maxDistance = 3; function editDistance(a, b) { if (Math.abs(a.length - b.length) > maxDistance) return Math.ma