breadc 0.8.2 → 0.8.3
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 +1 -1
- package/dist/index.cjs +123 -92
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +123 -92
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Yet another Command Line Application Framework with fully strong **[TypeScript](
|
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
+ ⚡️ **Light-weight**: Only
|
|
11
|
+
+ ⚡️ **Light-weight**: Only 75 kB (Unpacked).
|
|
12
12
|
+ 📖 **East to Learn**: Breadc is basically compatible with [cac](https://github.com/cacjs/cac) and there are only 5 APIs for building a CLI application: `breadc`, `command`, `option`, `action`, `run`.
|
|
13
13
|
+ 💻 **TypeScript Infer**: IDE will automatically infer the type of your command action function.
|
|
14
14
|
|
package/dist/index.cjs
CHANGED
|
@@ -128,6 +128,7 @@ class Token {
|
|
|
128
128
|
return this._type = "string";
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
/* c8 ignore next 1 */
|
|
131
132
|
}
|
|
132
133
|
class Lexer {
|
|
133
134
|
constructor(rawArgs) {
|
|
@@ -140,7 +141,7 @@ class Lexer {
|
|
|
140
141
|
return value ? new Token(value) : void 0;
|
|
141
142
|
}
|
|
142
143
|
hasNext() {
|
|
143
|
-
return this.cursor
|
|
144
|
+
return this.cursor < this.rawArgs.length;
|
|
144
145
|
}
|
|
145
146
|
peek() {
|
|
146
147
|
const value = this.rawArgs[this.cursor];
|
|
@@ -153,7 +154,7 @@ class Lexer {
|
|
|
153
154
|
const value = that.rawArgs[that.cursor];
|
|
154
155
|
that.cursor += 1;
|
|
155
156
|
return {
|
|
156
|
-
value: value ? new Token(value) : void 0,
|
|
157
|
+
value: value !== void 0 ? new Token(value) : void 0,
|
|
157
158
|
done: that.cursor > that.rawArgs.length
|
|
158
159
|
};
|
|
159
160
|
}
|
|
@@ -340,13 +341,13 @@ const initContextOptions = (options, context) => {
|
|
|
340
341
|
};
|
|
341
342
|
|
|
342
343
|
function makeCommand(format, config, root, container) {
|
|
343
|
-
let cursor = root;
|
|
344
344
|
const args = [];
|
|
345
345
|
const options = [];
|
|
346
346
|
const command = {
|
|
347
347
|
callback: void 0,
|
|
348
348
|
format,
|
|
349
349
|
description: config.description ?? "",
|
|
350
|
+
_default: false,
|
|
350
351
|
_arguments: args,
|
|
351
352
|
_options: options,
|
|
352
353
|
option(format2, _config, _config2 = {}) {
|
|
@@ -355,6 +356,21 @@ function makeCommand(format, config, root, container) {
|
|
|
355
356
|
options.push(option);
|
|
356
357
|
return command;
|
|
357
358
|
},
|
|
359
|
+
alias(format2) {
|
|
360
|
+
const aliasArgs = [];
|
|
361
|
+
const node2 = makeNode(aliasArgs);
|
|
362
|
+
function* g() {
|
|
363
|
+
for (const f of format2.split(" ")) {
|
|
364
|
+
yield { type: "const", name: f };
|
|
365
|
+
}
|
|
366
|
+
for (const a of args.filter((a2) => a2.type !== "const")) {
|
|
367
|
+
yield a;
|
|
368
|
+
}
|
|
369
|
+
return void 0;
|
|
370
|
+
}
|
|
371
|
+
insertTreeNode(aliasArgs, node2, g());
|
|
372
|
+
return command;
|
|
373
|
+
},
|
|
358
374
|
action(fn) {
|
|
359
375
|
command.callback = async (parsed) => {
|
|
360
376
|
await container.preCommand(command, parsed);
|
|
@@ -367,78 +383,45 @@ function makeCommand(format, config, root, container) {
|
|
|
367
383
|
};
|
|
368
384
|
}
|
|
369
385
|
};
|
|
370
|
-
const node =
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
386
|
+
const node = makeNode(args);
|
|
387
|
+
insertTreeNode(args, node, parseCommandFormat(format));
|
|
388
|
+
return command;
|
|
389
|
+
function makeNode(args2) {
|
|
390
|
+
return makeTreeNode({
|
|
391
|
+
command,
|
|
392
|
+
init(context) {
|
|
393
|
+
initContextOptions(options, context);
|
|
394
|
+
},
|
|
395
|
+
finish(context) {
|
|
396
|
+
const rest = context.result["--"];
|
|
397
|
+
for (let i = 0; i < args2.length; i++) {
|
|
398
|
+
if (args2[i].type === "const") {
|
|
399
|
+
if (rest[i] !== args2[i].name) {
|
|
400
|
+
throw new ParseError(`Sub-command ${args2[i].name} mismatch`);
|
|
401
|
+
}
|
|
402
|
+
} else if (args2[i].type === "require") {
|
|
403
|
+
if (i >= rest.length) {
|
|
404
|
+
throw new ParseError(
|
|
405
|
+
`You must provide require argument ${args2[i].name}`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
context.result.arguments.push(rest[i]);
|
|
409
|
+
} else if (args2[i].type === "optional") {
|
|
410
|
+
context.result.arguments.push(rest[i]);
|
|
411
|
+
} else if (args2[i].type === "rest") {
|
|
412
|
+
context.result.arguments.push(rest.splice(i));
|
|
387
413
|
}
|
|
388
|
-
context.result.arguments.push(rest[i]);
|
|
389
|
-
} else if (args[i].type === "optional") {
|
|
390
|
-
context.result.arguments.push(rest[i]);
|
|
391
|
-
} else if (args[i].type === "rest") {
|
|
392
|
-
context.result.arguments.push(rest.splice(i));
|
|
393
414
|
}
|
|
415
|
+
context.result["--"] = rest.splice(args2.length);
|
|
394
416
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (
|
|
402
|
-
|
|
403
|
-
throw new BreadcError(
|
|
404
|
-
`Required arguments should be placed before optional or rest arguments`
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
const start = i;
|
|
408
|
-
while (i < format.length && format[i] !== ">") {
|
|
409
|
-
i++;
|
|
410
|
-
}
|
|
411
|
-
const name = format.slice(start + 1, i);
|
|
412
|
-
state = 1;
|
|
413
|
-
args.push({ type: "require", name });
|
|
414
|
-
} else if (format[i] === "[") {
|
|
415
|
-
if (state !== 0 && state !== 1) {
|
|
416
|
-
throw new BreadcError(
|
|
417
|
-
`There is at most one optional or rest arguments`
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
const start = i;
|
|
421
|
-
while (i < format.length && format[i] !== "]") {
|
|
422
|
-
i++;
|
|
423
|
-
}
|
|
424
|
-
const name = format.slice(start + 1, i);
|
|
425
|
-
state = 2;
|
|
426
|
-
if (name.startsWith("...")) {
|
|
427
|
-
args.push({ type: "rest", name });
|
|
428
|
-
} else {
|
|
429
|
-
args.push({ type: "optional", name });
|
|
430
|
-
}
|
|
431
|
-
} else if (format[i] !== " ") {
|
|
432
|
-
if (state !== 0) {
|
|
433
|
-
throw new BreadcError(
|
|
434
|
-
`Sub-command should be placed at the beginning`
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
const start = i;
|
|
438
|
-
while (i < format.length && format[i] !== " ") {
|
|
439
|
-
i++;
|
|
440
|
-
}
|
|
441
|
-
const name = format.slice(start, i);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function insertTreeNode(args2, node2, parsed) {
|
|
420
|
+
let cursor = root;
|
|
421
|
+
for (const arg of parsed) {
|
|
422
|
+
args2.push(arg);
|
|
423
|
+
if (arg.type === "const") {
|
|
424
|
+
const name = arg.name;
|
|
442
425
|
if (cursor.children.has(name)) {
|
|
443
426
|
cursor = cursor.children.get(name);
|
|
444
427
|
} else {
|
|
@@ -461,24 +444,70 @@ function makeCommand(format, config, root, container) {
|
|
|
461
444
|
cursor.children.set(name, internalNode);
|
|
462
445
|
cursor = internalNode;
|
|
463
446
|
}
|
|
464
|
-
state = 0;
|
|
465
|
-
args.push({ type: "const", name });
|
|
466
447
|
}
|
|
467
448
|
}
|
|
468
449
|
cursor.command = command;
|
|
469
450
|
if (cursor !== root) {
|
|
470
451
|
for (const [key, value] of cursor.children) {
|
|
471
|
-
|
|
452
|
+
node2.children.set(key, value);
|
|
472
453
|
}
|
|
473
|
-
cursor.children =
|
|
474
|
-
cursor.next =
|
|
475
|
-
cursor.init =
|
|
476
|
-
cursor.finish =
|
|
454
|
+
cursor.children = node2.children;
|
|
455
|
+
cursor.next = node2.next;
|
|
456
|
+
cursor.init = node2.init;
|
|
457
|
+
cursor.finish = node2.finish;
|
|
477
458
|
} else {
|
|
478
|
-
|
|
459
|
+
command._default = true;
|
|
460
|
+
cursor.finish = node2.finish;
|
|
479
461
|
}
|
|
480
462
|
}
|
|
481
|
-
|
|
463
|
+
}
|
|
464
|
+
function* parseCommandFormat(format) {
|
|
465
|
+
let state = 0;
|
|
466
|
+
for (let i = 0; i < format.length; i++) {
|
|
467
|
+
if (format[i] === "<") {
|
|
468
|
+
if (state !== 0 && state !== 1) {
|
|
469
|
+
throw new BreadcError(
|
|
470
|
+
`Required arguments should be placed before optional or rest arguments`
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
const start = i;
|
|
474
|
+
while (i < format.length && format[i] !== ">") {
|
|
475
|
+
i++;
|
|
476
|
+
}
|
|
477
|
+
const name = format.slice(start + 1, i);
|
|
478
|
+
state = 1;
|
|
479
|
+
yield { type: "require", name };
|
|
480
|
+
} else if (format[i] === "[") {
|
|
481
|
+
if (state !== 0 && state !== 1) {
|
|
482
|
+
throw new BreadcError(
|
|
483
|
+
`There is at most one optional or rest arguments`
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
const start = i;
|
|
487
|
+
while (i < format.length && format[i] !== "]") {
|
|
488
|
+
i++;
|
|
489
|
+
}
|
|
490
|
+
const name = format.slice(start + 1, i);
|
|
491
|
+
state = 2;
|
|
492
|
+
if (name.startsWith("...")) {
|
|
493
|
+
yield { type: "rest", name };
|
|
494
|
+
} else {
|
|
495
|
+
yield { type: "optional", name };
|
|
496
|
+
}
|
|
497
|
+
} else if (format[i] !== " ") {
|
|
498
|
+
if (state !== 0) {
|
|
499
|
+
throw new BreadcError(`Sub-command should be placed at the beginning`);
|
|
500
|
+
}
|
|
501
|
+
const start = i;
|
|
502
|
+
while (i < format.length && format[i] !== " ") {
|
|
503
|
+
i++;
|
|
504
|
+
}
|
|
505
|
+
const name = format.slice(start, i);
|
|
506
|
+
state = 0;
|
|
507
|
+
yield { type: "const", name };
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return void 0;
|
|
482
511
|
}
|
|
483
512
|
function makeVersionCommand(name, config) {
|
|
484
513
|
const command = {
|
|
@@ -491,11 +520,12 @@ function makeVersionCommand(name, config) {
|
|
|
491
520
|
description: "Print version",
|
|
492
521
|
_arguments: [],
|
|
493
522
|
_options: [],
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
523
|
+
// @ts-ignore
|
|
524
|
+
option: void 0,
|
|
525
|
+
// @ts-ignore
|
|
526
|
+
alias: void 0,
|
|
527
|
+
// @ts-ignore
|
|
528
|
+
action: void 0
|
|
499
529
|
};
|
|
500
530
|
const node = makeTreeNode({
|
|
501
531
|
command,
|
|
@@ -600,11 +630,12 @@ function makeHelpCommand(name, config) {
|
|
|
600
630
|
description: "Print help",
|
|
601
631
|
_arguments: [],
|
|
602
632
|
_options: [],
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
633
|
+
// @ts-ignore
|
|
634
|
+
option: void 0,
|
|
635
|
+
// @ts-ignore
|
|
636
|
+
alias: void 0,
|
|
637
|
+
// @ts-ignore
|
|
638
|
+
action: void 0
|
|
608
639
|
};
|
|
609
640
|
const node = makeTreeNode({
|
|
610
641
|
command,
|
|
@@ -657,7 +688,7 @@ function breadc(name, config = {}) {
|
|
|
657
688
|
command(text, _config = {}) {
|
|
658
689
|
const config2 = typeof _config === "string" ? { description: _config } : _config;
|
|
659
690
|
const command = makeCommand(text, config2, root, container);
|
|
660
|
-
if (command.
|
|
691
|
+
if (command._default) {
|
|
661
692
|
defaultCommand = command;
|
|
662
693
|
}
|
|
663
694
|
return command;
|
package/dist/index.d.ts
CHANGED
|
@@ -104,10 +104,12 @@ interface Command<F extends string = string, AT extends any[] = ExtractCommand<F
|
|
|
104
104
|
callback?: (result: ParseResult) => Promise<any>;
|
|
105
105
|
format: F;
|
|
106
106
|
description: string;
|
|
107
|
+
_default: boolean;
|
|
107
108
|
_arguments: Argument[];
|
|
108
109
|
_options: Option[];
|
|
109
110
|
option<OF extends string = string, OT extends string | boolean = ExtractOptionType<OF>, OR extends any = ExtractOptionType<OF>>(format: OF, description?: string, option?: OptionOption<OT, OR>): Command<F, AT, CommandOption & ExtractOption<OF, OR>, GlobalOption>;
|
|
110
111
|
option<OF extends string = string, OT extends string | boolean = ExtractOptionType<OF>, OR extends any = ExtractOptionType<OF>>(format: OF, option?: OptionOption<OT, OR>): Command<F, AT, CommandOption & ExtractOption<OF, OR>, GlobalOption>;
|
|
112
|
+
alias(format: string): Command<F, AT, CommandOption, GlobalOption>;
|
|
111
113
|
action(fn: ActionFn<AT, CommandOption & GlobalOption>): void;
|
|
112
114
|
}
|
|
113
115
|
interface CommandOption {
|
package/dist/index.mjs
CHANGED
|
@@ -124,6 +124,7 @@ class Token {
|
|
|
124
124
|
return this._type = "string";
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
+
/* c8 ignore next 1 */
|
|
127
128
|
}
|
|
128
129
|
class Lexer {
|
|
129
130
|
constructor(rawArgs) {
|
|
@@ -136,7 +137,7 @@ class Lexer {
|
|
|
136
137
|
return value ? new Token(value) : void 0;
|
|
137
138
|
}
|
|
138
139
|
hasNext() {
|
|
139
|
-
return this.cursor
|
|
140
|
+
return this.cursor < this.rawArgs.length;
|
|
140
141
|
}
|
|
141
142
|
peek() {
|
|
142
143
|
const value = this.rawArgs[this.cursor];
|
|
@@ -149,7 +150,7 @@ class Lexer {
|
|
|
149
150
|
const value = that.rawArgs[that.cursor];
|
|
150
151
|
that.cursor += 1;
|
|
151
152
|
return {
|
|
152
|
-
value: value ? new Token(value) : void 0,
|
|
153
|
+
value: value !== void 0 ? new Token(value) : void 0,
|
|
153
154
|
done: that.cursor > that.rawArgs.length
|
|
154
155
|
};
|
|
155
156
|
}
|
|
@@ -336,13 +337,13 @@ const initContextOptions = (options, context) => {
|
|
|
336
337
|
};
|
|
337
338
|
|
|
338
339
|
function makeCommand(format, config, root, container) {
|
|
339
|
-
let cursor = root;
|
|
340
340
|
const args = [];
|
|
341
341
|
const options = [];
|
|
342
342
|
const command = {
|
|
343
343
|
callback: void 0,
|
|
344
344
|
format,
|
|
345
345
|
description: config.description ?? "",
|
|
346
|
+
_default: false,
|
|
346
347
|
_arguments: args,
|
|
347
348
|
_options: options,
|
|
348
349
|
option(format2, _config, _config2 = {}) {
|
|
@@ -351,6 +352,21 @@ function makeCommand(format, config, root, container) {
|
|
|
351
352
|
options.push(option);
|
|
352
353
|
return command;
|
|
353
354
|
},
|
|
355
|
+
alias(format2) {
|
|
356
|
+
const aliasArgs = [];
|
|
357
|
+
const node2 = makeNode(aliasArgs);
|
|
358
|
+
function* g() {
|
|
359
|
+
for (const f of format2.split(" ")) {
|
|
360
|
+
yield { type: "const", name: f };
|
|
361
|
+
}
|
|
362
|
+
for (const a of args.filter((a2) => a2.type !== "const")) {
|
|
363
|
+
yield a;
|
|
364
|
+
}
|
|
365
|
+
return void 0;
|
|
366
|
+
}
|
|
367
|
+
insertTreeNode(aliasArgs, node2, g());
|
|
368
|
+
return command;
|
|
369
|
+
},
|
|
354
370
|
action(fn) {
|
|
355
371
|
command.callback = async (parsed) => {
|
|
356
372
|
await container.preCommand(command, parsed);
|
|
@@ -363,78 +379,45 @@ function makeCommand(format, config, root, container) {
|
|
|
363
379
|
};
|
|
364
380
|
}
|
|
365
381
|
};
|
|
366
|
-
const node =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
382
|
+
const node = makeNode(args);
|
|
383
|
+
insertTreeNode(args, node, parseCommandFormat(format));
|
|
384
|
+
return command;
|
|
385
|
+
function makeNode(args2) {
|
|
386
|
+
return makeTreeNode({
|
|
387
|
+
command,
|
|
388
|
+
init(context) {
|
|
389
|
+
initContextOptions(options, context);
|
|
390
|
+
},
|
|
391
|
+
finish(context) {
|
|
392
|
+
const rest = context.result["--"];
|
|
393
|
+
for (let i = 0; i < args2.length; i++) {
|
|
394
|
+
if (args2[i].type === "const") {
|
|
395
|
+
if (rest[i] !== args2[i].name) {
|
|
396
|
+
throw new ParseError(`Sub-command ${args2[i].name} mismatch`);
|
|
397
|
+
}
|
|
398
|
+
} else if (args2[i].type === "require") {
|
|
399
|
+
if (i >= rest.length) {
|
|
400
|
+
throw new ParseError(
|
|
401
|
+
`You must provide require argument ${args2[i].name}`
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
context.result.arguments.push(rest[i]);
|
|
405
|
+
} else if (args2[i].type === "optional") {
|
|
406
|
+
context.result.arguments.push(rest[i]);
|
|
407
|
+
} else if (args2[i].type === "rest") {
|
|
408
|
+
context.result.arguments.push(rest.splice(i));
|
|
383
409
|
}
|
|
384
|
-
context.result.arguments.push(rest[i]);
|
|
385
|
-
} else if (args[i].type === "optional") {
|
|
386
|
-
context.result.arguments.push(rest[i]);
|
|
387
|
-
} else if (args[i].type === "rest") {
|
|
388
|
-
context.result.arguments.push(rest.splice(i));
|
|
389
410
|
}
|
|
411
|
+
context.result["--"] = rest.splice(args2.length);
|
|
390
412
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (
|
|
398
|
-
|
|
399
|
-
throw new BreadcError(
|
|
400
|
-
`Required arguments should be placed before optional or rest arguments`
|
|
401
|
-
);
|
|
402
|
-
}
|
|
403
|
-
const start = i;
|
|
404
|
-
while (i < format.length && format[i] !== ">") {
|
|
405
|
-
i++;
|
|
406
|
-
}
|
|
407
|
-
const name = format.slice(start + 1, i);
|
|
408
|
-
state = 1;
|
|
409
|
-
args.push({ type: "require", name });
|
|
410
|
-
} else if (format[i] === "[") {
|
|
411
|
-
if (state !== 0 && state !== 1) {
|
|
412
|
-
throw new BreadcError(
|
|
413
|
-
`There is at most one optional or rest arguments`
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
const start = i;
|
|
417
|
-
while (i < format.length && format[i] !== "]") {
|
|
418
|
-
i++;
|
|
419
|
-
}
|
|
420
|
-
const name = format.slice(start + 1, i);
|
|
421
|
-
state = 2;
|
|
422
|
-
if (name.startsWith("...")) {
|
|
423
|
-
args.push({ type: "rest", name });
|
|
424
|
-
} else {
|
|
425
|
-
args.push({ type: "optional", name });
|
|
426
|
-
}
|
|
427
|
-
} else if (format[i] !== " ") {
|
|
428
|
-
if (state !== 0) {
|
|
429
|
-
throw new BreadcError(
|
|
430
|
-
`Sub-command should be placed at the beginning`
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
const start = i;
|
|
434
|
-
while (i < format.length && format[i] !== " ") {
|
|
435
|
-
i++;
|
|
436
|
-
}
|
|
437
|
-
const name = format.slice(start, i);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function insertTreeNode(args2, node2, parsed) {
|
|
416
|
+
let cursor = root;
|
|
417
|
+
for (const arg of parsed) {
|
|
418
|
+
args2.push(arg);
|
|
419
|
+
if (arg.type === "const") {
|
|
420
|
+
const name = arg.name;
|
|
438
421
|
if (cursor.children.has(name)) {
|
|
439
422
|
cursor = cursor.children.get(name);
|
|
440
423
|
} else {
|
|
@@ -457,24 +440,70 @@ function makeCommand(format, config, root, container) {
|
|
|
457
440
|
cursor.children.set(name, internalNode);
|
|
458
441
|
cursor = internalNode;
|
|
459
442
|
}
|
|
460
|
-
state = 0;
|
|
461
|
-
args.push({ type: "const", name });
|
|
462
443
|
}
|
|
463
444
|
}
|
|
464
445
|
cursor.command = command;
|
|
465
446
|
if (cursor !== root) {
|
|
466
447
|
for (const [key, value] of cursor.children) {
|
|
467
|
-
|
|
448
|
+
node2.children.set(key, value);
|
|
468
449
|
}
|
|
469
|
-
cursor.children =
|
|
470
|
-
cursor.next =
|
|
471
|
-
cursor.init =
|
|
472
|
-
cursor.finish =
|
|
450
|
+
cursor.children = node2.children;
|
|
451
|
+
cursor.next = node2.next;
|
|
452
|
+
cursor.init = node2.init;
|
|
453
|
+
cursor.finish = node2.finish;
|
|
473
454
|
} else {
|
|
474
|
-
|
|
455
|
+
command._default = true;
|
|
456
|
+
cursor.finish = node2.finish;
|
|
475
457
|
}
|
|
476
458
|
}
|
|
477
|
-
|
|
459
|
+
}
|
|
460
|
+
function* parseCommandFormat(format) {
|
|
461
|
+
let state = 0;
|
|
462
|
+
for (let i = 0; i < format.length; i++) {
|
|
463
|
+
if (format[i] === "<") {
|
|
464
|
+
if (state !== 0 && state !== 1) {
|
|
465
|
+
throw new BreadcError(
|
|
466
|
+
`Required arguments should be placed before optional or rest arguments`
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
const start = i;
|
|
470
|
+
while (i < format.length && format[i] !== ">") {
|
|
471
|
+
i++;
|
|
472
|
+
}
|
|
473
|
+
const name = format.slice(start + 1, i);
|
|
474
|
+
state = 1;
|
|
475
|
+
yield { type: "require", name };
|
|
476
|
+
} else if (format[i] === "[") {
|
|
477
|
+
if (state !== 0 && state !== 1) {
|
|
478
|
+
throw new BreadcError(
|
|
479
|
+
`There is at most one optional or rest arguments`
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
const start = i;
|
|
483
|
+
while (i < format.length && format[i] !== "]") {
|
|
484
|
+
i++;
|
|
485
|
+
}
|
|
486
|
+
const name = format.slice(start + 1, i);
|
|
487
|
+
state = 2;
|
|
488
|
+
if (name.startsWith("...")) {
|
|
489
|
+
yield { type: "rest", name };
|
|
490
|
+
} else {
|
|
491
|
+
yield { type: "optional", name };
|
|
492
|
+
}
|
|
493
|
+
} else if (format[i] !== " ") {
|
|
494
|
+
if (state !== 0) {
|
|
495
|
+
throw new BreadcError(`Sub-command should be placed at the beginning`);
|
|
496
|
+
}
|
|
497
|
+
const start = i;
|
|
498
|
+
while (i < format.length && format[i] !== " ") {
|
|
499
|
+
i++;
|
|
500
|
+
}
|
|
501
|
+
const name = format.slice(start, i);
|
|
502
|
+
state = 0;
|
|
503
|
+
yield { type: "const", name };
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return void 0;
|
|
478
507
|
}
|
|
479
508
|
function makeVersionCommand(name, config) {
|
|
480
509
|
const command = {
|
|
@@ -487,11 +516,12 @@ function makeVersionCommand(name, config) {
|
|
|
487
516
|
description: "Print version",
|
|
488
517
|
_arguments: [],
|
|
489
518
|
_options: [],
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
519
|
+
// @ts-ignore
|
|
520
|
+
option: void 0,
|
|
521
|
+
// @ts-ignore
|
|
522
|
+
alias: void 0,
|
|
523
|
+
// @ts-ignore
|
|
524
|
+
action: void 0
|
|
495
525
|
};
|
|
496
526
|
const node = makeTreeNode({
|
|
497
527
|
command,
|
|
@@ -596,11 +626,12 @@ function makeHelpCommand(name, config) {
|
|
|
596
626
|
description: "Print help",
|
|
597
627
|
_arguments: [],
|
|
598
628
|
_options: [],
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
629
|
+
// @ts-ignore
|
|
630
|
+
option: void 0,
|
|
631
|
+
// @ts-ignore
|
|
632
|
+
alias: void 0,
|
|
633
|
+
// @ts-ignore
|
|
634
|
+
action: void 0
|
|
604
635
|
};
|
|
605
636
|
const node = makeTreeNode({
|
|
606
637
|
command,
|
|
@@ -653,7 +684,7 @@ function breadc(name, config = {}) {
|
|
|
653
684
|
command(text, _config = {}) {
|
|
654
685
|
const config2 = typeof _config === "string" ? { description: _config } : _config;
|
|
655
686
|
const command = makeCommand(text, config2, root, container);
|
|
656
|
-
if (command.
|
|
687
|
+
if (command._default) {
|
|
657
688
|
defaultCommand = command;
|
|
658
689
|
}
|
|
659
690
|
return command;
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breadc",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Yet another Command Line Application Framework with fully strong TypeScript support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"breadc",
|
|
7
7
|
"cli",
|
|
8
8
|
"framework",
|
|
9
9
|
"command-line",
|
|
10
|
-
"minimist",
|
|
11
10
|
"typescript"
|
|
12
11
|
],
|
|
13
12
|
"homepage": "https://github.com/yjl9903/Breadc#readme",
|
|
@@ -35,7 +34,7 @@
|
|
|
35
34
|
"dist"
|
|
36
35
|
],
|
|
37
36
|
"dependencies": {
|
|
38
|
-
"@breadc/color": "0.8.
|
|
37
|
+
"@breadc/color": "0.8.3"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
41
40
|
"@types/node": "^18.11.18",
|