123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
- 'use strict';
- const consola = require('consola');
- const utils = require('consola/utils');
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
- const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
- function toArray(val) {
- if (Array.isArray(val)) {
- return val;
- }
- return val === void 0 ? [] : [val];
- }
- function formatLineColumns(lines, linePrefix = "") {
- const maxLengh = [];
- for (const line of lines) {
- for (const [i, element] of line.entries()) {
- maxLengh[i] = Math.max(maxLengh[i] || 0, element.length);
- }
- }
- return lines.map(
- (l) => l.map(
- (c, i) => linePrefix + c[i === 0 ? "padStart" : "padEnd"](maxLengh[i])
- ).join(" ")
- ).join("\n");
- }
- function resolveValue(input) {
- return typeof input === "function" ? input() : input;
- }
- class CLIError extends Error {
- constructor(message, code) {
- super(message);
- this.code = code;
- this.name = "CLIError";
- }
- }
- const NUMBER_CHAR_RE = /\d/;
- const STR_SPLITTERS = ["-", "_", "/", "."];
- function isUppercase(char = "") {
- if (NUMBER_CHAR_RE.test(char)) {
- return void 0;
- }
- return char !== char.toLowerCase();
- }
- function splitByCase(str, separators) {
- const splitters = separators ?? STR_SPLITTERS;
- const parts = [];
- if (!str || typeof str !== "string") {
- return parts;
- }
- let buff = "";
- let previousUpper;
- let previousSplitter;
- for (const char of str) {
- const isSplitter = splitters.includes(char);
- if (isSplitter === true) {
- parts.push(buff);
- buff = "";
- previousUpper = void 0;
- continue;
- }
- const isUpper = isUppercase(char);
- if (previousSplitter === false) {
- if (previousUpper === false && isUpper === true) {
- parts.push(buff);
- buff = char;
- previousUpper = isUpper;
- continue;
- }
- if (previousUpper === true && isUpper === false && buff.length > 1) {
- const lastChar = buff.at(-1);
- parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
- buff = lastChar + char;
- previousUpper = isUpper;
- continue;
- }
- }
- buff += char;
- previousUpper = isUpper;
- previousSplitter = isSplitter;
- }
- parts.push(buff);
- return parts;
- }
- function upperFirst(str) {
- return str ? str[0].toUpperCase() + str.slice(1) : "";
- }
- function lowerFirst(str) {
- return str ? str[0].toLowerCase() + str.slice(1) : "";
- }
- function pascalCase(str, opts) {
- return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p) => upperFirst(opts?.normalize ? p.toLowerCase() : p)).join("") : "";
- }
- function camelCase(str, opts) {
- return lowerFirst(pascalCase(str || "", opts));
- }
- function kebabCase(str, joiner) {
- return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p) => p.toLowerCase()).join(joiner ?? "-") : "";
- }
- function toArr(any) {
- return any == void 0 ? [] : Array.isArray(any) ? any : [any];
- }
- function toVal(out, key, val, opts) {
- let x;
- const old = out[key];
- const nxt = ~opts.string.indexOf(key) ? val == void 0 || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
- out[key] = old == void 0 ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
- }
- function parseRawArgs(args = [], opts = {}) {
- let k;
- let arr;
- let arg;
- let name;
- let val;
- const out = { _: [] };
- let i = 0;
- let j = 0;
- let idx = 0;
- const len = args.length;
- const alibi = opts.alias !== void 0;
- const strict = opts.unknown !== void 0;
- const defaults = opts.default !== void 0;
- opts.alias = opts.alias || {};
- opts.string = toArr(opts.string);
- opts.boolean = toArr(opts.boolean);
- if (alibi) {
- for (k in opts.alias) {
- arr = opts.alias[k] = toArr(opts.alias[k]);
- for (i = 0; i < arr.length; i++) {
- (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
- }
- }
- }
- for (i = opts.boolean.length; i-- > 0; ) {
- arr = opts.alias[opts.boolean[i]] || [];
- for (j = arr.length; j-- > 0; ) {
- opts.boolean.push(arr[j]);
- }
- }
- for (i = opts.string.length; i-- > 0; ) {
- arr = opts.alias[opts.string[i]] || [];
- for (j = arr.length; j-- > 0; ) {
- opts.string.push(arr[j]);
- }
- }
- if (defaults) {
- for (k in opts.default) {
- name = typeof opts.default[k];
- arr = opts.alias[k] = opts.alias[k] || [];
- if (opts[name] !== void 0) {
- opts[name].push(k);
- for (i = 0; i < arr.length; i++) {
- opts[name].push(arr[i]);
- }
- }
- }
- }
- const keys = strict ? Object.keys(opts.alias) : [];
- for (i = 0; i < len; i++) {
- arg = args[i];
- if (arg === "--") {
- out._ = out._.concat(args.slice(++i));
- break;
- }
- for (j = 0; j < arg.length; j++) {
- if (arg.charCodeAt(j) !== 45) {
- break;
- }
- }
- if (j === 0) {
- out._.push(arg);
- } else if (arg.substring(j, j + 3) === "no-") {
- name = arg.slice(Math.max(0, j + 3));
- if (strict && !~keys.indexOf(name)) {
- return opts.unknown(arg);
- }
- out[name] = false;
- } else {
- for (idx = j + 1; idx < arg.length; idx++) {
- if (arg.charCodeAt(idx) === 61) {
- break;
- }
- }
- name = arg.substring(j, idx);
- val = arg.slice(Math.max(0, ++idx)) || i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i];
- arr = j === 2 ? [name] : name;
- for (idx = 0; idx < arr.length; idx++) {
- name = arr[idx];
- if (strict && !~keys.indexOf(name)) {
- return opts.unknown("-".repeat(j) + name);
- }
- toVal(out, name, idx + 1 < arr.length || val, opts);
- }
- }
- }
- if (defaults) {
- for (k in opts.default) {
- if (out[k] === void 0) {
- out[k] = opts.default[k];
- }
- }
- }
- if (alibi) {
- for (k in out) {
- arr = opts.alias[k] || [];
- while (arr.length > 0) {
- out[arr.shift()] = out[k];
- }
- }
- }
- return out;
- }
- function parseArgs(rawArgs, argsDef) {
- const parseOptions = {
- boolean: [],
- string: [],
- mixed: [],
- alias: {},
- default: {}
- };
- const args = resolveArgs(argsDef);
- for (const arg of args) {
- if (arg.type === "positional") {
- continue;
- }
- if (arg.type === "string") {
- parseOptions.string.push(arg.name);
- } else if (arg.type === "boolean") {
- parseOptions.boolean.push(arg.name);
- }
- if (arg.default !== void 0) {
- parseOptions.default[arg.name] = arg.default;
- }
- if (arg.alias) {
- parseOptions.alias[arg.name] = arg.alias;
- }
- }
- const parsed = parseRawArgs(rawArgs, parseOptions);
- const [...positionalArguments] = parsed._;
- const parsedArgsProxy = new Proxy(parsed, {
- get(target, prop) {
- return target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)];
- }
- });
- for (const [, arg] of args.entries()) {
- if (arg.type === "positional") {
- const nextPositionalArgument = positionalArguments.shift();
- if (nextPositionalArgument !== void 0) {
- parsedArgsProxy[arg.name] = nextPositionalArgument;
- } else if (arg.default === void 0 && arg.required !== false) {
- throw new CLIError(
- `Missing required positional argument: ${arg.name.toUpperCase()}`,
- "EARG"
- );
- } else {
- parsedArgsProxy[arg.name] = arg.default;
- }
- } else if (arg.required && parsedArgsProxy[arg.name] === void 0) {
- throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
- }
- }
- return parsedArgsProxy;
- }
- function resolveArgs(argsDef) {
- const args = [];
- for (const [name, argDef] of Object.entries(argsDef || {})) {
- args.push({
- ...argDef,
- name,
- alias: toArray(argDef.alias)
- });
- }
- return args;
- }
- function defineCommand(def) {
- return def;
- }
- async function runCommand(cmd, opts) {
- const cmdArgs = await resolveValue(cmd.args || {});
- const parsedArgs = parseArgs(opts.rawArgs, cmdArgs);
- const context = {
- rawArgs: opts.rawArgs,
- args: parsedArgs,
- data: opts.data,
- cmd
- };
- if (typeof cmd.setup === "function") {
- await cmd.setup(context);
- }
- let result;
- try {
- const subCommands = await resolveValue(cmd.subCommands);
- if (subCommands && Object.keys(subCommands).length > 0) {
- const subCommandArgIndex = opts.rawArgs.findIndex(
- (arg) => !arg.startsWith("-")
- );
- const subCommandName = opts.rawArgs[subCommandArgIndex];
- if (subCommandName) {
- if (!subCommands[subCommandName]) {
- throw new CLIError(
- `Unknown command \`${subCommandName}\``,
- "E_UNKNOWN_COMMAND"
- );
- }
- const subCommand = await resolveValue(subCommands[subCommandName]);
- if (subCommand) {
- await runCommand(subCommand, {
- rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1)
- });
- }
- } else if (!cmd.run) {
- throw new CLIError(`No command specified.`, "E_NO_COMMAND");
- }
- }
- if (typeof cmd.run === "function") {
- result = await cmd.run(context);
- }
- } finally {
- if (typeof cmd.cleanup === "function") {
- await cmd.cleanup(context);
- }
- }
- return { result };
- }
- async function resolveSubCommand(cmd, rawArgs, parent) {
- const subCommands = await resolveValue(cmd.subCommands);
- if (subCommands && Object.keys(subCommands).length > 0) {
- const subCommandArgIndex = rawArgs.findIndex((arg) => !arg.startsWith("-"));
- const subCommandName = rawArgs[subCommandArgIndex];
- const subCommand = await resolveValue(subCommands[subCommandName]);
- if (subCommand) {
- return resolveSubCommand(
- subCommand,
- rawArgs.slice(subCommandArgIndex + 1),
- cmd
- );
- }
- }
- return [cmd, parent];
- }
- async function showUsage(cmd, parent) {
- try {
- consola__default.log(await renderUsage(cmd, parent) + "\n");
- } catch (error) {
- consola__default.error(error);
- }
- }
- async function renderUsage(cmd, parent) {
- const cmdMeta = await resolveValue(cmd.meta || {});
- const cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));
- const parentMeta = await resolveValue(parent?.meta || {});
- const commandName = `${parentMeta.name ? `${parentMeta.name} ` : ""}` + (cmdMeta.name || process.argv[1]);
- const argLines = [];
- const posLines = [];
- const commandsLines = [];
- const usageLine = [];
- for (const arg of cmdArgs) {
- if (arg.type === "positional") {
- const name = arg.name.toUpperCase();
- const isRequired = arg.required !== false && arg.default === void 0;
- const defaultHint = arg.default ? `="${arg.default}"` : "";
- posLines.push([
- "`" + name + defaultHint + "`",
- arg.description || "",
- arg.valueHint ? `<${arg.valueHint}>` : ""
- ]);
- usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
- } else {
- const isRequired = arg.required === true && arg.default === void 0;
- const argStr = (arg.type === "boolean" && arg.default === true ? [
- ...(arg.alias || []).map((a) => `--no-${a}`),
- `--no-${arg.name}`
- ].join(", ") : [...(arg.alias || []).map((a) => `-${a}`), `--${arg.name}`].join(
- ", "
- )) + (arg.type === "string" && (arg.valueHint || arg.default) ? `=${arg.valueHint ? `<${arg.valueHint}>` : `"${arg.default || ""}"`}` : "");
- argLines.push([
- "`" + argStr + (isRequired ? " (required)" : "") + "`",
- arg.description || ""
- ]);
- if (isRequired) {
- usageLine.push(argStr);
- }
- }
- }
- if (cmd.subCommands) {
- const commandNames = [];
- const subCommands = await resolveValue(cmd.subCommands);
- for (const [name, sub] of Object.entries(subCommands)) {
- const subCmd = await resolveValue(sub);
- const meta = await resolveValue(subCmd?.meta);
- commandsLines.push([`\`${name}\``, meta?.description || ""]);
- commandNames.push(name);
- }
- usageLine.push(commandNames.join("|"));
- }
- const usageLines = [];
- const version = cmdMeta.version || parentMeta.version;
- usageLines.push(
- utils.colors.gray(
- `${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`
- ),
- ""
- );
- const hasOptions = argLines.length > 0 || posLines.length > 0;
- usageLines.push(
- `${utils.colors.underline(utils.colors.bold("USAGE"))} \`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}\``,
- ""
- );
- if (posLines.length > 0) {
- usageLines.push(utils.colors.underline(utils.colors.bold("ARGUMENTS")), "");
- usageLines.push(formatLineColumns(posLines, " "));
- usageLines.push("");
- }
- if (argLines.length > 0) {
- usageLines.push(utils.colors.underline(utils.colors.bold("OPTIONS")), "");
- usageLines.push(formatLineColumns(argLines, " "));
- usageLines.push("");
- }
- if (commandsLines.length > 0) {
- usageLines.push(utils.colors.underline(utils.colors.bold("COMMANDS")), "");
- usageLines.push(formatLineColumns(commandsLines, " "));
- usageLines.push(
- "",
- `Use \`${commandName} <command> --help\` for more information about a command.`
- );
- }
- return usageLines.filter((l) => typeof l === "string").join("\n");
- }
- async function runMain(cmd, opts = {}) {
- const rawArgs = opts.rawArgs || process.argv.slice(2);
- const showUsage$1 = opts.showUsage || showUsage;
- try {
- if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
- await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
- process.exit(0);
- } else if (rawArgs.length === 1 && rawArgs[0] === "--version") {
- const meta = typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
- if (!meta?.version) {
- throw new CLIError("No version specified", "E_NO_VERSION");
- }
- consola__default.log(meta.version);
- } else {
- await runCommand(cmd, { rawArgs });
- }
- } catch (error) {
- const isCLIError = error instanceof CLIError;
- if (!isCLIError) {
- consola__default.error(error, "\n");
- }
- if (isCLIError) {
- await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
- }
- consola__default.error(error.message);
- process.exit(1);
- }
- }
- function createMain(cmd) {
- return (opts = {}) => runMain(cmd, opts);
- }
- exports.createMain = createMain;
- exports.defineCommand = defineCommand;
- exports.parseArgs = parseArgs;
- exports.renderUsage = renderUsage;
- exports.runCommand = runCommand;
- exports.runMain = runMain;
- exports.showUsage = showUsage;
|