-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
125 lines (106 loc) · 2.72 KB
/
index.js
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use strict';
var UnsafeCommand = require('commander').Command;
var Option = require('commander').Option;
function Command(name) {
UnsafeCommand.call(this, name);
this.optsObj = {}; // options Store
}
Command.prototype = Object.create(UnsafeCommand.prototype, {
constructor: {
configurable: true,
enumerable: true,
value: Command,
writable: true
}
});
Command.prototype.option = function(flags, description, fn, defaultValue) {
var self = this.optsObj
, option = new Option(flags, description)
, oname = option.name()
, name = camelcase(oname);
// default as 3rd arg
if (typeof fn != 'function') {
if (fn instanceof RegExp) {
var regex = fn;
fn = function(val, def) {
var m = regex.exec(val);
return m ? m[0] : def;
}
}
else {
defaultValue = fn;
fn = null;
}
}
// preassign default value only for --no-*, [optional], or <required>
if (false == option.bool || option.optional || option.required) {
// when --no-* we make sure default is true
if (false == option.bool) defaultValue = true;
// preassign only if we have a default
if (undefined !== defaultValue) self[name] = defaultValue;
}
// register the option
this.options.push(option);
// when it's passed assign the value
// and conditionally invoke the callback
this.on('option:' + oname, function(val) {
// coercion
if (null !== val && fn) val = fn(val, undefined === self[name]
? defaultValue
: self[name]);
// unassigned or bool
if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) {
// if no value, bool true, and we have a default, then use it!
if (null == val) {
self[name] = option.bool
? defaultValue || true
: false;
} else {
self[name] = val;
}
} else if (null !== val) {
// reassign
self[name] = val;
}
});
return this;
}
/**
* Return an object containing options as key-value pairs
*
* @return {Object}
* @api public
*/
Command.prototype.opts = function() {
var result = {}
, len = this.options.length;
for (var i = 0 ; i < len; i++) {
var key = camelcase(this.options[i].name());
result[key] = key === 'version' ? this._version : this.optsObj[key];
}
return result;
};
/**
* Camel-case the given `flag`
*
* @param {String} flag
* @return {String}
* @api private
*/
function camelcase(flag) {
return flag.split('-').reduce(function(str, word) {
return str + word[0].toUpperCase() + word.slice(1);
});
}
/**
* Expose the root command.
*/
exports = module.exports = new Command();
/**
* Expose `Command`.
*/
exports.Command = Command;
/**
* Expose `Option`.
*/
exports.Option = Option;