commandable.js
1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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;
};