UNPKG

sv

Version:

A CLI for creating and updating SvelteKit projects

1,492 lines (1,485 loc) 382 kB
#!/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