breadc 0.1.0 → 0.3.0

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/dist/index.mjs CHANGED
@@ -1,33 +1,284 @@
1
- import { blue, yellow, red } from 'kolorist';
1
+ import { blue, yellow, red, gray } from 'kolorist';
2
2
  export { default as kolorist } from 'kolorist';
3
- import minimist from 'minimist';
4
- export { default as minimist } from 'minimist';
5
- import createDebug from 'debug';
6
- export { default as createDebug } from 'debug';
7
3
 
8
- function createDefaultLogger(name) {
9
- const debug = createDebug(name + ":breadc");
10
- return {
11
- println(message) {
12
- console.log(message);
13
- },
14
- info(message, ...args) {
15
- console.log(`${blue("INFO")} ${message}`, ...args);
16
- },
17
- warn(message, ...args) {
18
- console.log(`${yellow("WARN")} ${message}`, ...args);
19
- },
20
- error(message, ...args) {
21
- console.log(`${red("ERROR")} ${message}`, ...args);
22
- },
23
- debug(message, ...args) {
24
- debug(message, ...args);
4
+ var minimist = function (args, opts) {
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
+ });
25
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
+ }
253
+
254
+ function createDefaultLogger(name, logger) {
255
+ const println = !!logger && typeof logger === "function" ? logger : logger?.println ?? ((message, ...args) => {
256
+ console.log(message, ...args);
257
+ });
258
+ const info = typeof logger === "object" && logger?.info ? logger.info : (message, ...args) => {
259
+ println(`${blue("INFO")} ${message}`, ...args);
260
+ };
261
+ const warn = typeof logger === "object" && logger?.warn ? logger.warn : (message, ...args) => {
262
+ println(`${yellow("WARN")} ${message}`, ...args);
263
+ };
264
+ const error = typeof logger === "object" && logger?.error ? logger.error : (message, ...args) => {
265
+ println(`${red("ERROR")} ${message}`, ...args);
266
+ };
267
+ const debug = typeof logger === "object" && logger?.debug ? logger.debug : (message, ...args) => {
268
+ println(`${gray(name)} ${message}`, ...args);
269
+ };
270
+ return {
271
+ println,
272
+ info,
273
+ warn,
274
+ error,
275
+ debug
26
276
  };
27
277
  }
28
278
 
29
279
  const _Option = class {
30
280
  constructor(format, config = {}) {
281
+ this.format = format;
31
282
  const match = _Option.OptionRE.exec(format);
32
283
  if (match) {
33
284
  if (match[3]) {
@@ -43,25 +294,28 @@ const _Option = class {
43
294
  throw new Error(`Can not parse option format from "${format}"`);
44
295
  }
45
296
  this.description = config.description ?? "";
297
+ this.required = format.indexOf("<") !== -1;
298
+ this.default = config.default;
46
299
  this.construct = config.construct ?? ((text) => text ?? config.default ?? void 0);
47
300
  }
48
301
  };
49
302
  let Option = _Option;
50
303
  Option.OptionRE = /^(-[a-zA-Z], )?--([a-zA-Z.]+)( \[[a-zA-Z]+\]| <[a-zA-Z]+>)?$/;
51
304
 
52
- class Command {
305
+ const _Command = class {
53
306
  constructor(format, config) {
54
307
  this.options = [];
55
308
  this.format = config.condition ? [format] : format.split(" ").map((t) => t.trim()).filter(Boolean);
309
+ this.default = this.format.length === 0 || this.format[0][0] === "[" || this.format[0][0] === "<";
56
310
  this.description = config.description ?? "";
57
311
  this.conditionFn = config.condition;
58
312
  this.logger = config.logger;
313
+ if (this.format.length > _Command.MaxDep) {
314
+ this.logger.warn(`Command format string "${format}" is too long`);
315
+ }
59
316
  }
60
317
  option(format, configOrDescription = "", otherConfig = {}) {
61
- const config = otherConfig;
62
- if (typeof configOrDescription === "string") {
63
- config.description = configOrDescription;
64
- }
318
+ const config = typeof configOrDescription === "object" ? configOrDescription : { ...otherConfig, description: configOrDescription };
65
319
  try {
66
320
  const option = new Option(format, config);
67
321
  this.options.push(option);
@@ -70,13 +324,18 @@ class Command {
70
324
  }
71
325
  return this;
72
326
  }
327
+ get hasConditionFn() {
328
+ return !!this.conditionFn;
329
+ }
73
330
  shouldRun(args) {
74
331
  if (this.conditionFn) {
75
332
  return this.conditionFn(args);
76
333
  } else {
77
- const isArg = (t) => t[0] !== "[" && t[0] !== "<";
334
+ if (this.default)
335
+ return true;
336
+ const isCmd = (t) => t[0] !== "[" && t[0] !== "<";
78
337
  for (let i = 0; i < this.format.length; i++) {
79
- if (isArg(this.format[i])) {
338
+ if (!isCmd(this.format[i])) {
80
339
  return true;
81
340
  }
82
341
  if (i >= args["_"].length || this.format[i] !== args["_"][i]) {
@@ -86,7 +345,7 @@ class Command {
86
345
  return true;
87
346
  }
88
347
  }
89
- parseArgs(args) {
348
+ parseArgs(args, globalOptions) {
90
349
  if (this.conditionFn) {
91
350
  const argumentss2 = args["_"];
92
351
  const options2 = args;
@@ -97,33 +356,55 @@ class Command {
97
356
  options: args
98
357
  };
99
358
  }
100
- const isArg = (t) => t[0] !== "[" && t[0] !== "<";
359
+ const isCmd = (t) => t[0] !== "[" && t[0] !== "<";
101
360
  const argumentss = [];
102
361
  for (let i = 0; i < this.format.length; i++) {
103
- if (isArg(this.format[i]))
362
+ if (isCmd(this.format[i]))
104
363
  continue;
105
364
  if (i < args["_"].length) {
106
365
  if (this.format[i].startsWith("[...")) {
107
- argumentss.push(args["_"].slice(i));
366
+ argumentss.push(args["_"].slice(i).map(String));
108
367
  } else {
109
- argumentss.push(args["_"][i]);
368
+ argumentss.push(String(args["_"][i]));
110
369
  }
111
370
  } else {
112
371
  if (this.format[i].startsWith("<")) {
372
+ this.logger.warn(`You should provide the argument "${this.format[i]}"`);
113
373
  argumentss.push(void 0);
114
374
  } else if (this.format[i].startsWith("[...")) {
115
375
  argumentss.push([]);
116
376
  } else if (this.format[i].startsWith("[")) {
117
377
  argumentss.push(void 0);
118
- } else ;
378
+ } else {
379
+ this.logger.warn(`unknown format string ("${this.format[i]}")`);
380
+ }
119
381
  }
120
382
  }
383
+ const fullOptions = globalOptions.concat(this.options).reduce((map, o) => {
384
+ map.set(o.name, o);
385
+ return map;
386
+ }, /* @__PURE__ */ new Map());
121
387
  const options = args;
122
388
  delete options["_"];
389
+ for (const [name, rawOption] of fullOptions) {
390
+ if (rawOption.required) {
391
+ if (options[name] === void 0) {
392
+ options[name] = false;
393
+ } else if (options[name] === "") {
394
+ options[name] = true;
395
+ }
396
+ } else {
397
+ if (options[name] === false) {
398
+ options[name] = void 0;
399
+ } else if (!(name in options)) {
400
+ options[name] = void 0;
401
+ }
402
+ }
403
+ }
123
404
  return {
124
405
  command: this,
125
406
  arguments: argumentss,
126
- options: args
407
+ options
127
408
  };
128
409
  }
129
410
  action(fn) {
@@ -131,17 +412,29 @@ class Command {
131
412
  return this;
132
413
  }
133
414
  async run(...args) {
134
- this.actionFn && this.actionFn(...args);
415
+ if (this.actionFn) {
416
+ this.actionFn(...args);
417
+ } else {
418
+ this.logger.warn(`You may miss action function in "${this.format}"`);
419
+ }
135
420
  }
136
- }
137
- Command.MaxDep = 4;
138
- function createVersionCommand(breadc) {
421
+ };
422
+ let Command = _Command;
423
+ Command.MaxDep = 5;
424
+ function createHelpCommand(breadc) {
425
+ let helpCommand = void 0;
139
426
  return new Command("-h, --help", {
140
427
  condition(args) {
141
- const isEmpty = !args["_"].length && !args["--"]?.length;
142
- if (args.help && isEmpty) {
143
- return true;
144
- } else if (args.h && isEmpty) {
428
+ const isEmpty = !args["--"]?.length;
429
+ if ((args.help || args.h) && isEmpty) {
430
+ if (args["_"].length > 0) {
431
+ for (const cmd of breadc.commands) {
432
+ if (!cmd.hasConditionFn && !cmd.default && cmd.shouldRun(args)) {
433
+ helpCommand = cmd;
434
+ return true;
435
+ }
436
+ }
437
+ }
145
438
  return true;
146
439
  } else {
147
440
  return false;
@@ -149,10 +442,12 @@ function createVersionCommand(breadc) {
149
442
  },
150
443
  logger: breadc.logger
151
444
  }).action(() => {
152
- breadc.logger.println("Help");
445
+ for (const line of breadc.help(helpCommand)) {
446
+ breadc.logger.println(line);
447
+ }
153
448
  });
154
449
  }
155
- function createHelpCommand(breadc) {
450
+ function createVersionCommand(breadc) {
156
451
  return new Command("-v, --version", {
157
452
  condition(args) {
158
453
  const isEmpty = !args["_"].length && !args["--"]?.length;
@@ -166,7 +461,7 @@ function createHelpCommand(breadc) {
166
461
  },
167
462
  logger: breadc.logger
168
463
  }).action(() => {
169
- breadc.logger.println(`${breadc.name}/${breadc.version}`);
464
+ breadc.logger.println(breadc.version());
170
465
  });
171
466
  }
172
467
 
@@ -175,22 +470,78 @@ class Breadc {
175
470
  this.options = [];
176
471
  this.commands = [];
177
472
  this.name = name;
178
- this.version = option.version ?? "unknown";
179
- this.logger = option.logger ?? createDefaultLogger(name);
473
+ this._version = option.version ?? "unknown";
474
+ this.description = option.description;
475
+ this.logger = createDefaultLogger(name, option.logger);
180
476
  const breadc = {
181
477
  name: this.name,
182
- version: this.version,
478
+ version: () => this.version.call(this),
479
+ help: (command) => this.help.call(this, command),
183
480
  logger: this.logger,
184
481
  options: this.options,
185
482
  commands: this.commands
186
483
  };
187
- this.commands = [createVersionCommand(breadc), createHelpCommand(breadc)];
484
+ this.commands.push(createVersionCommand(breadc), createHelpCommand(breadc));
188
485
  }
189
- option(format, configOrDescription = "", otherConfig = {}) {
190
- const config = otherConfig;
191
- if (typeof configOrDescription === "string") {
192
- config.description = configOrDescription;
486
+ version() {
487
+ return `${this.name}/${this._version}`;
488
+ }
489
+ help(command) {
490
+ const output = [];
491
+ const println = (msg) => output.push(msg);
492
+ println(this.version());
493
+ if (!command) {
494
+ if (this.description) {
495
+ println("");
496
+ if (Array.isArray(this.description)) {
497
+ for (const line of this.description) {
498
+ println(line);
499
+ }
500
+ } else {
501
+ println(this.description);
502
+ }
503
+ }
504
+ } else {
505
+ if (command.description) {
506
+ println("");
507
+ println(command.description);
508
+ }
509
+ }
510
+ if (!command) {
511
+ if (this.defaultCommand) {
512
+ println(``);
513
+ println(`Usage:`);
514
+ println(` $ ${this.name} ${this.defaultCommand.format.join(" ")}`);
515
+ }
516
+ } else {
517
+ println(``);
518
+ println(`Usage:`);
519
+ println(` $ ${this.name} ${command.format.join(" ")}`);
520
+ }
521
+ if (!command && this.commands.length > 2) {
522
+ println(``);
523
+ println(`Commands:`);
524
+ const commandHelps = this.commands.filter((c) => !c.hasConditionFn).map((c) => [` $ ${this.name} ${c.format.join(" ")}`, c.description]);
525
+ for (const line of twoColumn(commandHelps)) {
526
+ println(line);
527
+ }
528
+ }
529
+ println(``);
530
+ println(`Options:`);
531
+ const optionHelps = [].concat([
532
+ ...command ? command.options.map((o) => [` ${o.format}`, o.description]) : [],
533
+ ...this.options.map((o) => [` ${o.format}`, o.description]),
534
+ [` -h, --help`, `Display this message`],
535
+ [` -v, --version`, `Display version number`]
536
+ ]);
537
+ for (const line of twoColumn(optionHelps)) {
538
+ println(line);
193
539
  }
540
+ println(``);
541
+ return output;
542
+ }
543
+ option(format, configOrDescription = "", otherConfig = {}) {
544
+ const config = typeof configOrDescription === "object" ? configOrDescription : { ...otherConfig, description: configOrDescription };
194
545
  try {
195
546
  const option = new Option(format, config);
196
547
  this.options.push(option);
@@ -199,32 +550,64 @@ class Breadc {
199
550
  }
200
551
  return this;
201
552
  }
202
- command(format, config = {}) {
553
+ command(format, configOrDescription = "", otherConfig = {}) {
554
+ const config = typeof configOrDescription === "object" ? configOrDescription : { ...otherConfig, description: configOrDescription };
203
555
  const command = new Command(format, { ...config, logger: this.logger });
556
+ if (command.default) {
557
+ if (this.defaultCommand) {
558
+ this.logger.warn("You can not have two default commands.");
559
+ }
560
+ this.defaultCommand = command;
561
+ }
204
562
  this.commands.push(command);
205
563
  return command;
206
564
  }
207
565
  parse(args) {
208
- const allowOptions = [this.options, this.commands.map((c) => c.options)].flat();
566
+ const allowOptions = [
567
+ ...this.options,
568
+ ...this.commands.flatMap((c) => c.options)
569
+ ];
209
570
  const alias = allowOptions.reduce((map, o) => {
210
571
  if (o.shortcut) {
211
572
  map[o.shortcut] = o.name;
212
573
  }
213
574
  return map;
214
575
  }, {});
576
+ const defaults = allowOptions.reduce((map, o) => {
577
+ if (o.default) {
578
+ map[o.name] = o.default;
579
+ }
580
+ return map;
581
+ }, {});
215
582
  const argv = minimist(args, {
216
583
  string: allowOptions.filter((o) => o.type === "string").map((o) => o.name),
217
584
  boolean: allowOptions.filter((o) => o.type === "boolean").map((o) => o.name),
218
- alias
585
+ alias,
586
+ default: defaults,
587
+ unknown: (t) => {
588
+ if (t[0] !== "-")
589
+ return true;
590
+ else {
591
+ if (["--help", "-h", "--version", "-v"].includes(t)) {
592
+ return true;
593
+ } else {
594
+ this.logger.warn(`Find unknown flag "${t}"`);
595
+ return false;
596
+ }
597
+ }
598
+ }
219
599
  });
220
600
  for (const shortcut of Object.keys(alias)) {
221
601
  delete argv[shortcut];
222
602
  }
223
603
  for (const command of this.commands) {
224
- if (command.shouldRun(argv)) {
225
- return command.parseArgs(argv);
604
+ if (!command.default && command.shouldRun(argv)) {
605
+ return command.parseArgs(argv, this.options);
226
606
  }
227
607
  }
608
+ if (this.defaultCommand) {
609
+ return this.defaultCommand.parseArgs(argv, this.options);
610
+ }
228
611
  const argumentss = argv["_"];
229
612
  const options = argv;
230
613
  delete options["_"];
@@ -241,9 +624,17 @@ class Breadc {
241
624
  }
242
625
  }
243
626
  }
627
+ function twoColumn(texts, split = " ") {
628
+ const left = padRight(texts.map((t) => t[0]));
629
+ return left.map((l, idx) => l + split + texts[idx][1]);
630
+ }
631
+ function padRight(texts, fill = " ") {
632
+ const length = texts.map((t) => t.length).reduce((max, l) => Math.max(max, l), 0);
633
+ return texts.map((t) => t + fill.repeat(length - t.length));
634
+ }
244
635
 
245
636
  function breadc(name, option = {}) {
246
637
  return new Breadc(name, option);
247
638
  }
248
639
 
249
- export { breadc as default };
640
+ export { breadc as default, minimist };