69 lines
1.8 KiB
JavaScript
69 lines
1.8 KiB
JavaScript
|
var nopt = require('nopt');
|
||
|
|
||
|
// Commandable Mixin
|
||
|
//
|
||
|
// Provides API to route arbitrary routes or register command / sub commands /
|
||
|
// sub programs.
|
||
|
var commandable = module.exports;
|
||
|
|
||
|
// XXX: tomdocify, generate in readme
|
||
|
|
||
|
commandable.cmd =
|
||
|
commandable.command = function command(name, fn) {
|
||
|
this._commands[name] = fn;
|
||
|
var commandable = fn && fn.command && fn.route && fn.parse;
|
||
|
this.on(name, commandable ? function(args, opts, position) {
|
||
|
fn.parse(args, position);
|
||
|
} : fn);
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
commandable.route = function route(pattern, fn) {
|
||
|
pattern = pattern instanceof RegExp ? pattern : new RegExp('^' + pattern + '$');
|
||
|
this._routes.push({
|
||
|
pattern: pattern,
|
||
|
fn: fn
|
||
|
});
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
commandable.routeCommand = function routeCommand(opts) {
|
||
|
opts = opts || this.nopt;
|
||
|
var args = opts.argv.remain;
|
||
|
var commands = Object.keys(this._commands);
|
||
|
|
||
|
// firt try to find a route, then fallback to command
|
||
|
var route = this._routes.filter(function(route) {
|
||
|
return route.pattern.test(args.join(' '));
|
||
|
});
|
||
|
|
||
|
if(route.length) return route[0].fn();
|
||
|
|
||
|
var first = 0
|
||
|
var registered = args.filter(function(arg, i) {
|
||
|
var match = ~commands.indexOf(arg);
|
||
|
if(match) first = first || i;
|
||
|
return match;
|
||
|
});
|
||
|
|
||
|
if(!registered[0]) return this.run();
|
||
|
|
||
|
opts.argv.remain = args.slice(0, first);
|
||
|
registered.forEach(function(command) {
|
||
|
var position = opts.argv.original.indexOf(command) + 1;
|
||
|
var options = nopt({}, {}, opts.argv.original, position);
|
||
|
this.emit(command, options.argv.original, options, position);
|
||
|
}, this);
|
||
|
};
|
||
|
|
||
|
|
||
|
commandable.registered = function(args) {
|
||
|
var commands = Object.keys(this._commands);
|
||
|
var registered = args.filter(function(arg, i) {
|
||
|
return ~commands.indexOf(arg);
|
||
|
});
|
||
|
|
||
|
return registered.length ? this._commands[registered] : false;
|
||
|
};
|
||
|
|