Skip to content

Commit 84f6bc1

Browse files
committed
refactor: rewrite~!
- Closes lukeed#4
1 parent b19beb2 commit 84f6bc1

1 file changed

Lines changed: 67 additions & 111 deletions

File tree

lib/index.js

Lines changed: 67 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,111 @@
1-
'use strict';
2-
3-
const EQQ = /\s|=/;
4-
const FLAG = /^-{1,2}/;
5-
const PREFIX = /^--no-/i;
6-
7-
function isBool(any) {
8-
return typeof any === 'boolean';
9-
}
10-
111
function toArr(any) {
12-
return Array.isArray(any) ? any : any == null ? [] : [any];
13-
}
14-
15-
function toString(any) {
16-
return any == null || any === true ? '' : String(any);
17-
}
18-
19-
function toBool(any) {
20-
return any === 'false' ? false : Boolean(any);
2+
return any == null ? [] : Array.isArray(any) ? any : [any];
213
}
224

23-
function toNum(any) {
24-
let x = Number(any);
25-
return !isBool(any) && (x * 0 === 0) ? x : any;
5+
function toVal(out, key, val, opts) {
6+
var x, old=out[key], nxt=(
7+
!!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val))
8+
: !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val))
9+
: typeof val === 'boolean' ? val
10+
: (x = +val,x * 0 === 0) ? x : val
11+
);
12+
out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]);
2613
}
2714

