sv
Version:
A CLI for creating and updating SvelteKit projects
1,492 lines (1,485 loc) • 382 kB
JavaScript
#!/usr/bin/env node
import { Element, __commonJS, __require, __toESM, addPnpmBuildDependendencies, box, cancel, confirm, create, detect, esm_exports, from, getUserAgent, group, installDependencies, intro, isCancel, log, multiselect, note, outro, packageManagerPrompt, parseCss, parseHtml as parseHtml$1, parseHtml$1 as parseHtml, parseJson, parseScript, parseSvelte, resolveCommand, select, spinner, templates, text, up, walk_exports } from "./package-manager-Hi1R0gbv.js";
import { __commonJS$1, __export, __toESM$1, addFromString, applyAddons, array_exports, common_exports, createWorkspace, dedent_default, exports_exports, formatFiles, function_exports, getHighlighter, imports_exports, kit_exports, object_exports, require_picocolors, setupAddons, variables_exports } from "./install-C_HkLE-c.js";
import fs, { existsSync } from "node:fs";
import path, { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import process$1 from "node:process";
import { exec, execSync } from "node:child_process";
import { createGunzip } from "node:zlib";
import { pipeline } from "node:stream/promises";
import { promisify } from "node:util";
//#region packages/cli/package.json
var name = "sv";
var version = "0.8.0";
var type = "module";
var description = "A CLI for creating and updating SvelteKit projects";
var license = "MIT";
var repository = {
"type": "git",
"url": "https://github.com/sveltejs/cli",
"directory": "packages/cli"
};
var homepage = "https://svelte.dev";
var scripts = {
"check": "tsc",
"format": "pnpm lint --write",
"lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore"
};
var files = ["dist"];
var bin = "./dist/bin.js";
var exports$1 = {
".": {
"types": "./dist/lib/index.d.ts",
"default": "./dist/index.js"
},
"./testing": {
"types": "./dist/lib/testing.d.ts",
"default": "./dist/testing.js"
}
};
var devDependencies = {
"@sveltejs/addons": "workspace:*",
"@sveltejs/clack-prompts": "workspace:*",
"@sveltejs/cli-core": "workspace:*",
"@sveltejs/create": "workspace:*",
"@types/degit": "^2.8.6",
"@types/ps-tree": "^1.1.6",
"@types/tar-fs": "^2.0.4",
"commander": "^13.0.0",
"degit": "^2.8.4",
"empathic": "^1.0.0",
"package-manager-detector": "^0.2.7",
"picocolors": "^1.1.1",
"ps-tree": "^1.2.0",
"tar-fs": "^3.0.6",
"tinyexec": "^0.3.1",
"valibot": "^0.41.0"
};
var keywords = [
"create",
"new",
"project",
"starter",
"svelte",
"sveltekit",
"template",
"wizard"
];
var package_default = {
name,
version,
type,
description,
license,
repository,
homepage,
scripts,
files,
bin,
exports: exports$1,
devDependencies,
keywords
};
//#endregion
//#region node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/error.js
var require_error = __commonJS({ "node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/error.js"(exports) {
var CommanderError$3 = 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 = undefined;
}
};
var InvalidArgumentError$4 = class extends CommanderError$3 {
/**
* 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;
}
};
exports.CommanderError = CommanderError$3;
exports.InvalidArgumentError = InvalidArgumentError$4;
} });
//#endregion
//#region node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/argument.js
var require_argument = __commonJS({ "node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/argument.js"(exports) {
const { InvalidArgumentError: InvalidArgumentError$3 } = require_error();
var Argument$3 = 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$1, description$1) {
this.description = description$1 || "";
this.variadic = false;
this.parseArg = undefined;
this.defaultValue = undefined;
this.defaultValueDescription = undefined;
this.argChoices = undefined;
switch (name$1[0]) {
case "<":
this.required = true;
this._name = name$1.slice(1, -1);
break;
case "[":
this.required = false;
this._name = name$1.slice(1, -1);
break;
default:
this.required = true;
this._name = name$1;
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$1) {
this.defaultValue = value;
this.defaultValueDescription = description$1;
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 InvalidArgumentError$3(`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;
}
};
/**
* Takes an argument and returns its human readable equivalent for help usage.
*
* @param {Argument} arg
* @return {string}
* @private
*/
function humanReadableArgName$2(arg) {
const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
}
exports.Argument = Argument$3;
exports.humanReadableArgName = humanReadableArgName$2;
} });
//#endregion
//#region node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/help.js
var require_help = __commonJS({ "node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/help.js"(exports) {
const { humanReadableArgName: humanReadableArgName$1 } = require_argument();
var Help$3 = class {
constructor() {
this.helpWidth = undefined;
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((cmd$1) => !cmd$1._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$1(arg)).join(" ");
return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (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 !== undefined) {
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 !== undefined && option.optional) extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
if (option.envVar !== undefined) extraInfo.push(`env: ${option.envVar}`);
if (extraInfo.length > 0) return `${option.description} (${extraInfo.join(", ")})`;
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 !== undefined) 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;
}
/**
* 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$1) {
return helper.formatItem(term, termWidth, description$1, 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)));
});
if (argumentList.length > 0) output = output.concat([
helper.styleTitle("Arguments:"),
...argumentList,
""
]);
const optionList = helper.visibleOptions(cmd).map((option) => {
return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
});
if (optionList.length > 0) output = output.concat([
helper.styleTitle("Options:"),
...optionList,
""
]);
if (helper.showGlobalOptions) {
const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
});
if (globalOptionList.length > 0) output = output.concat([
helper.styleTitle("Global Options:"),
...globalOptionList,
""
]);
}
const commandList = helper.visibleCommands(cmd).map((cmd$1) => {
return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(cmd$1)), helper.styleSubcommandDescription(helper.subcommandDescription(cmd$1)));
});
if (commandList.length > 0) output = output.concat([
helper.styleTitle("Commands:"),
...commandList,
""
]);
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$1(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$1, helper) {
const itemIndent = 2;
const itemIndentStr = " ".repeat(itemIndent);
if (!description$1) 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$1)) formattedDescription = description$1;
else {
const wrappedDescription = helper.boxWrap(description$1, remainingWidth);
formattedDescription = wrappedDescription.replace(/\n/g, "\n" + " ".repeat(termWidth + spacerWidth));
}
return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `\n${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");
}
};
/**
* Strip style ANSI escape sequences from the string. In particular, SGR (Select Graphic Rendition) codes.
*
* @param {string} str
* @returns {string}
* @package
*/
function stripColor$1(str) {
const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
return str.replace(sgrPattern, "");
}
exports.Help = Help$3;
exports.stripColor = stripColor$1;
} });
//#endregion
//#region node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/option.js
var require_option = __commonJS({ "node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/option.js"(exports) {
const { InvalidArgumentError: InvalidArgumentError$2 } = require_error();
var Option$3 = class {
/**
* Initialize a new `Option` with the given `flags` and `description`.
*
* @param {string} flags
* @param {string} [description]
*/
constructor(flags, description$1) {
this.flags = flags;
this.description = description$1 || "";
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 = undefined;
this.defaultValueDescription = undefined;
this.presetArg = undefined;
this.envVar = undefined;
this.parseArg = undefined;
this.hidden = false;
this.argChoices = undefined;
this.conflictsWith = [];
this.implied = undefined;
}
/**
* 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$1) {
this.defaultValue = value;
this.defaultValueDescription = description$1;
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$1) {
this.envVar = name$1;
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 InvalidArgumentError$2(`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());
}
/**
* 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$1 = class {
/**
* @param {Option[]} options
*/
constructor(options$6) {
this.positiveOptions = new Map();
this.negativeOptions = new Map();
this.dualOptions = new Set();
options$6.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 !== undefined ? preset : false;
return option.negate === (negativeValue === value);
}
};
/**
* Convert string from kebab-case to camelCase.
*
* @param {string} str
* @return {string}
* @private
*/
function camelcase(str) {
return str.split("-").reduce((str$1, word) => {
return str$1 + word[0].toUpperCase() + word.slice(1);
});
}
/**
* Split the short and long flag out of something like '-m,--mixed <value>'
*
* @private
*/
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 (/^-[^-][^-]/.test(flagParts[0])) throw new Error(`invalid Option flags, short option is dash and single character: '${flags}'`);
if (shortFlag && shortFlagExp.test(flagParts[0])) throw new Error(`invalid Option flags, more than one short flag: '${flags}'`);
if (longFlag && longFlagExp.test(flagParts[0])) throw new Error(`invalid Option flags, more than one long flag: '${flags}'`);
if (!(shortFlag || longFlag) || flagParts[0].startsWith("-")) throw new Error(`invalid Option flags: '${flags}'`);
return {
shortFlag,
longFlag
};
}
exports.Option = Option$3;
exports.DualOptions = DualOptions$1;
} });
//#endregion
//#region node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/suggestSimilar.js
var require_suggestSimilar = __commonJS({ "node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/suggestSimilar.js"(exports) {
const maxDistance = 3;
function editDistance(a, b) {
if (Math.abs(a.length - b.length) > maxDistance) return Math.max(a.length, b.length);
const d = [];
for (let i = 0; i <= a.length; i++) d[i] = [i];
for (let j = 0; j <= b.length; j++) d[0][j] = j;
for (let j = 1; j <= b.length; j++) for (let i = 1; i <= a.length; i++) {
let cost = 1;
if (a[i - 1] === b[j - 1]) cost = 0;
else cost = 1;
d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
}
return d[a.length][b.length];
}
/**
* Find close matches, restricted to same number of edits.
*
* @param {string} word
* @param {string[]} candidates
* @returns {string}
*/
function suggestSimilar$1(word, candidates) {
if (!candidates || candidates.length === 0) return "";
candidates = Array.from(new Set(candidates));
const searchingOptions = word.startsWith("--");
if (searchingOptions) {
word = word.slice(2);
candidates = candidates.map((candidate) => candidate.slice(2));
}
let similar = [];
let bestDistance = maxDistance;
const minSimilarity = .4;
candidates.forEach((candidate) => {
if (candidate.length <= 1) return;
const distance = editDistance(word, candidate);
const length = Math.max(word.length, candidate.length);
const similarity = (length - distance) / length;
if (similarity > minSimilarity) {
if (distance < bestDistance) {
bestDistance = distance;
similar = [candidate];
} else if (distance === bestDistance) similar.push(candidate);
}
});
similar.sort((a, b) => a.localeCompare(b));
if (searchingOptions) similar = similar.map((candidate) => `--${candidate}`);
if (similar.length > 1) return `\n(Did you mean one of ${similar.join(", ")}?)`;
if (similar.length === 1) return `\n(Did you mean ${similar[0]}?)`;
return "";
}
exports.suggestSimilar = suggestSimilar$1;
} });
//#endregion
//#region node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/command.js
var require_command = __commonJS({ "node_modules/.pnpm/commander@13.0.0/node_modules/commander/lib/command.js"(exports) {
const EventEmitter$1 = __require("node:events").EventEmitter;
const childProcess = __require("node:child_process");
const path$2 = __require("node:path");
const fs$3 = __require("node:fs");
const process$2 = __require("node:process");
const { Argument: Argument$2, humanReadableArgName } = require_argument();
const { CommanderError: CommanderError$2 } = require_error();
const { Help: Help$2, stripColor } = require_help();
const { Option: Option$2, DualOptions } = require_option();
const { suggestSimilar } = require_suggestSimilar();
var Command$2 = class Command$2 extends EventEmitter$1 {
/**
* Initialize a new `Command`.
*
* @param {string} [name]
*/
constructor(name$1) {
super();
/** @type {Command[]} */
this.commands = [];
/** @type {Option[]} */
this.options = [];
this.parent = null;
this._allowUnknownOption = false;
this._allowExcessArguments = false;
/** @type {Argument[]} */
this.registeredArguments = [];
this._args = this.registeredArguments;
/** @type {string[]} */
this.args = [];
this.rawArgs = [];
this.processedArgs = [];
this._scriptPath = null;
this._name = name$1 || "";
this._optionValues = {};
this._optionValueSources = {};
this._storeOptionsAsProperties = false;
this._actionHandler = null;
this._executableHandler = false;
this._executableFile = null;
this._executableDir = null;
this._defaultCommandName = null;
this._exitCallback = null;
this._aliases = [];
this._combineFlagAndOptionalValue = true;
this._description = "";
this._summary = "";
this._argsDescription = undefined;
this._enablePositionalOptions = false;
this._passThroughOptions = false;
this._lifeCycleHooks = {};
/** @type {(boolean | string)} */
this._showHelpAfterError = false;
this._showSuggestionAfterError = true;
this._savedState = null;
this._outputConfiguration = {
writeOut: (str) => process$2.stdout.write(str),
writeErr: (str) => process$2.stderr.write(str),
outputError: (str, write$1) => write$1(str),
getOutHelpWidth: () => process$2.stdout.isTTY ? process$2.stdout.columns : undefined,
getErrHelpWidth: () => process$2.stderr.isTTY ? process$2.stderr.columns : undefined,
getOutHasColors: () => useColor() ?? (process$2.stdout.isTTY && process$2.stdout.hasColors?.()),
getErrHasColors: () => useColor() ?? (process$2.stderr.isTTY && process$2.stderr.hasColors?.()),
stripColor: (str) => stripColor(str)
};
this._hidden = false;
/** @type {(Option | null | undefined)} */
this._helpOption = undefined;
this._addImplicitHelpCommand = undefined;
/** @type {Command} */
this._helpCommand = undefined;
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._helpOption = sourceCommand._helpOption;
this._helpCommand = sourceCommand._helpCommand;
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;
}
/**
* @returns {Command[]}
* @private
*/
_getCommandAndAncestors() {
const result = [];
for (let command = this; command; command = command.parent) result.push(command);
return result;
}
/**
* 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$1, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
const cmd = this.createCommand(name$1);
if (desc) {
cmd.description(desc);
cmd._executableHandler = true;
}
if (opts.isDefault) this._defaultCommandName = cmd._name;
cmd._hidden = !!(opts.noHelp || opts.hidden);
cmd._executableFile = opts.executableFile || null;
if (args) cmd.arguments(args);
this._registerCommand(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$1) {
return new Command$2(name$1);
}
/**
* 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 Help$2(), 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:
*
* // change how output being written, defaults to stdout and stderr
* writeOut(str)
* writeErr(str)
* // change how output being written for errors, defaults to writeErr
* outputError(str, write) // used for displaying errors and not used for displaying help
* // specify width for wrapping help
* getOutHelpWidth()
* getErrHelpWidth()
* // color support, currently only used with Help
* getOutHasColors()
* getErrHasColors()
* stripColor() // used to remove ANSI escape codes if output does not have colors
*
* @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;
this._registerCommand(cmd);
cmd.parent = this;
cmd._checkForBrokenPassThrough();
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$1, description$1) {
return new Argument$2(name$1, description$1);
}
/**
* 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$1, description$1, fn, defaultValue) {
const argument = this.createArgument(name$1, description$1);
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.trim().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.registeredArguments.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.registeredArguments.push(argument);
return this;
}
/**
* Customise or override default help command. By default a help command is automatically added if your command has subcommands.
*
* @example
* program.helpCommand('help [cmd]');
* program.helpCommand('help [cmd]', 'show help');
* program.helpCommand(false); // suppress default help command
* program.helpCommand(true); // add help command even if no subcommands
*
* @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
* @param {string} [description] - custom description
* @return {Command} `this` command for chaining
*/
helpCommand(enableOrNameAndArgs, description$1) {
if (typeof enableOrNameAndArgs === "boolean") {
this._addImplicitHelpCommand = enableOrNameAndArgs;
return this;
}
enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
const helpDescription = description$1 ?? "display help for command";
const helpCommand = this.createCommand(helpName);
helpCommand.helpOption(false);
if (helpArgs) helpCommand.arguments(helpArgs);
if (helpDescription) helpCommand.description(helpDescription);
this._addImplicitHelpCommand = true;
this._helpCommand = helpCommand;
return this;
}
/**
* Add prepared custom help command.
*
* @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
* @param {string} [deprecatedDescription] - deprecated custom description used with custom name only
* @return {Command} `this` command for chaining
*/
addHelpCommand(helpCommand, deprecatedDescription) {
if (typeof helpCommand !== "object") {
this.helpCommand(helpCommand, deprecatedDescription);
return this;
}
this._addImplicitHelpCommand = true;
this._helpCommand = helpCommand;
return this;
}
/**
* Lazy create help command.
*
* @return {(Command|null)}
* @package
*/
_getHelpCommand() {
const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
if (hasImplicitHelpCommand) {
if (this._helpCommand === undefined) this.helpCommand(undefined, undefined);
return this._helpCommand;
}
return null;
}
/**
* 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;
else {}
};
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
* @private
*/
_exit(exitCode, code, message) {
if (this._exitCallback) this._exitCallback(new CommanderError$2(exitCode, code, message));
process$2.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) => {
const expectedArgsCount = this.registeredArguments.length;
const actionArgs = args.slice(0, expectedArgsCount);
if (this._storeOptionsAsProperties) actionArgs[expectedArgsCount] = this;
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