breadc 0.3.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/dist/index.cjs +14 -262
- package/dist/index.d.ts +22 -267
- package/dist/index.mjs +13 -261
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
Yet another Command Line Application Framework powered by [minimist](https://www.npmjs.com/package/minimist), but with fully strong [TypeScript](https://www.typescriptlang.org/) support.
|
|
6
6
|
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
+ ⚡️ **Light-weight**: Only 61 kB.
|
|
10
|
+
+ 📖 **East to Learn**: Breadc is basically compatible with [cac](https://github.com/cacjs/cac) and there are only 4 APIs for building a CLI application: `command`, `option`, `action`, `run`.
|
|
11
|
+
+ 💻 **TypeScript Infer**: IDE will automatically infer the type of your command action function.
|
|
12
|
+
|
|
7
13
|
## Installation
|
|
8
14
|
|
|
9
15
|
```bash
|
|
@@ -18,11 +24,11 @@ Try [./examples/echo.ts](./examples/echo.ts).
|
|
|
18
24
|
import Breadc from 'breadc'
|
|
19
25
|
|
|
20
26
|
const cli = Breadc('echo', { version: '1.0.0' })
|
|
21
|
-
.option('--host
|
|
22
|
-
.option('--port
|
|
27
|
+
.option('--host [host]', { default: 'localhost' })
|
|
28
|
+
.option('--port [port]', { construct: (port) => (port ? +port : 3000) });
|
|
23
29
|
|
|
24
30
|
cli
|
|
25
|
-
.command('[message]')
|
|
31
|
+
.command('[message]', 'Say something!')
|
|
26
32
|
.action((message, option) => {
|
|
27
33
|
const host = option.host;
|
|
28
34
|
const port = option.port;
|
|
@@ -34,7 +40,7 @@ cli.run(process.argv.slice(2))
|
|
|
34
40
|
.catch(err => cli.logger.error(err.message))
|
|
35
41
|
```
|
|
36
42
|
|
|
37
|
-
If you are using IDEs that support TypeScript (like [Visual Studio Code](https://code.visualstudio.com/)),
|
|
43
|
+
If you are using IDEs that support TypeScript (like [Visual Studio Code](https://code.visualstudio.com/)), input something using `option`, and then you will find the `option` is automatically typed with `{ host: string, port: number }`. In the figure below, [Visual Studio Code](https://code.visualstudio.com/) will automatically infer that the type of `option.host` is `string` and the type of `option.port` is `number`.
|
|
38
44
|
|
|
39
45
|

|
|
40
46
|
|
package/dist/index.cjs
CHANGED
|
@@ -3,260 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
const kolorist = require('kolorist');
|
|
6
|
+
const minimist = require('minimist');
|
|
6
7
|
|
|
7
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
|
8
9
|
|
|
9
10
|
const kolorist__default = /*#__PURE__*/_interopDefaultLegacy(kolorist);
|
|
10
|
-
|
|
11
|
-
var minimist = function (args, opts) {
|
|
12
|
-
if (!opts) opts = {};
|
|
13
|
-
|
|
14
|
-
var flags = { bools : {}, strings : {}, unknownFn: null };
|
|
15
|
-
|
|
16
|
-
if (typeof opts['unknown'] === 'function') {
|
|
17
|
-
flags.unknownFn = opts['unknown'];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
|
|
21
|
-
flags.allBools = true;
|
|
22
|
-
} else {
|
|
23
|
-
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
|
|
24
|
-
flags.bools[key] = true;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
var aliases = {};
|
|
29
|
-
Object.keys(opts.alias || {}).forEach(function (key) {
|
|
30
|
-
aliases[key] = [].concat(opts.alias[key]);
|
|
31
|
-
aliases[key].forEach(function (x) {
|
|
32
|
-
aliases[x] = [key].concat(aliases[key].filter(function (y) {
|
|
33
|
-
return x !== y;
|
|
34
|
-
}));
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
[].concat(opts.string).filter(Boolean).forEach(function (key) {
|
|
39
|
-
flags.strings[key] = true;
|
|
40
|
-
if (aliases[key]) {
|
|
41
|
-
flags.strings[aliases[key]] = true;
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
var defaults = opts['default'] || {};
|
|
46
|
-
|
|
47
|
-
var argv = { _ : [] };
|
|
48
|
-
Object.keys(flags.bools).forEach(function (key) {
|
|
49
|
-
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
var notFlags = [];
|
|
53
|
-
|
|
54
|
-
if (args.indexOf('--') !== -1) {
|
|
55
|
-
notFlags = args.slice(args.indexOf('--')+1);
|
|
56
|
-
args = args.slice(0, args.indexOf('--'));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function argDefined(key, arg) {
|
|
60
|
-
return (flags.allBools && /^--[^=]+$/.test(arg)) ||
|
|
61
|
-
flags.strings[key] || flags.bools[key] || aliases[key];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function setArg (key, val, arg) {
|
|
65
|
-
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
|
66
|
-
if (flags.unknownFn(arg) === false) return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
var value = !flags.strings[key] && isNumber(val)
|
|
70
|
-
? Number(val) : val
|
|
71
|
-
;
|
|
72
|
-
setKey(argv, key.split('.'), value);
|
|
73
|
-
|
|
74
|
-
(aliases[key] || []).forEach(function (x) {
|
|
75
|
-
setKey(argv, x.split('.'), value);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function setKey (obj, keys, value) {
|
|
80
|
-
var o = obj;
|
|
81
|
-
for (var i = 0; i < keys.length-1; i++) {
|
|
82
|
-
var key = keys[i];
|
|
83
|
-
if (isConstructorOrProto(o, key)) return;
|
|
84
|
-
if (o[key] === undefined) o[key] = {};
|
|
85
|
-
if (o[key] === Object.prototype || o[key] === Number.prototype
|
|
86
|
-
|| o[key] === String.prototype) o[key] = {};
|
|
87
|
-
if (o[key] === Array.prototype) o[key] = [];
|
|
88
|
-
o = o[key];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
var key = keys[keys.length - 1];
|
|
92
|
-
if (isConstructorOrProto(o, key)) return;
|
|
93
|
-
if (o === Object.prototype || o === Number.prototype
|
|
94
|
-
|| o === String.prototype) o = {};
|
|
95
|
-
if (o === Array.prototype) o = [];
|
|
96
|
-
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
|
|
97
|
-
o[key] = value;
|
|
98
|
-
}
|
|
99
|
-
else if (Array.isArray(o[key])) {
|
|
100
|
-
o[key].push(value);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
o[key] = [ o[key], value ];
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function aliasIsBoolean(key) {
|
|
108
|
-
return aliases[key].some(function (x) {
|
|
109
|
-
return flags.bools[x];
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
for (var i = 0; i < args.length; i++) {
|
|
114
|
-
var arg = args[i];
|
|
115
|
-
|
|
116
|
-
if (/^--.+=/.test(arg)) {
|
|
117
|
-
// Using [\s\S] instead of . because js doesn't support the
|
|
118
|
-
// 'dotall' regex modifier. See:
|
|
119
|
-
// http://stackoverflow.com/a/1068308/13216
|
|
120
|
-
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
|
121
|
-
var key = m[1];
|
|
122
|
-
var value = m[2];
|
|
123
|
-
if (flags.bools[key]) {
|
|
124
|
-
value = value !== 'false';
|
|
125
|
-
}
|
|
126
|
-
setArg(key, value, arg);
|
|
127
|
-
}
|
|
128
|
-
else if (/^--no-.+/.test(arg)) {
|
|
129
|
-
var key = arg.match(/^--no-(.+)/)[1];
|
|
130
|
-
setArg(key, false, arg);
|
|
131
|
-
}
|
|
132
|
-
else if (/^--.+/.test(arg)) {
|
|
133
|
-
var key = arg.match(/^--(.+)/)[1];
|
|
134
|
-
var next = args[i + 1];
|
|
135
|
-
if (next !== undefined && !/^-/.test(next)
|
|
136
|
-
&& !flags.bools[key]
|
|
137
|
-
&& !flags.allBools
|
|
138
|
-
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
139
|
-
setArg(key, next, arg);
|
|
140
|
-
i++;
|
|
141
|
-
}
|
|
142
|
-
else if (/^(true|false)$/.test(next)) {
|
|
143
|
-
setArg(key, next === 'true', arg);
|
|
144
|
-
i++;
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
else if (/^-[^-]+/.test(arg)) {
|
|
151
|
-
var letters = arg.slice(1,-1).split('');
|
|
152
|
-
|
|
153
|
-
var broken = false;
|
|
154
|
-
for (var j = 0; j < letters.length; j++) {
|
|
155
|
-
var next = arg.slice(j+2);
|
|
156
|
-
|
|
157
|
-
if (next === '-') {
|
|
158
|
-
setArg(letters[j], next, arg);
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
|
163
|
-
setArg(letters[j], next.split('=')[1], arg);
|
|
164
|
-
broken = true;
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (/[A-Za-z]/.test(letters[j])
|
|
169
|
-
&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
|
|
170
|
-
setArg(letters[j], next, arg);
|
|
171
|
-
broken = true;
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (letters[j+1] && letters[j+1].match(/\W/)) {
|
|
176
|
-
setArg(letters[j], arg.slice(j+2), arg);
|
|
177
|
-
broken = true;
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
var key = arg.slice(-1)[0];
|
|
186
|
-
if (!broken && key !== '-') {
|
|
187
|
-
if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
|
|
188
|
-
&& !flags.bools[key]
|
|
189
|
-
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
190
|
-
setArg(key, args[i+1], arg);
|
|
191
|
-
i++;
|
|
192
|
-
}
|
|
193
|
-
else if (args[i+1] && /^(true|false)$/.test(args[i+1])) {
|
|
194
|
-
setArg(key, args[i+1] === 'true', arg);
|
|
195
|
-
i++;
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
|
204
|
-
argv._.push(
|
|
205
|
-
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
if (opts.stopEarly) {
|
|
209
|
-
argv._.push.apply(argv._, args.slice(i + 1));
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
Object.keys(defaults).forEach(function (key) {
|
|
216
|
-
if (!hasKey(argv, key.split('.'))) {
|
|
217
|
-
setKey(argv, key.split('.'), defaults[key]);
|
|
218
|
-
|
|
219
|
-
(aliases[key] || []).forEach(function (x) {
|
|
220
|
-
setKey(argv, x.split('.'), defaults[key]);
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
if (opts['--']) {
|
|
226
|
-
argv['--'] = new Array();
|
|
227
|
-
notFlags.forEach(function(key) {
|
|
228
|
-
argv['--'].push(key);
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
notFlags.forEach(function(key) {
|
|
233
|
-
argv._.push(key);
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return argv;
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
function hasKey (obj, keys) {
|
|
241
|
-
var o = obj;
|
|
242
|
-
keys.slice(0,-1).forEach(function (key) {
|
|
243
|
-
o = (o[key] || {});
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
var key = keys[keys.length - 1];
|
|
247
|
-
return key in o;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function isNumber (x) {
|
|
251
|
-
if (typeof x === 'number') return true;
|
|
252
|
-
if (/^0x[0-9a-f]+$/i.test(x)) return true;
|
|
253
|
-
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
function isConstructorOrProto (obj, key) {
|
|
258
|
-
return key === 'constructor' && typeof obj[key] === 'function' || key === '__proto__';
|
|
259
|
-
}
|
|
11
|
+
const minimist__default = /*#__PURE__*/_interopDefaultLegacy(minimist);
|
|
260
12
|
|
|
261
13
|
function createDefaultLogger(name, logger) {
|
|
262
14
|
const println = !!logger && typeof logger === "function" ? logger : logger?.println ?? ((message, ...args) => {
|
|
@@ -303,11 +55,11 @@ const _Option = class {
|
|
|
303
55
|
this.description = config.description ?? "";
|
|
304
56
|
this.required = format.indexOf("<") !== -1;
|
|
305
57
|
this.default = config.default;
|
|
306
|
-
this.construct = config.construct
|
|
58
|
+
this.construct = config.construct;
|
|
307
59
|
}
|
|
308
60
|
};
|
|
309
61
|
let Option = _Option;
|
|
310
|
-
Option.OptionRE = /^(-[a-zA-Z], )?--([a-zA-Z
|
|
62
|
+
Option.OptionRE = /^(-[a-zA-Z], )?--([a-zA-Z]+)( \[[a-zA-Z]+\]| <[a-zA-Z]+>)?$/;
|
|
311
63
|
|
|
312
64
|
const _Command = class {
|
|
313
65
|
constructor(format, config) {
|
|
@@ -407,6 +159,13 @@ const _Command = class {
|
|
|
407
159
|
options[name] = void 0;
|
|
408
160
|
}
|
|
409
161
|
}
|
|
162
|
+
if (rawOption.construct) {
|
|
163
|
+
options[name] = rawOption.construct(options[name]);
|
|
164
|
+
} else if (rawOption.default) {
|
|
165
|
+
if (!options[name]) {
|
|
166
|
+
options[name] = rawOption.default;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
410
169
|
}
|
|
411
170
|
return {
|
|
412
171
|
command: this,
|
|
@@ -420,7 +179,7 @@ const _Command = class {
|
|
|
420
179
|
}
|
|
421
180
|
async run(...args) {
|
|
422
181
|
if (this.actionFn) {
|
|
423
|
-
this.actionFn(...args);
|
|
182
|
+
this.actionFn(...args, { logger: this.logger });
|
|
424
183
|
} else {
|
|
425
184
|
this.logger.warn(`You may miss action function in "${this.format}"`);
|
|
426
185
|
}
|
|
@@ -580,17 +339,10 @@ class Breadc {
|
|
|
580
339
|
}
|
|
581
340
|
return map;
|
|
582
341
|
}, {});
|
|
583
|
-
const
|
|
584
|
-
if (o.default) {
|
|
585
|
-
map[o.name] = o.default;
|
|
586
|
-
}
|
|
587
|
-
return map;
|
|
588
|
-
}, {});
|
|
589
|
-
const argv = minimist(args, {
|
|
342
|
+
const argv = minimist__default(args, {
|
|
590
343
|
string: allowOptions.filter((o) => o.type === "string").map((o) => o.name),
|
|
591
344
|
boolean: allowOptions.filter((o) => o.type === "boolean").map((o) => o.name),
|
|
592
345
|
alias,
|
|
593
|
-
default: defaults,
|
|
594
346
|
unknown: (t) => {
|
|
595
347
|
if (t[0] !== "-")
|
|
596
348
|
return true;
|
|
@@ -645,5 +397,5 @@ function breadc(name, option = {}) {
|
|
|
645
397
|
}
|
|
646
398
|
|
|
647
399
|
exports.kolorist = kolorist__default;
|
|
400
|
+
exports.minimist = minimist__default;
|
|
648
401
|
exports["default"] = breadc;
|
|
649
|
-
exports.minimist = minimist;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,259 +1,11 @@
|
|
|
1
|
+
import { ParsedArgs } from 'minimist';
|
|
2
|
+
export { default as minimist } from 'minimist';
|
|
1
3
|
export { default as kolorist } from 'kolorist';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
if (!opts) opts = {};
|
|
5
|
-
|
|
6
|
-
var flags = { bools : {}, strings : {}, unknownFn: null };
|
|
7
|
-
|
|
8
|
-
if (typeof opts['unknown'] === 'function') {
|
|
9
|
-
flags.unknownFn = opts['unknown'];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
|
|
13
|
-
flags.allBools = true;
|
|
14
|
-
} else {
|
|
15
|
-
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
|
|
16
|
-
flags.bools[key] = true;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
var aliases = {};
|
|
21
|
-
Object.keys(opts.alias || {}).forEach(function (key) {
|
|
22
|
-
aliases[key] = [].concat(opts.alias[key]);
|
|
23
|
-
aliases[key].forEach(function (x) {
|
|
24
|
-
aliases[x] = [key].concat(aliases[key].filter(function (y) {
|
|
25
|
-
return x !== y;
|
|
26
|
-
}));
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
[].concat(opts.string).filter(Boolean).forEach(function (key) {
|
|
31
|
-
flags.strings[key] = true;
|
|
32
|
-
if (aliases[key]) {
|
|
33
|
-
flags.strings[aliases[key]] = true;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
var defaults = opts['default'] || {};
|
|
38
|
-
|
|
39
|
-
var argv = { _ : [] };
|
|
40
|
-
Object.keys(flags.bools).forEach(function (key) {
|
|
41
|
-
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
var notFlags = [];
|
|
45
|
-
|
|
46
|
-
if (args.indexOf('--') !== -1) {
|
|
47
|
-
notFlags = args.slice(args.indexOf('--')+1);
|
|
48
|
-
args = args.slice(0, args.indexOf('--'));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function argDefined(key, arg) {
|
|
52
|
-
return (flags.allBools && /^--[^=]+$/.test(arg)) ||
|
|
53
|
-
flags.strings[key] || flags.bools[key] || aliases[key];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function setArg (key, val, arg) {
|
|
57
|
-
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
|
58
|
-
if (flags.unknownFn(arg) === false) return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
var value = !flags.strings[key] && isNumber(val)
|
|
62
|
-
? Number(val) : val
|
|
63
|
-
;
|
|
64
|
-
setKey(argv, key.split('.'), value);
|
|
65
|
-
|
|
66
|
-
(aliases[key] || []).forEach(function (x) {
|
|
67
|
-
setKey(argv, x.split('.'), value);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function setKey (obj, keys, value) {
|
|
72
|
-
var o = obj;
|
|
73
|
-
for (var i = 0; i < keys.length-1; i++) {
|
|
74
|
-
var key = keys[i];
|
|
75
|
-
if (isConstructorOrProto(o, key)) return;
|
|
76
|
-
if (o[key] === undefined) o[key] = {};
|
|
77
|
-
if (o[key] === Object.prototype || o[key] === Number.prototype
|
|
78
|
-
|| o[key] === String.prototype) o[key] = {};
|
|
79
|
-
if (o[key] === Array.prototype) o[key] = [];
|
|
80
|
-
o = o[key];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
var key = keys[keys.length - 1];
|
|
84
|
-
if (isConstructorOrProto(o, key)) return;
|
|
85
|
-
if (o === Object.prototype || o === Number.prototype
|
|
86
|
-
|| o === String.prototype) o = {};
|
|
87
|
-
if (o === Array.prototype) o = [];
|
|
88
|
-
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
|
|
89
|
-
o[key] = value;
|
|
90
|
-
}
|
|
91
|
-
else if (Array.isArray(o[key])) {
|
|
92
|
-
o[key].push(value);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
o[key] = [ o[key], value ];
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function aliasIsBoolean(key) {
|
|
100
|
-
return aliases[key].some(function (x) {
|
|
101
|
-
return flags.bools[x];
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
for (var i = 0; i < args.length; i++) {
|
|
106
|
-
var arg = args[i];
|
|
107
|
-
|
|
108
|
-
if (/^--.+=/.test(arg)) {
|
|
109
|
-
// Using [\s\S] instead of . because js doesn't support the
|
|
110
|
-
// 'dotall' regex modifier. See:
|
|
111
|
-
// http://stackoverflow.com/a/1068308/13216
|
|
112
|
-
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
|
113
|
-
var key = m[1];
|
|
114
|
-
var value = m[2];
|
|
115
|
-
if (flags.bools[key]) {
|
|
116
|
-
value = value !== 'false';
|
|
117
|
-
}
|
|
118
|
-
setArg(key, value, arg);
|
|
119
|
-
}
|
|
120
|
-
else if (/^--no-.+/.test(arg)) {
|
|
121
|
-
var key = arg.match(/^--no-(.+)/)[1];
|
|
122
|
-
setArg(key, false, arg);
|
|
123
|
-
}
|
|
124
|
-
else if (/^--.+/.test(arg)) {
|
|
125
|
-
var key = arg.match(/^--(.+)/)[1];
|
|
126
|
-
var next = args[i + 1];
|
|
127
|
-
if (next !== undefined && !/^-/.test(next)
|
|
128
|
-
&& !flags.bools[key]
|
|
129
|
-
&& !flags.allBools
|
|
130
|
-
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
131
|
-
setArg(key, next, arg);
|
|
132
|
-
i++;
|
|
133
|
-
}
|
|
134
|
-
else if (/^(true|false)$/.test(next)) {
|
|
135
|
-
setArg(key, next === 'true', arg);
|
|
136
|
-
i++;
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
else if (/^-[^-]+/.test(arg)) {
|
|
143
|
-
var letters = arg.slice(1,-1).split('');
|
|
144
|
-
|
|
145
|
-
var broken = false;
|
|
146
|
-
for (var j = 0; j < letters.length; j++) {
|
|
147
|
-
var next = arg.slice(j+2);
|
|
148
|
-
|
|
149
|
-
if (next === '-') {
|
|
150
|
-
setArg(letters[j], next, arg);
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
|
155
|
-
setArg(letters[j], next.split('=')[1], arg);
|
|
156
|
-
broken = true;
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (/[A-Za-z]/.test(letters[j])
|
|
161
|
-
&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
|
|
162
|
-
setArg(letters[j], next, arg);
|
|
163
|
-
broken = true;
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (letters[j+1] && letters[j+1].match(/\W/)) {
|
|
168
|
-
setArg(letters[j], arg.slice(j+2), arg);
|
|
169
|
-
broken = true;
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
var key = arg.slice(-1)[0];
|
|
178
|
-
if (!broken && key !== '-') {
|
|
179
|
-
if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
|
|
180
|
-
&& !flags.bools[key]
|
|
181
|
-
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
182
|
-
setArg(key, args[i+1], arg);
|
|
183
|
-
i++;
|
|
184
|
-
}
|
|
185
|
-
else if (args[i+1] && /^(true|false)$/.test(args[i+1])) {
|
|
186
|
-
setArg(key, args[i+1] === 'true', arg);
|
|
187
|
-
i++;
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
|
196
|
-
argv._.push(
|
|
197
|
-
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
if (opts.stopEarly) {
|
|
201
|
-
argv._.push.apply(argv._, args.slice(i + 1));
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
Object.keys(defaults).forEach(function (key) {
|
|
208
|
-
if (!hasKey(argv, key.split('.'))) {
|
|
209
|
-
setKey(argv, key.split('.'), defaults[key]);
|
|
210
|
-
|
|
211
|
-
(aliases[key] || []).forEach(function (x) {
|
|
212
|
-
setKey(argv, x.split('.'), defaults[key]);
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
if (opts['--']) {
|
|
218
|
-
argv['--'] = new Array();
|
|
219
|
-
notFlags.forEach(function(key) {
|
|
220
|
-
argv['--'].push(key);
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
notFlags.forEach(function(key) {
|
|
225
|
-
argv._.push(key);
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return argv;
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
function hasKey (obj, keys) {
|
|
233
|
-
var o = obj;
|
|
234
|
-
keys.slice(0,-1).forEach(function (key) {
|
|
235
|
-
o = (o[key] || {});
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
var key = keys[keys.length - 1];
|
|
239
|
-
return key in o;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function isNumber (x) {
|
|
243
|
-
if (typeof x === 'number') return true;
|
|
244
|
-
if (/^0x[0-9a-f]+$/i.test(x)) return true;
|
|
245
|
-
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
function isConstructorOrProto (obj, key) {
|
|
250
|
-
return key === 'constructor' && typeof obj[key] === 'function' || key === '__proto__';
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
interface OptionConfig<T = string> {
|
|
5
|
+
interface OptionConfig<F extends string, T = never> {
|
|
254
6
|
description?: string;
|
|
255
7
|
default?: T;
|
|
256
|
-
construct?: (rawText
|
|
8
|
+
construct?: (rawText: ExtractOptionType<F>) => T;
|
|
257
9
|
}
|
|
258
10
|
/**
|
|
259
11
|
* Option
|
|
@@ -273,11 +25,11 @@ declare class Option<T extends string = string, F = string> {
|
|
|
273
25
|
readonly description: string;
|
|
274
26
|
readonly type: 'string' | 'boolean';
|
|
275
27
|
readonly required: boolean;
|
|
276
|
-
readonly construct
|
|
277
|
-
constructor(format: T, config?: OptionConfig<F>);
|
|
28
|
+
readonly construct?: (rawText: ExtractOptionType<T>) => F;
|
|
29
|
+
constructor(format: T, config?: OptionConfig<T, F>);
|
|
278
30
|
}
|
|
279
31
|
|
|
280
|
-
declare type ConditionFn = (args:
|
|
32
|
+
declare type ConditionFn = (args: ParsedArgs) => boolean;
|
|
281
33
|
interface CommandConfig {
|
|
282
34
|
description?: string;
|
|
283
35
|
}
|
|
@@ -294,11 +46,11 @@ declare class Command<F extends string = string, CommandOption extends object =
|
|
|
294
46
|
condition?: ConditionFn;
|
|
295
47
|
logger: Logger;
|
|
296
48
|
});
|
|
297
|
-
option<OF extends string, T =
|
|
298
|
-
option<OF extends string, T =
|
|
49
|
+
option<OF extends string, T = undefined>(format: OF, description: string, config?: Omit<OptionConfig<OF, T>, 'description'>): Command<F, CommandOption & ExtractOption<OF, T>>;
|
|
50
|
+
option<OF extends string, T = undefined>(format: OF, config?: OptionConfig<OF, T>): Command<F, CommandOption & ExtractOption<OF, T>>;
|
|
299
51
|
get hasConditionFn(): boolean;
|
|
300
|
-
shouldRun(args:
|
|
301
|
-
parseArgs(args:
|
|
52
|
+
shouldRun(args: ParsedArgs): boolean;
|
|
53
|
+
parseArgs(args: ParsedArgs, globalOptions: Option[]): ParseResult;
|
|
302
54
|
action(fn: ActionFn<ExtractCommand<F>, CommandOption>): this;
|
|
303
55
|
run(...args: any[]): Promise<void>;
|
|
304
56
|
}
|
|
@@ -322,8 +74,8 @@ interface ParseResult {
|
|
|
322
74
|
arguments: any[];
|
|
323
75
|
options: Record<string, string>;
|
|
324
76
|
}
|
|
325
|
-
declare type ExtractOption<T extends string> = {
|
|
326
|
-
[k in ExtractOptionName<T>]: ExtractOptionType<T
|
|
77
|
+
declare type ExtractOption<T extends string, D = undefined> = {
|
|
78
|
+
[k in ExtractOptionName<T>]: D extends undefined ? ExtractOptionType<T> : D;
|
|
327
79
|
};
|
|
328
80
|
/**
|
|
329
81
|
* Extract option name type
|
|
@@ -337,12 +89,15 @@ declare type ExtractOptionType<T extends string> = T extends `-${Letter}, --${in
|
|
|
337
89
|
declare type Lowercase = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
|
|
338
90
|
declare type Uppercase = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
339
91
|
declare type Letter = Lowercase | Uppercase;
|
|
340
|
-
declare type Push<T extends any[], U> = [...T, U];
|
|
341
|
-
declare type
|
|
92
|
+
declare type Push<T extends any[], U, R> = [...T, U, R];
|
|
93
|
+
declare type Context = {
|
|
94
|
+
logger: Logger;
|
|
95
|
+
};
|
|
96
|
+
declare type ActionFn<T extends any[], Option extends object = {}> = (...arg: Push<T, Option, Context>) => void;
|
|
342
97
|
/**
|
|
343
98
|
* Max Dep: 5
|
|
344
99
|
*
|
|
345
|
-
* Generated by: npx tsx
|
|
100
|
+
* Generated by: npx tsx examples/genType.ts 5
|
|
346
101
|
*/
|
|
347
102
|
declare type ExtractCommand<T extends string> = T extends `<${infer P1}> <${infer P2}> <${infer P3}> <${infer P4}> [...${infer P5}]` ? [string, string, string, string, string[]] : T extends `<${infer P1}> <${infer P2}> <${infer P3}> <${infer P4}> [${infer P5}]` ? [string, string, string, string, string | undefined] : T extends `<${infer P1}> <${infer P2}> <${infer P3}> <${infer P4}> <${infer P5}>` ? [string, string, string, string, string] : T extends `${infer P1} <${infer P2}> <${infer P3}> <${infer P4}> [...${infer P5}]` ? [string, string, string, string[]] : T extends `${infer P1} <${infer P2}> <${infer P3}> <${infer P4}> [${infer P5}]` ? [string, string, string, string | undefined] : T extends `${infer P1} <${infer P2}> <${infer P3}> <${infer P4}> <${infer P5}>` ? [string, string, string, string] : T extends `${infer P1} ${infer P2} <${infer P3}> <${infer P4}> [...${infer P5}]` ? [string, string, string[]] : T extends `${infer P1} ${infer P2} <${infer P3}> <${infer P4}> [${infer P5}]` ? [string, string, string | undefined] : T extends `${infer P1} ${infer P2} <${infer P3}> <${infer P4}> <${infer P5}>` ? [string, string, string] : T extends `${infer P1} ${infer P2} ${infer P3} <${infer P4}> [...${infer P5}]` ? [string, string[]] : T extends `${infer P1} ${infer P2} ${infer P3} <${infer P4}> [${infer P5}]` ? [string, string | undefined] : T extends `${infer P1} ${infer P2} ${infer P3} <${infer P4}> <${infer P5}>` ? [string, string] : T extends `<${infer P1}> <${infer P2}> <${infer P3}> [...${infer P4}]` ? [string, string, string, string[]] : T extends `<${infer P1}> <${infer P2}> <${infer P3}> [${infer P4}]` ? [string, string, string, string | undefined] : T extends `<${infer P1}> <${infer P2}> <${infer P3}> <${infer P4}>` ? [string, string, string, string] : T extends `${infer P1} <${infer P2}> <${infer P3}> [...${infer P4}]` ? [string, string, string[]] : T extends `${infer P1} <${infer P2}> <${infer P3}> [${infer P4}]` ? [string, string, string | undefined] : T extends `${infer P1} <${infer P2}> <${infer P3}> <${infer P4}>` ? [string, string, string] : T extends `${infer P1} ${infer P2} <${infer P3}> [...${infer P4}]` ? [string, string[]] : T extends `${infer P1} ${infer P2} <${infer P3}> [${infer P4}]` ? [string, string | undefined] : T extends `${infer P1} ${infer P2} <${infer P3}> <${infer P4}>` ? [string, string] : T extends `${infer P1} ${infer P2} ${infer P3} [...${infer P4}]` ? [string[]] : T extends `${infer P1} ${infer P2} ${infer P3} [${infer P4}]` ? [string | undefined] : T extends `${infer P1} ${infer P2} ${infer P3} <${infer P4}>` ? [string] : T extends `<${infer P1}> <${infer P2}> [...${infer P3}]` ? [string, string, string[]] : T extends `<${infer P1}> <${infer P2}> [${infer P3}]` ? [string, string, string | undefined] : T extends `<${infer P1}> <${infer P2}> <${infer P3}>` ? [string, string, string] : T extends `${infer P1} <${infer P2}> [...${infer P3}]` ? [string, string[]] : T extends `${infer P1} <${infer P2}> [${infer P3}]` ? [string, string | undefined] : T extends `${infer P1} <${infer P2}> <${infer P3}>` ? [string, string] : T extends `${infer P1} ${infer P2} [...${infer P3}]` ? [string[]] : T extends `${infer P1} ${infer P2} [${infer P3}]` ? [string | undefined] : T extends `${infer P1} ${infer P2} <${infer P3}>` ? [string] : T extends `${infer P1} ${infer P2} ${infer P3}` ? [] : T extends `<${infer P1}> [...${infer P2}]` ? [string, string[]] : T extends `<${infer P1}> [${infer P2}]` ? [string, string | undefined] : T extends `<${infer P1}> <${infer P2}>` ? [string, string] : T extends `${infer P1} [...${infer P2}]` ? [string[]] : T extends `${infer P1} [${infer P2}]` ? [string | undefined] : T extends `${infer P1} <${infer P2}>` ? [string] : T extends `${infer P1} ${infer P2}` ? [] : T extends `[...${infer P1}]` ? [string[]] : T extends `[${infer P1}]` ? [string | undefined] : T extends `<${infer P1}>` ? [string] : T extends `${infer P1}` ? [] : T extends `` ? [] : never;
|
|
348
103
|
|
|
@@ -357,8 +112,8 @@ declare class Breadc<GlobalOption extends object = {}> {
|
|
|
357
112
|
constructor(name: string, option: AppOption);
|
|
358
113
|
version(): string;
|
|
359
114
|
help(command?: Command): string[];
|
|
360
|
-
option<F extends string, T =
|
|
361
|
-
option<F extends string, T =
|
|
115
|
+
option<F extends string, T = undefined>(format: F, description: string, config?: Omit<OptionConfig<F, T>, 'description'>): Breadc<GlobalOption & ExtractOption<F, T>>;
|
|
116
|
+
option<F extends string, T = undefined>(format: F, config?: OptionConfig<F, T>): Breadc<GlobalOption & ExtractOption<F, T>>;
|
|
362
117
|
command<F extends string>(format: F, description: string, config?: Omit<CommandConfig, 'description'>): Command<F, GlobalOption>;
|
|
363
118
|
command<F extends string>(format: F, config?: CommandConfig): Command<F, GlobalOption>;
|
|
364
119
|
parse(args: string[]): ParseResult;
|
|
@@ -367,4 +122,4 @@ declare class Breadc<GlobalOption extends object = {}> {
|
|
|
367
122
|
|
|
368
123
|
declare function breadc(name: string, option?: AppOption): Breadc<{}>;
|
|
369
124
|
|
|
370
|
-
export { breadc as default
|
|
125
|
+
export { breadc as default };
|
package/dist/index.mjs
CHANGED
|
@@ -1,255 +1,7 @@
|
|
|
1
1
|
import { blue, yellow, red, gray } from 'kolorist';
|
|
2
2
|
export { default as kolorist } from 'kolorist';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!opts) opts = {};
|
|
6
|
-
|
|
7
|
-
var flags = { bools : {}, strings : {}, unknownFn: null };
|
|
8
|
-
|
|
9
|
-
if (typeof opts['unknown'] === 'function') {
|
|
10
|
-
flags.unknownFn = opts['unknown'];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
|
|
14
|
-
flags.allBools = true;
|
|
15
|
-
} else {
|
|
16
|
-
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
|
|
17
|
-
flags.bools[key] = true;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
var aliases = {};
|
|
22
|
-
Object.keys(opts.alias || {}).forEach(function (key) {
|
|
23
|
-
aliases[key] = [].concat(opts.alias[key]);
|
|
24
|
-
aliases[key].forEach(function (x) {
|
|
25
|
-
aliases[x] = [key].concat(aliases[key].filter(function (y) {
|
|
26
|
-
return x !== y;
|
|
27
|
-
}));
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
[].concat(opts.string).filter(Boolean).forEach(function (key) {
|
|
32
|
-
flags.strings[key] = true;
|
|
33
|
-
if (aliases[key]) {
|
|
34
|
-
flags.strings[aliases[key]] = true;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
var defaults = opts['default'] || {};
|
|
39
|
-
|
|
40
|
-
var argv = { _ : [] };
|
|
41
|
-
Object.keys(flags.bools).forEach(function (key) {
|
|
42
|
-
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
var notFlags = [];
|
|
46
|
-
|
|
47
|
-
if (args.indexOf('--') !== -1) {
|
|
48
|
-
notFlags = args.slice(args.indexOf('--')+1);
|
|
49
|
-
args = args.slice(0, args.indexOf('--'));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function argDefined(key, arg) {
|
|
53
|
-
return (flags.allBools && /^--[^=]+$/.test(arg)) ||
|
|
54
|
-
flags.strings[key] || flags.bools[key] || aliases[key];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function setArg (key, val, arg) {
|
|
58
|
-
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
|
59
|
-
if (flags.unknownFn(arg) === false) return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
var value = !flags.strings[key] && isNumber(val)
|
|
63
|
-
? Number(val) : val
|
|
64
|
-
;
|
|
65
|
-
setKey(argv, key.split('.'), value);
|
|
66
|
-
|
|
67
|
-
(aliases[key] || []).forEach(function (x) {
|
|
68
|
-
setKey(argv, x.split('.'), value);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function setKey (obj, keys, value) {
|
|
73
|
-
var o = obj;
|
|
74
|
-
for (var i = 0; i < keys.length-1; i++) {
|
|
75
|
-
var key = keys[i];
|
|
76
|
-
if (isConstructorOrProto(o, key)) return;
|
|
77
|
-
if (o[key] === undefined) o[key] = {};
|
|
78
|
-
if (o[key] === Object.prototype || o[key] === Number.prototype
|
|
79
|
-
|| o[key] === String.prototype) o[key] = {};
|
|
80
|
-
if (o[key] === Array.prototype) o[key] = [];
|
|
81
|
-
o = o[key];
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
var key = keys[keys.length - 1];
|
|
85
|
-
if (isConstructorOrProto(o, key)) return;
|
|
86
|
-
if (o === Object.prototype || o === Number.prototype
|
|
87
|
-
|| o === String.prototype) o = {};
|
|
88
|
-
if (o === Array.prototype) o = [];
|
|
89
|
-
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
|
|
90
|
-
o[key] = value;
|
|
91
|
-
}
|
|
92
|
-
else if (Array.isArray(o[key])) {
|
|
93
|
-
o[key].push(value);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
o[key] = [ o[key], value ];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function aliasIsBoolean(key) {
|
|
101
|
-
return aliases[key].some(function (x) {
|
|
102
|
-
return flags.bools[x];
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
for (var i = 0; i < args.length; i++) {
|
|
107
|
-
var arg = args[i];
|
|
108
|
-
|
|
109
|
-
if (/^--.+=/.test(arg)) {
|
|
110
|
-
// Using [\s\S] instead of . because js doesn't support the
|
|
111
|
-
// 'dotall' regex modifier. See:
|
|
112
|
-
// http://stackoverflow.com/a/1068308/13216
|
|
113
|
-
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
|
114
|
-
var key = m[1];
|
|
115
|
-
var value = m[2];
|
|
116
|
-
if (flags.bools[key]) {
|
|
117
|
-
value = value !== 'false';
|
|
118
|
-
}
|
|
119
|
-
setArg(key, value, arg);
|
|
120
|
-
}
|
|
121
|
-
else if (/^--no-.+/.test(arg)) {
|
|
122
|
-
var key = arg.match(/^--no-(.+)/)[1];
|
|
123
|
-
setArg(key, false, arg);
|
|
124
|
-
}
|
|
125
|
-
else if (/^--.+/.test(arg)) {
|
|
126
|
-
var key = arg.match(/^--(.+)/)[1];
|
|
127
|
-
var next = args[i + 1];
|
|
128
|
-
if (next !== undefined && !/^-/.test(next)
|
|
129
|
-
&& !flags.bools[key]
|
|
130
|
-
&& !flags.allBools
|
|
131
|
-
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
132
|
-
setArg(key, next, arg);
|
|
133
|
-
i++;
|
|
134
|
-
}
|
|
135
|
-
else if (/^(true|false)$/.test(next)) {
|
|
136
|
-
setArg(key, next === 'true', arg);
|
|
137
|
-
i++;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
else if (/^-[^-]+/.test(arg)) {
|
|
144
|
-
var letters = arg.slice(1,-1).split('');
|
|
145
|
-
|
|
146
|
-
var broken = false;
|
|
147
|
-
for (var j = 0; j < letters.length; j++) {
|
|
148
|
-
var next = arg.slice(j+2);
|
|
149
|
-
|
|
150
|
-
if (next === '-') {
|
|
151
|
-
setArg(letters[j], next, arg);
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
|
156
|
-
setArg(letters[j], next.split('=')[1], arg);
|
|
157
|
-
broken = true;
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (/[A-Za-z]/.test(letters[j])
|
|
162
|
-
&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
|
|
163
|
-
setArg(letters[j], next, arg);
|
|
164
|
-
broken = true;
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (letters[j+1] && letters[j+1].match(/\W/)) {
|
|
169
|
-
setArg(letters[j], arg.slice(j+2), arg);
|
|
170
|
-
broken = true;
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
var key = arg.slice(-1)[0];
|
|
179
|
-
if (!broken && key !== '-') {
|
|
180
|
-
if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
|
|
181
|
-
&& !flags.bools[key]
|
|
182
|
-
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
183
|
-
setArg(key, args[i+1], arg);
|
|
184
|
-
i++;
|
|
185
|
-
}
|
|
186
|
-
else if (args[i+1] && /^(true|false)$/.test(args[i+1])) {
|
|
187
|
-
setArg(key, args[i+1] === 'true', arg);
|
|
188
|
-
i++;
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
|
197
|
-
argv._.push(
|
|
198
|
-
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
if (opts.stopEarly) {
|
|
202
|
-
argv._.push.apply(argv._, args.slice(i + 1));
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
Object.keys(defaults).forEach(function (key) {
|
|
209
|
-
if (!hasKey(argv, key.split('.'))) {
|
|
210
|
-
setKey(argv, key.split('.'), defaults[key]);
|
|
211
|
-
|
|
212
|
-
(aliases[key] || []).forEach(function (x) {
|
|
213
|
-
setKey(argv, x.split('.'), defaults[key]);
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
if (opts['--']) {
|
|
219
|
-
argv['--'] = new Array();
|
|
220
|
-
notFlags.forEach(function(key) {
|
|
221
|
-
argv['--'].push(key);
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
notFlags.forEach(function(key) {
|
|
226
|
-
argv._.push(key);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return argv;
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
function hasKey (obj, keys) {
|
|
234
|
-
var o = obj;
|
|
235
|
-
keys.slice(0,-1).forEach(function (key) {
|
|
236
|
-
o = (o[key] || {});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
var key = keys[keys.length - 1];
|
|
240
|
-
return key in o;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
function isNumber (x) {
|
|
244
|
-
if (typeof x === 'number') return true;
|
|
245
|
-
if (/^0x[0-9a-f]+$/i.test(x)) return true;
|
|
246
|
-
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
function isConstructorOrProto (obj, key) {
|
|
251
|
-
return key === 'constructor' && typeof obj[key] === 'function' || key === '__proto__';
|
|
252
|
-
}
|
|
3
|
+
import minimist from 'minimist';
|
|
4
|
+
export { default as minimist } from 'minimist';
|
|
253
5
|
|
|
254
6
|
function createDefaultLogger(name, logger) {
|
|
255
7
|
const println = !!logger && typeof logger === "function" ? logger : logger?.println ?? ((message, ...args) => {
|
|
@@ -296,11 +48,11 @@ const _Option = class {
|
|
|
296
48
|
this.description = config.description ?? "";
|
|
297
49
|
this.required = format.indexOf("<") !== -1;
|
|
298
50
|
this.default = config.default;
|
|
299
|
-
this.construct = config.construct
|
|
51
|
+
this.construct = config.construct;
|
|
300
52
|
}
|
|
301
53
|
};
|
|
302
54
|
let Option = _Option;
|
|
303
|
-
Option.OptionRE = /^(-[a-zA-Z], )?--([a-zA-Z
|
|
55
|
+
Option.OptionRE = /^(-[a-zA-Z], )?--([a-zA-Z]+)( \[[a-zA-Z]+\]| <[a-zA-Z]+>)?$/;
|
|
304
56
|
|
|
305
57
|
const _Command = class {
|
|
306
58
|
constructor(format, config) {
|
|
@@ -400,6 +152,13 @@ const _Command = class {
|
|
|
400
152
|
options[name] = void 0;
|
|
401
153
|
}
|
|
402
154
|
}
|
|
155
|
+
if (rawOption.construct) {
|
|
156
|
+
options[name] = rawOption.construct(options[name]);
|
|
157
|
+
} else if (rawOption.default) {
|
|
158
|
+
if (!options[name]) {
|
|
159
|
+
options[name] = rawOption.default;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
403
162
|
}
|
|
404
163
|
return {
|
|
405
164
|
command: this,
|
|
@@ -413,7 +172,7 @@ const _Command = class {
|
|
|
413
172
|
}
|
|
414
173
|
async run(...args) {
|
|
415
174
|
if (this.actionFn) {
|
|
416
|
-
this.actionFn(...args);
|
|
175
|
+
this.actionFn(...args, { logger: this.logger });
|
|
417
176
|
} else {
|
|
418
177
|
this.logger.warn(`You may miss action function in "${this.format}"`);
|
|
419
178
|
}
|
|
@@ -573,17 +332,10 @@ class Breadc {
|
|
|
573
332
|
}
|
|
574
333
|
return map;
|
|
575
334
|
}, {});
|
|
576
|
-
const defaults = allowOptions.reduce((map, o) => {
|
|
577
|
-
if (o.default) {
|
|
578
|
-
map[o.name] = o.default;
|
|
579
|
-
}
|
|
580
|
-
return map;
|
|
581
|
-
}, {});
|
|
582
335
|
const argv = minimist(args, {
|
|
583
336
|
string: allowOptions.filter((o) => o.type === "string").map((o) => o.name),
|
|
584
337
|
boolean: allowOptions.filter((o) => o.type === "boolean").map((o) => o.name),
|
|
585
338
|
alias,
|
|
586
|
-
default: defaults,
|
|
587
339
|
unknown: (t) => {
|
|
588
340
|
if (t[0] !== "-")
|
|
589
341
|
return true;
|
|
@@ -637,4 +389,4 @@ function breadc(name, option = {}) {
|
|
|
637
389
|
return new Breadc(name, option);
|
|
638
390
|
}
|
|
639
391
|
|
|
640
|
-
export { breadc as default
|
|
392
|
+
export { breadc as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breadc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Yet another Command Line Application Framework with fully strong TypeScript support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -34,23 +34,23 @@
|
|
|
34
34
|
"dist"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"kolorist": "^1.5.1"
|
|
37
|
+
"kolorist": "^1.5.1",
|
|
38
|
+
"minimist": "^1.2.6"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@types/minimist": "^1.2.2",
|
|
41
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^18.0.0",
|
|
42
43
|
"bumpp": "^8.2.1",
|
|
43
|
-
"minimist": "^1.2.6",
|
|
44
44
|
"prettier": "^2.7.1",
|
|
45
45
|
"typescript": "^4.7.4",
|
|
46
46
|
"unbuild": "^0.7.4",
|
|
47
47
|
"vite": "^2.9.12",
|
|
48
|
-
"vitest": "^0.15.
|
|
48
|
+
"vitest": "^0.15.2"
|
|
49
49
|
},
|
|
50
50
|
"packageManager": "pnpm@7.3.0",
|
|
51
51
|
"scripts": {
|
|
52
52
|
"build": "unbuild",
|
|
53
|
-
"format": "prettier --write src/**/*.ts test/*.ts examples/*.ts
|
|
53
|
+
"format": "prettier --write src/**/*.ts test/*.ts examples/*.ts",
|
|
54
54
|
"release": "bumpp --commit --push --tag && pnpm publish",
|
|
55
55
|
"test": "vitest",
|
|
56
56
|
"typecheck": "tsc --noEmit",
|