UNPKG

zod-opts

Version:

node.js CLI option parser / validator using Zod

154 lines (153 loc) 6.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateGlobalUsage = generateGlobalUsage; exports.generateGlobalCommandUsage = generateGlobalCommandUsage; exports.generateOptionsText = generateOptionsText; exports.generatePositionalArgumentsText = generatePositionalArgumentsText; exports.generateCommandsText = generateCommandsText; exports.generateGlobalHelp = generateGlobalHelp; exports.generateCommandHelp = generateCommandHelp; exports.generateGlobalCommandHelp = generateGlobalCommandHelp; function getBuiltInOptions(version) { const helpCommand = { name: "help", type: "boolean", required: false, alias: "h", description: "Show help", isArray: false, }; const versionCommand = { name: "version", type: "boolean", required: false, alias: "V", description: "Show version", isArray: false, }; return version === undefined ? [helpCommand] : [helpCommand, versionCommand]; } function addPaddingToTable(rows) { if (rows.length === 0) { return rows; } const colLength = rows[0].length; const colMax = Array.from({ length: colLength }, (_, col) => { const colCells = rows.map((row) => row[col]); return Math.max(...colCells.map((cell) => cell.length)); }); const rowsPadded = rows.map((row) => { return row.map((cell, col) => cell.padEnd(colMax[col])); }); return rowsPadded; } function tableToText(rows) { return rows.map((cells) => cells.join("")).join("\n"); } function generateGlobalUsage(scriptName, positionalArgs, commandName) { const positionalStr = positionalArgs .map((option) => { const inner = option.isArray ? `${option.name} ...` : `${option.name}`; if (option.required) { return `<${inner}>`; } return `[${inner}]`; }) .join(" "); const commandStr = commandName !== undefined ? `${commandName} ` : ""; return `Usage: ${scriptName} ${commandStr}[options] ${positionalStr}`; } function generateGlobalCommandUsage(scriptName) { return `Usage: ${scriptName} [options] <command>`; } function generateDefaultString(option) { return option.defaultValue !== undefined ? `(default: ${JSON.stringify(option.defaultValue)})` : ""; } function generateNameAndArgString(option) { var _a, _b; const arrayStr = option.isArray ? " ..." : ""; switch (option.type) { case "string": return `--${option.name} <${(_a = option.argumentName) !== null && _a !== void 0 ? _a : "string"}${arrayStr}>`; case "number": return `--${option.name} <${(_b = option.argumentName) !== null && _b !== void 0 ? _b : "number"}${arrayStr}>`; case "boolean": return `--${option.name}`; } } function generateChoiceString(option) { if (option.enumValues === undefined) { return ""; } return `(choices: ${option.enumValues.map((s) => `"${s}"`).join(", ")})`; } function generateDescriptionString(option) { var _a; const descriptionStr = (_a = option.description) !== null && _a !== void 0 ? _a : ""; const defaultStr = generateDefaultString(option); const choiceStr = generateChoiceString(option); return `${collapseWhiteSpace([descriptionStr, choiceStr, defaultStr])} `; } function collapseWhiteSpace(words, splitter = " ") { return words.filter((s) => s !== "").join(splitter); } function generateOptionsText(options, indent = 2) { const indentStr = " ".repeat(indent); const table = options.map((option) => { const aliasStr = option.alias !== undefined ? `-${option.alias}, ` : ""; const nameAndArgStr = `${generateNameAndArgString(option)} `; const descriptionStr = generateDescriptionString(option); const requiredStr = option.required ? "[required]" : ""; return [indentStr, aliasStr, nameAndArgStr, descriptionStr, requiredStr]; }); return `Options:\n${tableToText(addPaddingToTable(table))}`; } function generatePositionalArgumentsText(positionalArgs, indent = 2) { if (positionalArgs.length === 0) { return ""; } const indentStr = " ".repeat(indent); const table = positionalArgs.map((arg) => { const nameAndArgStr = `${arg.name} `; const descriptionStr = generateDescriptionString(arg); const requiredStr = arg.required ? "[required]" : ""; return [indentStr, nameAndArgStr, descriptionStr, requiredStr]; }); return `Arguments:\n${tableToText(addPaddingToTable(table))}`; } function generateCommandsText(commands, indent = 2) { const indentStr = " ".repeat(indent); const table = commands.map((command) => { const nameStr = `${command.name} `; const descriptionStr = command.description !== undefined ? `${command.description}` : ""; return [indentStr, nameStr, descriptionStr]; }); return `Commands:\n${tableToText(addPaddingToTable(table))}`; } function generateGlobalHelp({ options, positionalArgs, name, description, version, }) { const globalUsage = generateGlobalUsage(name !== null && name !== void 0 ? name : "program", positionalArgs); const descriptionStr = description !== undefined ? `${description}` : ""; const optionsWithBuildIn = getBuiltInOptions(version).concat(options); const optionsText = generateOptionsText(optionsWithBuildIn); const positionalArgsText = generatePositionalArgumentsText(positionalArgs); return `${collapseWhiteSpace([globalUsage, descriptionStr, positionalArgsText, optionsText], "\n\n")}\n`; } function generateCommandHelp({ command, name, version, }) { const positionalArg = command.positionalArgs; const options = command.options; const globalUsage = generateGlobalUsage(name !== null && name !== void 0 ? name : "script", positionalArg, command.name); const optionsWithBuildIn = getBuiltInOptions(version).concat(options); const descriptionStr = command.description !== undefined ? `${command.description}` : ""; const optionsText = generateOptionsText(optionsWithBuildIn); const positionalArgsText = generatePositionalArgumentsText(positionalArg); return `${collapseWhiteSpace([globalUsage, descriptionStr, positionalArgsText, optionsText], "\n\n")}\n`; } function generateGlobalCommandHelp({ commands, name, description, version, }) { const globalUsage = generateGlobalCommandUsage(name !== null && name !== void 0 ? name : "script"); const descriptionStr = description !== undefined ? `${description}` : ""; const commandsText = generateCommandsText(commands); const optionsText = generateOptionsText(getBuiltInOptions(version)); return `${collapseWhiteSpace([globalUsage, descriptionStr, commandsText, optionsText], "\n\n")}\n`; }