f2e-server3
Version:
f2e-server 3.0
150 lines (149 loc) • 5.13 kB
JavaScript
;
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;