28-
function getAlibi(names, arr) {
29-
if (arr.length === 0) return arr;
30-
let k, i = 0, len = arr.length, vals = [];
31-
for (; i < len; i++) {
32-
k = arr[i];
33-
vals.push(k);
34-
if (names[k] !== void 0) {
35-
vals = vals.concat(names[k]);
36-
}
37-
}
38-
return vals;
39-
}
40-
41-
function typecast(key, val, strings, booleans) {
42-
if (strings.indexOf(key) !== -1) return toString(val);
43-
if (booleans.indexOf(key) !== -1) return toBool(val);
44-
return toNum(val);
45-
}
46-
47-
module.exports = function(args, opts) {
15+
module.exports = function (args, opts) {
4816
args = args || [];
4917
opts = opts || {};
5018

19+
var k, arr, arg, name, val, out={ _:[] };
20+
var i=0, j=0, idx=0, len=args.length;
21+
22+
const alibi = opts.alias !== void 0;
23+
const strict = opts.unknown !== void 0;
24+
const defaults = opts.default !== void 0;
25+
26+
opts.alias = opts.alias || {};
5127
opts.string = toArr(opts.string);
5228
opts.boolean = toArr(opts.boolean);
5329

54-
const aliases = {};
55-
let k, i, j, x, y, len, type;
56-
57-
if (opts.alias !== void 0) {
30+
if (alibi) {
5831
for (k in opts.alias) {
59-
aliases[k] = toArr(opts.alias[k]);
60-
len = aliases[k].length; // save length
61-
for (i = 0; i < len; i++) {
62-
x = aliases[k][i]; // alias's key name
63-
aliases[x] = [k]; // set initial array
64-
for (j = 0; j < len; j++) {
65-
if (x !== aliases[k][j]) {
66-
aliases[x].push(aliases[k][j]);
67-
}
68-
}
32+
arr = opts.alias[k] = toArr(opts.alias[k]);
33+
for (i=0; i < arr.length; i++) {
34+
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
6935
}
7036
}
7137
}
7238

73-
if (opts.default !== void 0) {
39+
opts.boolean.forEach(key => {
40+
opts.boolean = opts.boolean.concat(opts.alias[key] = opts.alias[key] || []);
41+
});
42+
43+
opts.string.forEach(key => {
44+
opts.string = opts.string.concat(opts.alias[key] = opts.alias[key] || []);
45+
});
46+
47+
if (defaults) {
7448
for (k in opts.default) {
75-
type = typeof opts.default[k];
76-
opts[type] = (opts[type] || []).concat(k);
49+
opts.alias[k] = opts.alias[k] || [];
50+
opts[typeof opts.default[k]].push(k);
7751
}
7852
}
7953

80-
// apply to all aliases
81-
opts.string = getAlibi(aliases, opts.string);
82-
opts.boolean = getAlibi(aliases, opts.boolean);
54+
const keys = strict ? Object.keys(opts.alias) : [];
8355

84-
let idx = 0;
85-
const out = { _: [] };
56+
for (i=0; i < len; i++) {
57+
arg = args[i];
8658

87-
while (args[idx] !== void 0) {
88-
let incr = 1;
89-
const val = args[idx];
90-
91-
if (val === '--') {
92-
out._ = out._.concat(args.slice(idx + 1));
59+
if (arg === '--') {
60+
out._ = out._.concat(args.slice(++i));
9361
break;
94-
} else if (!FLAG.test(val)) {
95-
out._.push(val);
96-
} else if (PREFIX.test(val)) {
97-
out[val.replace(PREFIX, '')] = false;
98-
} else {
99-
let tmp;
100-
const segs = val.split(EQQ);
101-
const isGroup = segs[0].charCodeAt(1) !== 45; // '-'
102-
103-
const flag = segs[0].substr(isGroup ? 1 : 2);
104-
len = flag.length;
105-
const key = isGroup ? flag[len - 1] : flag;
62+
}
10663

107-
if (opts.unknown !== void 0 && aliases[key] === void 0) {
108-
return opts.unknown(segs[0]);
109-
}
64+
for (j=0; j < arg.length; j++) {
65+
if (arg.charCodeAt(j) !== 45) break; // "-"
66+
}
11067

111-
if (segs.length > 1) {
112-
tmp = segs[1];
113-
} else {
114-
tmp = args[idx + 1] || true;
115-
FLAG.test(tmp) ? (tmp = true) : (incr = 2);
68+
if (j === 0) {
69+
out._.push(arg);
70+
} else if (arg.substring(j, j + 3) === 'no-') {
71+
name = arg.substring(j + 3);
72+
if (strict && !~keys.indexOf(name)) {
73+
return opts.unknown(name);
11674
}
117-
118-
if (isGroup && len > 1) {
119-
for (i = len - 1; i--; ) {
120-
k = flag[i]; // all but last key
121-
out[k] = typecast(k, true, opts.string, opts.boolean);
122-
}
75+
out[name] = false;
76+
} else {
77+
for (idx=j+1; idx < arg.length; idx++) {
78+
if (arg.charCodeAt(idx) === 61) break; // "="
12379
}
12480

125-
const value = typecast(key, tmp, opts.string, opts.boolean);
126-
out[key] = out[key] !== void 0 ? toArr(out[key]).concat(value) : value;
81+
name = arg.substring(j, idx);
82+
val = arg.substring(++idx) || (i+1 === len || args[i+1].charCodeAt(0) === 45 || args[++i]);
83+
arr = (j === 2 ? [name] : name);
12784

128-
// handle discarded args when dealing with booleans
129-
if (isBool(value) && !isBool(tmp) && tmp !== 'true' && tmp !== 'false') {
130-
out._.push(tmp);
85+
for (j=0; j < arr.length; j++) {
86+
name = arr[j];
87+
if (strict && !~keys.indexOf(name)) return opts.unknown(name);
88+
toVal(out, name, (j + 1 < arr.length) || val, opts);
13189
}
13290
}
133-
134-
idx += incr;
13591
}
13692

137-
if (opts.default !== void 0) {
93+
if (defaults) {
13894
for (k in opts.default) {
13995
if (out[k] === void 0) {
14096
out[k] = opts.default[k];
14197
}
14298
}
14399
}
144100

145-
for (k in out) {
146-
if (aliases[k] === void 0) continue;
147-
y = out[k];
148-
len = aliases[k].length;
149-
for (i = 0; i < len; i++) {
150-
out[aliases[k][i]] = y; // assign value
101+
if (alibi) {
102+
for (k in out) {
103+
arr = opts.alias[k] || [];
104+
while (arr.length > 0) {
105+
out[arr.shift()] = out[k];
106+
}
151107
}
152108
}
153109

154110
return out;
155-
};
111+
}

0 commit comments

Comments
 (0)