UNPKG

f2e-server3

Version:

f2e-server 3.0

150 lines (149 loc) 5.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Command = void 0; const node_process_1 = require("node:process"); class Command { options = []; commands = new Map(); name; subname; _version = ''; _description = ''; constructor(name) { this.name = name; } version(v) { this._version = v; return this; } command(name) { if (this.subname) { throw new Error('subcommand already defined'); } const [name1, name2] = name.split(/[\s\t]+/); const c = new Command(name1); if (name2) { if (/^<(.*?)>$/.test(name2)) { c.subname = name2.slice(1, -1); } else { throw new Error('invalid subcommand name'); } } this.commands.set(name1, c); return c; } description(description) { this._description = description; return this; } option(name_all, description, defaultValue, values) { const [short, name, arg] = name_all.split(/[\s\t,]+/); const o = { name, short, argument: arg.slice(1, arg.length - 1), description, defaultValue, values: values && Array.from(values), }; const t = this; t.options.push(o); return t; } actions = []; action(ac) { this.actions.push(ac); return this; } async parse(argv) { const { commands } = this; const result = {}; let command = this; for (let i = 2; i < argv.length; i++) { const item = argv[i]; const next = argv[i + 1]; switch (item) { case '-V': case '--version': console.log(command._version); (0, node_process_1.exit)(0); case '-h': case '--help': console.log(command.showHelp()); (0, node_process_1.exit)(0); default: } if (item.startsWith('-')) { const op = command.options.find(o => o.short === item || o.name === item); if (op) { const type = typeof (op.defaultValue || ''); if (!next.startsWith('-')) { const value = type === 'string' ? next : JSON.parse(next); if (op.values && op.values.indexOf(value) === -1) { console.error(`Invalid value "${value}" for option "${op.name}", expected one of "${op.values}"`); (0, node_process_1.exit)(1); } result[op.argument] = value; i++; } else if (type === 'boolean') { result[op.argument] = true; } else { console.error(`Missing value for option "${op.name}"`); (0, node_process_1.exit)(1); } } else { console.log(`Unknown option "${item}"`); (0, node_process_1.exit)(1); } } else { const cmd = commands.get(item); if (!cmd) { console.error(`Unknown command "${item}"`); (0, node_process_1.exit)(1); } else { command = cmd; if (command.subname) { result[command.subname] = next; i++; } } } } for (let i = 0; i < command.options.length; i++) { const op = command.options[i]; if (op.defaultValue && !(op.argument in result)) { result[op.argument] = op.defaultValue; } } for (let i = 0; i < command.actions.length; i++) { command.actions[i](result); } } showHelp() { const { name, subname, _version, _description } = this; const options = this.options.slice(0); const commands = [...this.commands.values()]; if (_version) { options.push({ name: '--version', short: '-V', description: 'Show version number', argument: '' }); } options.push({ name: '--help', short: '-h', description: 'Show help', argument: '' }); return [ `Usage: ${name} [options] ${_description || ''}`, ` Options: ${options.map(option => ` ${option.short}, ${option.name}\t\t${option.description}`).join('\n')} `, commands.length > 0 && ` Commands: ${commands.map(cmd => ` ${cmd.name}${subname ? ` <${subname}>` : ''}${cmd.options.length > 0 ? ' [options]' : ' '}\t${cmd._description}`).join('\n')} ` ].filter(l => !!l).join('\n'); } } exports.Command = Command;