bob-core 0.7.0 → 0.8.1
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/Command.d.ts +4 -4
- package/dist/Command.js +3 -3
- package/dist/CommandHelper.d.ts +1 -1
- package/dist/CommandHelper.js +11 -3
- package/dist/CommandParser.d.ts +35 -0
- package/dist/CommandParser.js +162 -0
- package/dist/Parser.d.ts +3 -2
- package/dist/Parser.js +25 -8
- package/dist/errors/MissingRequiredArgumentValue.d.ts +1 -1
- package/package.json +1 -1
package/dist/Command.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommandHelper } from "./CommandHelper";
|
|
2
|
-
import {
|
|
2
|
+
import { CommandParser } from "./CommandParser";
|
|
3
3
|
export type CommandExample = {
|
|
4
4
|
description: string;
|
|
5
5
|
command: string;
|
|
@@ -12,10 +12,10 @@ export declare abstract class Command<C = undefined> extends CommandHelper {
|
|
|
12
12
|
[key: string]: string;
|
|
13
13
|
};
|
|
14
14
|
protected commandsExamples: CommandExample[];
|
|
15
|
-
protected parser:
|
|
15
|
+
protected parser: CommandParser;
|
|
16
16
|
get command(): string;
|
|
17
17
|
protected abstract handle(): Promise<void | number>;
|
|
18
18
|
run(ctx: C, ...args: any[]): Promise<number>;
|
|
19
|
-
protected option(key: string, defaultValue?:
|
|
20
|
-
protected argument(key: string, defaultValue?:
|
|
19
|
+
protected option<T = string | number | boolean | string[] | number[]>(key: string, defaultValue?: T | null): T | null;
|
|
20
|
+
protected argument<T = string | number | boolean | string[] | number[]>(key: string, defaultValue?: T | null): T | null;
|
|
21
21
|
}
|
package/dist/Command.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Command = void 0;
|
|
4
4
|
const CommandHelper_1 = require("./CommandHelper");
|
|
5
|
-
const
|
|
5
|
+
const CommandParser_1 = require("./CommandParser");
|
|
6
6
|
class Command extends CommandHelper_1.CommandHelper {
|
|
7
7
|
ctx;
|
|
8
8
|
helperDefinitions = {};
|
|
@@ -16,7 +16,7 @@ class Command extends CommandHelper_1.CommandHelper {
|
|
|
16
16
|
}
|
|
17
17
|
async run(ctx, ...args) {
|
|
18
18
|
this.ctx = ctx;
|
|
19
|
-
this.parser = new
|
|
19
|
+
this.parser = new CommandParser_1.CommandParser(this.signature, this.helperDefinitions, ...args);
|
|
20
20
|
if (args.includes('--help') || args.includes('-h')) {
|
|
21
21
|
return this.help.call(this);
|
|
22
22
|
}
|
|
@@ -26,7 +26,7 @@ class Command extends CommandHelper_1.CommandHelper {
|
|
|
26
26
|
option(key, defaultValue = null) {
|
|
27
27
|
return this.parser.option(key) ?? defaultValue;
|
|
28
28
|
}
|
|
29
|
-
argument(key, defaultValue) {
|
|
29
|
+
argument(key, defaultValue = null) {
|
|
30
30
|
return this.parser.argument(key) ?? defaultValue;
|
|
31
31
|
}
|
|
32
32
|
}
|
package/dist/CommandHelper.d.ts
CHANGED
package/dist/CommandHelper.js
CHANGED
|
@@ -39,7 +39,15 @@ class CommandHelper {
|
|
|
39
39
|
log((0, chalk_1.default) `\n{yellow Arguments}:`);
|
|
40
40
|
for (const signature of availableArguments) {
|
|
41
41
|
const spaces = (0, string_1.generateSpace)(maxLength - signature.name.length);
|
|
42
|
-
|
|
42
|
+
let message = (0, chalk_1.default) ` {green ${signature.name}} ${spaces} ${signature.help ?? '\b'}`;
|
|
43
|
+
if (signature.defaultValue !== undefined && signature.optional) {
|
|
44
|
+
const defaultValue = signature.type === 'array' ? JSON.stringify(signature.defaultValue) : signature.defaultValue;
|
|
45
|
+
message += (0, chalk_1.default) ` {yellow [default: ${defaultValue}]}`;
|
|
46
|
+
}
|
|
47
|
+
if (signature.variadic) {
|
|
48
|
+
message += (0, chalk_1.default) ` {white (variadic)}`;
|
|
49
|
+
}
|
|
50
|
+
log(message);
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
if (availableOptions.length > 0) {
|
|
@@ -51,8 +59,8 @@ class CommandHelper {
|
|
|
51
59
|
message += (0, chalk_1.default) ` {white (${signature.type})}`;
|
|
52
60
|
}
|
|
53
61
|
if (signature.defaultValue !== undefined && signature.optional) {
|
|
54
|
-
const
|
|
55
|
-
message += (0, chalk_1.default) ` {yellow [default: ${
|
|
62
|
+
const defaultValue = signature.type === 'array' ? JSON.stringify(signature.defaultValue) : signature.defaultValue;
|
|
63
|
+
message += (0, chalk_1.default) ` {yellow [default: ${defaultValue}]}`;
|
|
56
64
|
}
|
|
57
65
|
log(message);
|
|
58
66
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type ArgSignature = {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
optional?: boolean;
|
|
5
|
+
variadic?: boolean;
|
|
6
|
+
alias?: string[];
|
|
7
|
+
help?: string;
|
|
8
|
+
defaultValue?: string | boolean | Array<string> | null;
|
|
9
|
+
isOption?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare class CommandParser {
|
|
12
|
+
protected readonly signature: string;
|
|
13
|
+
protected readonly helperDefinitions: {
|
|
14
|
+
[key: string]: string;
|
|
15
|
+
};
|
|
16
|
+
command: string;
|
|
17
|
+
private arguments;
|
|
18
|
+
private options;
|
|
19
|
+
private argumentsSignature;
|
|
20
|
+
private optionsSignature;
|
|
21
|
+
option(name: string): any;
|
|
22
|
+
argument(name: string): any;
|
|
23
|
+
argumentsSignatures(): {
|
|
24
|
+
[argument: string]: ArgSignature;
|
|
25
|
+
};
|
|
26
|
+
optionsSignatures(): {
|
|
27
|
+
[option: string]: ArgSignature;
|
|
28
|
+
};
|
|
29
|
+
constructor(signature: string, helperDefinitions: {
|
|
30
|
+
[key: string]: string;
|
|
31
|
+
}, ...args: any[]);
|
|
32
|
+
private parseSignature;
|
|
33
|
+
private parseParamSignature;
|
|
34
|
+
validate(): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CommandParser = void 0;
|
|
7
|
+
const minimist_1 = __importDefault(require("minimist"));
|
|
8
|
+
const MissingRequiredArgumentValue_1 = require("./errors/MissingRequiredArgumentValue");
|
|
9
|
+
class CommandParser {
|
|
10
|
+
signature;
|
|
11
|
+
helperDefinitions;
|
|
12
|
+
command;
|
|
13
|
+
arguments = {};
|
|
14
|
+
options = {};
|
|
15
|
+
argumentsSignature = {};
|
|
16
|
+
optionsSignature = {};
|
|
17
|
+
option(name) {
|
|
18
|
+
if (!this.optionsSignature[name]) {
|
|
19
|
+
throw new Error(`Option ${name} not found`);
|
|
20
|
+
}
|
|
21
|
+
const signature = this.optionsSignature[name];
|
|
22
|
+
if (signature.type === 'boolean') {
|
|
23
|
+
if (this.options[name] === 'true' || this.options[name] === '1') {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
else if (this.options[name] === 'false' || this.options[name] === '0') {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return Boolean(this.options[name]);
|
|
30
|
+
}
|
|
31
|
+
if (signature.type === 'array') {
|
|
32
|
+
if (!this.options[name]) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return Array.isArray(this.options[name]) ? this.options[name] : [this.options[name]];
|
|
36
|
+
}
|
|
37
|
+
return this.options[name];
|
|
38
|
+
}
|
|
39
|
+
argument(name) {
|
|
40
|
+
return this.arguments[name];
|
|
41
|
+
}
|
|
42
|
+
argumentsSignatures() {
|
|
43
|
+
return this.argumentsSignature;
|
|
44
|
+
}
|
|
45
|
+
optionsSignatures() {
|
|
46
|
+
return this.optionsSignature;
|
|
47
|
+
}
|
|
48
|
+
constructor(signature, helperDefinitions, ...args) {
|
|
49
|
+
this.signature = signature;
|
|
50
|
+
this.helperDefinitions = helperDefinitions;
|
|
51
|
+
const [command, ...params] = signature.split(/\{(.*?)\}/g).map(param => param.trim()).filter(Boolean);
|
|
52
|
+
const { _: paramValues, ...optionValues } = (0, minimist_1.default)(args);
|
|
53
|
+
this.command = command;
|
|
54
|
+
this.parseSignature(params, optionValues, paramValues);
|
|
55
|
+
}
|
|
56
|
+
parseSignature(params, optionValues, paramValues) {
|
|
57
|
+
for (const paramSignature of params) {
|
|
58
|
+
const param = this.parseParamSignature(paramSignature);
|
|
59
|
+
if (param.isOption) {
|
|
60
|
+
const optionValue = optionValues[param.name];
|
|
61
|
+
this.options[param.name] = optionValue ?? param.defaultValue ?? null;
|
|
62
|
+
this.optionsSignature[param.name] = param;
|
|
63
|
+
for (const alias of param.alias ?? []) {
|
|
64
|
+
if (optionValues[alias]) {
|
|
65
|
+
this.options[param.name] = optionValues[alias];
|
|
66
|
+
this.optionsSignature[param.name] = param;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (param.variadic) {
|
|
72
|
+
const paramValue = paramValues.splice(0, paramValues.length);
|
|
73
|
+
this.arguments[param.name] = paramValue ?? [];
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const paramValue = paramValues.shift();
|
|
77
|
+
this.arguments[param.name] = paramValue ?? param.defaultValue ?? null;
|
|
78
|
+
}
|
|
79
|
+
this.argumentsSignature[param.name] = param;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
parseParamSignature(argument) {
|
|
84
|
+
let cleanedArgs = argument;
|
|
85
|
+
let isOptional = false;
|
|
86
|
+
let isVariadic = false;
|
|
87
|
+
if (cleanedArgs.endsWith('?')) {
|
|
88
|
+
cleanedArgs = cleanedArgs.slice(0, -1);
|
|
89
|
+
isOptional = true;
|
|
90
|
+
}
|
|
91
|
+
if (cleanedArgs.endsWith('*')) {
|
|
92
|
+
cleanedArgs = cleanedArgs.slice(0, -1);
|
|
93
|
+
isVariadic = true;
|
|
94
|
+
}
|
|
95
|
+
const arg = {
|
|
96
|
+
name: cleanedArgs,
|
|
97
|
+
optional: isOptional,
|
|
98
|
+
type: isVariadic ? 'array' : 'string',
|
|
99
|
+
help: undefined,
|
|
100
|
+
defaultValue: isVariadic ? [] : null,
|
|
101
|
+
variadic: isVariadic,
|
|
102
|
+
isOption: false
|
|
103
|
+
};
|
|
104
|
+
if (arg.name.includes(':')) {
|
|
105
|
+
const [name, help] = arg.name.split(':');
|
|
106
|
+
arg.name = name.trim();
|
|
107
|
+
arg.help = help.trim();
|
|
108
|
+
}
|
|
109
|
+
if (arg.name.includes('=')) {
|
|
110
|
+
const [name, defaultValue] = arg.name.split('=');
|
|
111
|
+
arg.name = name.trim();
|
|
112
|
+
arg.defaultValue = defaultValue.trim();
|
|
113
|
+
arg.optional = true;
|
|
114
|
+
if (!arg.defaultValue.length) {
|
|
115
|
+
arg.defaultValue = null;
|
|
116
|
+
}
|
|
117
|
+
else if (arg.defaultValue === 'true') {
|
|
118
|
+
arg.defaultValue = true;
|
|
119
|
+
arg.type = 'boolean';
|
|
120
|
+
}
|
|
121
|
+
else if (arg.defaultValue === 'false') {
|
|
122
|
+
arg.defaultValue = false;
|
|
123
|
+
arg.type = 'boolean';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
if (arg.name.startsWith('--')) {
|
|
128
|
+
arg.optional = true;
|
|
129
|
+
arg.defaultValue = false;
|
|
130
|
+
arg.type = 'boolean';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (arg.name.includes('|')) {
|
|
134
|
+
const [name, ...alias] = arg.name.split('|');
|
|
135
|
+
arg.name = name.trim();
|
|
136
|
+
arg.alias = alias.map(a => a.trim());
|
|
137
|
+
}
|
|
138
|
+
if (arg.name.startsWith('--')) {
|
|
139
|
+
arg.isOption = true;
|
|
140
|
+
arg.name = arg.name.slice(2);
|
|
141
|
+
}
|
|
142
|
+
if (arg.defaultValue === '*') {
|
|
143
|
+
arg.defaultValue = [];
|
|
144
|
+
arg.type = 'array';
|
|
145
|
+
}
|
|
146
|
+
arg.help = arg.help ?? this.helperDefinitions[arg.name] ?? this.helperDefinitions[`--${arg.name}`];
|
|
147
|
+
return arg;
|
|
148
|
+
}
|
|
149
|
+
validate() {
|
|
150
|
+
// validate arguments
|
|
151
|
+
for (const [argument, value] of Object.entries(this.arguments)) {
|
|
152
|
+
const argSignature = this.argumentsSignature[argument];
|
|
153
|
+
if (!value && !argSignature.optional) {
|
|
154
|
+
throw new MissingRequiredArgumentValue_1.MissingRequiredArgumentValue(argSignature);
|
|
155
|
+
}
|
|
156
|
+
if (!value?.length && argSignature.variadic && !argSignature.optional) {
|
|
157
|
+
throw new MissingRequiredArgumentValue_1.MissingRequiredArgumentValue(argSignature);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.CommandParser = CommandParser;
|
package/dist/Parser.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export type ArgSignature = {
|
|
2
2
|
name: string;
|
|
3
3
|
type: string;
|
|
4
|
-
optional
|
|
4
|
+
optional?: boolean;
|
|
5
|
+
variadic?: boolean;
|
|
5
6
|
alias?: string[];
|
|
6
7
|
help?: string;
|
|
7
|
-
defaultValue?: string | boolean | Array<
|
|
8
|
+
defaultValue?: string | boolean | Array<string> | null;
|
|
8
9
|
isOption?: boolean;
|
|
9
10
|
};
|
|
10
11
|
export declare class Parser {
|
package/dist/Parser.js
CHANGED
|
@@ -29,6 +29,9 @@ class Parser {
|
|
|
29
29
|
return Boolean(this.options[name]);
|
|
30
30
|
}
|
|
31
31
|
if (signature.type === 'array') {
|
|
32
|
+
if (!this.options[name]) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
32
35
|
return Array.isArray(this.options[name]) ? this.options[name] : [this.options[name]];
|
|
33
36
|
}
|
|
34
37
|
return this.options[name];
|
|
@@ -65,8 +68,14 @@ class Parser {
|
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
else {
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
if (param.variadic) {
|
|
72
|
+
const paramValue = paramValues.splice(0, paramValues.length);
|
|
73
|
+
this.arguments[param.name] = paramValue ?? [];
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const paramValue = paramValues.shift();
|
|
77
|
+
this.arguments[param.name] = paramValue ?? param.defaultValue ?? null;
|
|
78
|
+
}
|
|
70
79
|
this.argumentsSignature[param.name] = param;
|
|
71
80
|
}
|
|
72
81
|
}
|
|
@@ -74,16 +83,22 @@ class Parser {
|
|
|
74
83
|
parseParamSignature(argument) {
|
|
75
84
|
let cleanedArgs = argument;
|
|
76
85
|
let isOptional = false;
|
|
77
|
-
|
|
86
|
+
let isVariadic = false;
|
|
87
|
+
if (cleanedArgs.endsWith('?')) {
|
|
78
88
|
cleanedArgs = cleanedArgs.slice(0, -1);
|
|
79
89
|
isOptional = true;
|
|
80
90
|
}
|
|
91
|
+
if (cleanedArgs.endsWith('*')) {
|
|
92
|
+
cleanedArgs = cleanedArgs.slice(0, -1);
|
|
93
|
+
isVariadic = true;
|
|
94
|
+
}
|
|
81
95
|
const arg = {
|
|
82
96
|
name: cleanedArgs,
|
|
83
97
|
optional: isOptional,
|
|
84
|
-
type: 'string',
|
|
98
|
+
type: isVariadic ? 'array' : 'string',
|
|
85
99
|
help: undefined,
|
|
86
|
-
defaultValue: null,
|
|
100
|
+
defaultValue: isVariadic ? [] : null,
|
|
101
|
+
variadic: isVariadic,
|
|
87
102
|
isOption: false
|
|
88
103
|
};
|
|
89
104
|
if (arg.name.includes(':')) {
|
|
@@ -110,6 +125,7 @@ class Parser {
|
|
|
110
125
|
}
|
|
111
126
|
else {
|
|
112
127
|
if (arg.name.startsWith('--')) {
|
|
128
|
+
arg.optional = true;
|
|
113
129
|
arg.defaultValue = false;
|
|
114
130
|
arg.type = 'boolean';
|
|
115
131
|
}
|
|
@@ -127,9 +143,7 @@ class Parser {
|
|
|
127
143
|
arg.defaultValue = [];
|
|
128
144
|
arg.type = 'array';
|
|
129
145
|
}
|
|
130
|
-
|
|
131
|
-
arg.help = this.helperDefinitions[arg.name];
|
|
132
|
-
}
|
|
146
|
+
arg.help = arg.help ?? this.helperDefinitions[arg.name] ?? this.helperDefinitions[`--${arg.name}`];
|
|
133
147
|
return arg;
|
|
134
148
|
}
|
|
135
149
|
validate() {
|
|
@@ -139,6 +153,9 @@ class Parser {
|
|
|
139
153
|
if (!value && !argSignature.optional) {
|
|
140
154
|
throw new MissingRequiredArgumentValue_1.MissingRequiredArgumentValue(argSignature);
|
|
141
155
|
}
|
|
156
|
+
if (!value?.length && argSignature.variadic && !argSignature.optional) {
|
|
157
|
+
throw new MissingRequiredArgumentValue_1.MissingRequiredArgumentValue(argSignature);
|
|
158
|
+
}
|
|
142
159
|
}
|
|
143
160
|
}
|
|
144
161
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BobError } from "./BobError";
|
|
2
|
-
import { ArgSignature } from "../
|
|
2
|
+
import { ArgSignature } from "../CommandParser";
|
|
3
3
|
export declare class MissingRequiredArgumentValue extends BobError {
|
|
4
4
|
readonly paramSignature: ArgSignature;
|
|
5
5
|
constructor(paramSignature: ArgSignature);
|