@2fd/command
Version:
Modular command line tool
205 lines (204 loc) • 6.96 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var flags_1 = require('./flags');
var utils_1 = require('./utils');
var SoftCommand = (function () {
function SoftCommand() {
}
/**
* @abstract
*/
SoftCommand.prototype.action = function (input, output) {
throw new Error('Command must be implement action method');
};
/**
* Add option to flag index
*/
SoftCommand.prototype.addFlag = function (flag) {
var _this = this;
flag
.list
.forEach(function (f) {
_this._flags[f] = flag;
});
return this;
};
SoftCommand.prototype.consume = function (input, output) {
var param = input.argv.shift();
param[0] === '-' ?
this.parseFlag(param, input, output) :
this.parseParam(param, input, output);
};
SoftCommand.prototype.hasToConsume = function (input, output) {
return input.argv.length > 0;
};
/**
* Parse input and call action method
*/
SoftCommand.prototype.handle = function (input, output) {
this.initialize();
this.params.before(input, output);
this.flags.forEach(function (flag) { return flag.before(input, output); });
while (this.hasToConsume(input, output))
this.consume(input, output);
if (input.flags[this.helpFlag.name]) {
this.help(input, output);
}
else {
this.params.after(input, output);
this.flags.forEach(function (flag) { return flag.after(input, output); });
this.action(input, output);
}
};
/**
* Print help info from command
*/
SoftCommand.prototype.help = function (input, output) {
var ident = utils_1.repeat(' ', utils_1.TAB_SIZE);
var join = '\n' + ident;
var executable = input.exec.join(' ');
var helps = [];
var styles = [];
helps.push('');
helps.push('%c' + this.helpDescription());
styles.push('color:green');
helps.push('%c' + this.helpUsage(executable));
styles.push(''); // reset styles
this.helpOptions()
.forEach(function (definition) {
var option = definition[0], description = definition[1];
var hasDescription = !!description;
if (!hasDescription) {
helps.push('%c');
helps.push('%c' + option);
styles.push('');
styles.push('color:yellow');
}
else {
helps.push('%c' + option + '%c' + description);
styles.push('color:green');
styles.push(''); // reset styles
}
});
output.log.apply(output, [helps.join(join) + '\n'].concat(styles));
};
/**
* Return command description
*/
SoftCommand.prototype.helpDescription = function () {
if (this.description)
return this.description + '\n';
return '';
};
/**
* Return usage description
*/
SoftCommand.prototype.helpUsage = function (executable) {
var hasFlags = this.flags
.filter(function (flag) { return !!flag.list.length; })
.length;
var options = hasFlags ? '[OPTIONS]' : '';
var paramDefinition = this.params.definition;
return "Usage: " + executable + " " + options + " " + paramDefinition + "\n";
};
/**
* Return flags description
*/
SoftCommand.prototype.helpOptions = function () {
var flags = this.flags
.filter(function (flag) { return !!flag.list.length; });
var flagList = this.flags
.map(function (flag) { return flag.list.join(', '); });
var max = Math.max.apply(Math, flagList.map(function (flags) { return flags.length; }));
var helpFlags = flagList.map(function (flag, i) {
var ident = utils_1.repeat(' ', utils_1.TAB_SIZE);
var space = utils_1.repeat(' ', max - flag.length + utils_1.TAB_SIZE);
return [flag + space, flags[i].description];
});
return [
['[OPTIONS]:']
].concat(helpFlags);
};
/**
* Add option list and help flags to flag index
*/
SoftCommand.prototype.initialize = function () {
var _this = this;
if (this._flags)
return;
this._flags = {};
this.helpFlag = this.helpFlag || new flags_1.HelpFlag;
this.flags.push(this.helpFlag);
this.flags.forEach(function (flag) { return _this.addFlag(flag); });
};
/**
* Call parse method from option in flag index
*/
SoftCommand.prototype.parseFlag = function (flag, input, output) {
this._flags[flag].parse(flag, input, output);
};
/**
*
*/
SoftCommand.prototype.parseParam = function (param, input, output) {
this.params.parse(param, input, output);
};
return SoftCommand;
}());
exports.SoftCommand = SoftCommand;
/**
* Base implementation from command
*/
var Command = (function (_super) {
__extends(Command, _super);
function Command() {
_super.apply(this, arguments);
}
/**
* Add option to flag index
*/
Command.prototype.addFlag = function (flag) {
var _this = this;
var command = this.constructor.name;
flag
.list
.forEach(function (f) {
if (_this._flags[f])
throw new Error("Cannot overwrite flag " + f + " in command " + command);
});
_super.prototype.addFlag.call(this, flag);
return this;
};
Command.prototype.initialize = function () {
if (this._flags)
return;
var command = this.constructor.name;
if (!this.params)
throw new Error('Command must be define params property');
if (!Array.isArray(this.flags))
throw new Error('Command must be define flag list property');
var commands = {};
this
.flags
.forEach(function (flag) {
if (commands[flag.name])
throw new Error("Cannot overwrite flag with name " + flag.name + " in command " + command);
commands[flag.name] = true;
});
_super.prototype.initialize.call(this);
};
/**
* Call parse method from option in flag index
*/
Command.prototype.parseFlag = function (flag, input, output) {
if (!this._flags[flag])
throw new Error('Unexpected option: ' + flag);
_super.prototype.parseFlag.call(this, flag, input, output);
};
return Command;
}(SoftCommand));
exports.Command = Command;