@wooksjs/event-cli 0.4.8 → 0.4.10
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.cjs +408 -403
- package/dist/index.mjs +408 -403
- package/package.json +7 -4
package/dist/index.mjs
CHANGED
|
@@ -3,19 +3,19 @@ import { WooksAdapterBase } from 'wooks';
|
|
|
3
3
|
import { CliHelpRenderer } from '@prostojs/cli-help';
|
|
4
4
|
import minimist from 'minimist';
|
|
5
5
|
|
|
6
|
-
function createCliContext(data, options) {
|
|
7
|
-
return createEventContext({
|
|
8
|
-
event: Object.assign(Object.assign({}, data), { type: 'CLI' }),
|
|
9
|
-
options,
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Wrapper on top of useEventContext that provides
|
|
14
|
-
* proper context types for CLI event
|
|
15
|
-
* @returns set of hooks { getCtx, restoreCtx, clearCtx, hookStore, getStore, setStore }
|
|
16
|
-
*/
|
|
17
|
-
function useCliContext() {
|
|
18
|
-
return useEventContext('CLI');
|
|
6
|
+
function createCliContext(data, options) {
|
|
7
|
+
return createEventContext({
|
|
8
|
+
event: Object.assign(Object.assign({}, data), { type: 'CLI' }),
|
|
9
|
+
options,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Wrapper on top of useEventContext that provides
|
|
14
|
+
* proper context types for CLI event
|
|
15
|
+
* @returns set of hooks { getCtx, restoreCtx, clearCtx, hookStore, getStore, setStore }
|
|
16
|
+
*/
|
|
17
|
+
function useCliContext() {
|
|
18
|
+
return useEventContext('CLI');
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/******************************************************************************
|
|
@@ -32,7 +32,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
32
32
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
33
33
|
PERFORMANCE OF THIS SOFTWARE.
|
|
34
34
|
***************************************************************************** */
|
|
35
|
-
/* global Reflect, Promise */
|
|
35
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
@@ -43,400 +43,405 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
43
43
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
44
44
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
45
45
|
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const cliShortcuts = {
|
|
49
|
-
cli: 'CLI',
|
|
50
|
-
};
|
|
51
|
-
class WooksCli extends WooksAdapterBase {
|
|
52
|
-
constructor(opts, wooks) {
|
|
53
|
-
super(wooks, opts === null || opts === void 0 ? void 0 : opts.logger, opts === null || opts === void 0 ? void 0 : opts.router);
|
|
54
|
-
this.opts = opts;
|
|
55
|
-
this.alreadyComputedAliases = false;
|
|
56
|
-
this.logger = (opts === null || opts === void 0 ? void 0 : opts.logger) || this.getLogger('wooks-cli');
|
|
57
|
-
this.cliHelp =
|
|
58
|
-
(opts === null || opts === void 0 ? void 0 : opts.cliHelp) instanceof CliHelpRenderer
|
|
59
|
-
? opts.cliHelp
|
|
60
|
-
: new CliHelpRenderer(opts === null || opts === void 0 ? void 0 : opts.cliHelp);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* ### Register CLI Command
|
|
64
|
-
* Command path segments may be separated by / or space.
|
|
65
|
-
*
|
|
66
|
-
* For example the folowing path are interpreted the same:
|
|
67
|
-
* - "command test use:dev :name"
|
|
68
|
-
* - "command/test/use:dev/:name"
|
|
69
|
-
*
|
|
70
|
-
* Where name will become an argument
|
|
71
|
-
*
|
|
72
|
-
* ```js
|
|
73
|
-
* // example without options
|
|
74
|
-
* app.cli('command/:arg', () => 'arg = ' + useRouteParams().params.arg )
|
|
75
|
-
*
|
|
76
|
-
* // example with options
|
|
77
|
-
* app.cli('command/:arg', {
|
|
78
|
-
* description: 'Description of the command',
|
|
79
|
-
* options: [{ keys: ['project', 'p'], description: 'Description of the option', value: 'myProject' }],
|
|
80
|
-
* args: { arg: 'Description of the arg' },
|
|
81
|
-
* aliases: ['cmd'], // alias "cmd/:arg" will be registered
|
|
82
|
-
* examples: [{
|
|
83
|
-
* description: 'Example of usage with someProject',
|
|
84
|
-
* cmd: 'argValue -p=someProject',
|
|
85
|
-
* // will result in help display:
|
|
86
|
-
* // "# Example of usage with someProject\n" +
|
|
87
|
-
* // "$ myCli command argValue -p=someProject\n"
|
|
88
|
-
* }],
|
|
89
|
-
* handler: () => 'arg = ' + useRouteParams().params.arg
|
|
90
|
-
* })
|
|
91
|
-
* ```
|
|
92
|
-
*
|
|
93
|
-
* @param path command path
|
|
94
|
-
* @param _options handler or options
|
|
95
|
-
*
|
|
96
|
-
* @returns
|
|
97
|
-
*/
|
|
98
|
-
cli(path, _options) {
|
|
99
|
-
var _a;
|
|
100
|
-
const options = typeof _options === 'function' ? { handler: _options } : _options;
|
|
101
|
-
const handler = typeof _options === 'function' ? _options : _options.handler;
|
|
102
|
-
const makePath = (s) => '/' + s.replace(/\s+/g, '/');
|
|
103
|
-
// register handler
|
|
104
|
-
const targetPath = makePath(path);
|
|
105
|
-
const routed = this.on('CLI', targetPath, handler);
|
|
106
|
-
if (options.onRegister) {
|
|
107
|
-
options.onRegister(targetPath, 0, routed);
|
|
108
|
-
}
|
|
109
|
-
// register direct aliases
|
|
110
|
-
for (const alias of options.aliases || []) {
|
|
111
|
-
const vars = routed.getArgs().map((k) => ':' + k).join('/');
|
|
112
|
-
const targetPath = makePath(alias) + (vars ? '/' + vars : '');
|
|
113
|
-
this.on('CLI', targetPath, handler);
|
|
114
|
-
if (options.onRegister) {
|
|
115
|
-
options.onRegister(targetPath, 1, routed);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// register helpCli entry
|
|
119
|
-
const command = routed.getStaticPart().replace(/\//g, ' ').trim();
|
|
120
|
-
const args = Object.assign({}, (options.args || {}));
|
|
121
|
-
for (const arg of routed.getArgs()) {
|
|
122
|
-
if (!args[arg]) {
|
|
123
|
-
args[arg] = '';
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
this.cliHelp.addEntry({
|
|
127
|
-
command,
|
|
128
|
-
aliases: (_a = options.aliases) === null || _a === void 0 ? void 0 : _a.map(alias => alias.replace(/\\:/g, ':')),
|
|
129
|
-
args,
|
|
130
|
-
description: options.description,
|
|
131
|
-
examples: options.examples,
|
|
132
|
-
options: options.options,
|
|
133
|
-
custom: { handler: options.handler, cb: options.onRegister },
|
|
134
|
-
});
|
|
135
|
-
return routed;
|
|
136
|
-
}
|
|
137
|
-
computeAliases() {
|
|
138
|
-
if (!this.alreadyComputedAliases) {
|
|
139
|
-
this.alreadyComputedAliases = true;
|
|
140
|
-
const aliases = this.cliHelp.getComputedAliases();
|
|
141
|
-
for (const [alias, entry] of Object.entries(aliases)) {
|
|
142
|
-
if (entry.custom) {
|
|
143
|
-
const vars = Object.keys(entry.args || {})
|
|
144
|
-
.map((k) => ':' + k)
|
|
145
|
-
.join('/');
|
|
146
|
-
const path = '/' +
|
|
147
|
-
alias.replace(/\s+/g, '/').replace(/:/g, '\\:') +
|
|
148
|
-
(vars ? '/' + vars : '');
|
|
149
|
-
this.on('CLI', path, entry.custom.handler);
|
|
150
|
-
if (entry.custom.cb) {
|
|
151
|
-
entry.custom.cb(path, 3);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* ## run
|
|
159
|
-
* ### Start command processing
|
|
160
|
-
* Triggers command processing
|
|
161
|
-
*
|
|
162
|
-
* By default takes `process.argv.slice(2)` as a command
|
|
163
|
-
*
|
|
164
|
-
* It's possible to replace the command by passing an argument
|
|
165
|
-
*
|
|
166
|
-
* @param _argv optionally overwrite `process.argv.slice(2)` with your `argv` array
|
|
167
|
-
*/
|
|
168
|
-
run(_argv, _opts) {
|
|
169
|
-
var _a, _b;
|
|
170
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
-
const argv = _argv || process.argv.slice(2);
|
|
172
|
-
const parsedFlags = minimist(argv, _opts);
|
|
173
|
-
const pathParams = parsedFlags._;
|
|
174
|
-
const path = '/' +
|
|
175
|
-
pathParams.map((v) => encodeURI(v).replace(/\//g, '%2F')).join('/');
|
|
176
|
-
const { restoreCtx, clearCtx, store } = createCliContext({ opts: _opts, argv, pathParams, cliHelp: this.cliHelp, command: path.replace(/\//g, ' ').trim() }, this.mergeEventOptions((_a = this.opts) === null || _a === void 0 ? void 0 : _a.eventOptions));
|
|
177
|
-
store('flags').value = parsedFlags;
|
|
178
|
-
this.computeAliases();
|
|
179
|
-
const { handlers: foundHandlers, firstStatic } = this.wooks.lookup('CLI', path);
|
|
180
|
-
if (typeof firstStatic === 'string') {
|
|
181
|
-
// overwriting command with firstStatic to properly search for help
|
|
182
|
-
store('event').set('command', firstStatic.replace(/\//g, ' ').trim());
|
|
183
|
-
}
|
|
184
|
-
const handlers = foundHandlers ||
|
|
185
|
-
(((_b = this.opts) === null || _b === void 0 ? void 0 : _b.onNotFound) && [this.opts.onNotFound]) ||
|
|
186
|
-
null;
|
|
187
|
-
if (handlers) {
|
|
188
|
-
try {
|
|
189
|
-
for (const handler of handlers) {
|
|
190
|
-
restoreCtx();
|
|
191
|
-
const response = yield handler();
|
|
192
|
-
if (typeof response === 'string') {
|
|
193
|
-
console.log(response);
|
|
194
|
-
}
|
|
195
|
-
else if (Array.isArray(response)) {
|
|
196
|
-
response.forEach((r) => console.log(typeof r === 'string'
|
|
197
|
-
? r
|
|
198
|
-
: JSON.stringify(r, null, ' ')));
|
|
199
|
-
}
|
|
200
|
-
else if (response instanceof Error) {
|
|
201
|
-
this.onError(response);
|
|
202
|
-
}
|
|
203
|
-
else if (response) {
|
|
204
|
-
if (response) {
|
|
205
|
-
console.log(JSON.stringify(response, null, ' '));
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
catch (e) {
|
|
211
|
-
this.onError(e);
|
|
212
|
-
}
|
|
213
|
-
clearCtx();
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
this.onUnknownCommand(pathParams);
|
|
217
|
-
clearCtx();
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
onError(e) {
|
|
222
|
-
var _a;
|
|
223
|
-
if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.onError) {
|
|
224
|
-
this.opts.onError(e);
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
this.error(e.message);
|
|
228
|
-
process.exit(1);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Triggers `unknown command` processing and callbacks
|
|
233
|
-
* @param pathParams `string[]` containing command
|
|
234
|
-
*/
|
|
235
|
-
onUnknownCommand(pathParams) {
|
|
236
|
-
var _a;
|
|
237
|
-
const raiseError = () => {
|
|
238
|
-
this.error('[0m' + 'Unknown command: ' + pathParams.join(' '));
|
|
239
|
-
process.exit(1);
|
|
240
|
-
};
|
|
241
|
-
if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.onUnknownCommand) {
|
|
242
|
-
this.opts.onUnknownCommand(pathParams, raiseError);
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
raiseError();
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
error(e) {
|
|
249
|
-
if (typeof e === 'string') {
|
|
250
|
-
console.error('[31m' + 'ERROR: ' + '[0m' + e);
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
console.error('[31m' + 'ERROR: ' + '[0m' + e.message);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
46
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
47
|
+
|
|
48
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
49
|
+
var e = new Error(message);
|
|
50
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const cliShortcuts = {
|
|
54
|
+
cli: 'CLI',
|
|
55
|
+
};
|
|
56
|
+
class WooksCli extends WooksAdapterBase {
|
|
57
|
+
constructor(opts, wooks) {
|
|
58
|
+
super(wooks, opts === null || opts === void 0 ? void 0 : opts.logger, opts === null || opts === void 0 ? void 0 : opts.router);
|
|
59
|
+
this.opts = opts;
|
|
60
|
+
this.alreadyComputedAliases = false;
|
|
61
|
+
this.logger = (opts === null || opts === void 0 ? void 0 : opts.logger) || this.getLogger('wooks-cli');
|
|
62
|
+
this.cliHelp =
|
|
63
|
+
(opts === null || opts === void 0 ? void 0 : opts.cliHelp) instanceof CliHelpRenderer
|
|
64
|
+
? opts.cliHelp
|
|
65
|
+
: new CliHelpRenderer(opts === null || opts === void 0 ? void 0 : opts.cliHelp);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* ### Register CLI Command
|
|
69
|
+
* Command path segments may be separated by / or space.
|
|
70
|
+
*
|
|
71
|
+
* For example the folowing path are interpreted the same:
|
|
72
|
+
* - "command test use:dev :name"
|
|
73
|
+
* - "command/test/use:dev/:name"
|
|
74
|
+
*
|
|
75
|
+
* Where name will become an argument
|
|
76
|
+
*
|
|
77
|
+
* ```js
|
|
78
|
+
* // example without options
|
|
79
|
+
* app.cli('command/:arg', () => 'arg = ' + useRouteParams().params.arg )
|
|
80
|
+
*
|
|
81
|
+
* // example with options
|
|
82
|
+
* app.cli('command/:arg', {
|
|
83
|
+
* description: 'Description of the command',
|
|
84
|
+
* options: [{ keys: ['project', 'p'], description: 'Description of the option', value: 'myProject' }],
|
|
85
|
+
* args: { arg: 'Description of the arg' },
|
|
86
|
+
* aliases: ['cmd'], // alias "cmd/:arg" will be registered
|
|
87
|
+
* examples: [{
|
|
88
|
+
* description: 'Example of usage with someProject',
|
|
89
|
+
* cmd: 'argValue -p=someProject',
|
|
90
|
+
* // will result in help display:
|
|
91
|
+
* // "# Example of usage with someProject\n" +
|
|
92
|
+
* // "$ myCli command argValue -p=someProject\n"
|
|
93
|
+
* }],
|
|
94
|
+
* handler: () => 'arg = ' + useRouteParams().params.arg
|
|
95
|
+
* })
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @param path command path
|
|
99
|
+
* @param _options handler or options
|
|
100
|
+
*
|
|
101
|
+
* @returns
|
|
102
|
+
*/
|
|
103
|
+
cli(path, _options) {
|
|
104
|
+
var _a;
|
|
105
|
+
const options = typeof _options === 'function' ? { handler: _options } : _options;
|
|
106
|
+
const handler = typeof _options === 'function' ? _options : _options.handler;
|
|
107
|
+
const makePath = (s) => '/' + s.replace(/\s+/g, '/');
|
|
108
|
+
// register handler
|
|
109
|
+
const targetPath = makePath(path);
|
|
110
|
+
const routed = this.on('CLI', targetPath, handler);
|
|
111
|
+
if (options.onRegister) {
|
|
112
|
+
options.onRegister(targetPath, 0, routed);
|
|
113
|
+
}
|
|
114
|
+
// register direct aliases
|
|
115
|
+
for (const alias of options.aliases || []) {
|
|
116
|
+
const vars = routed.getArgs().map((k) => ':' + k).join('/');
|
|
117
|
+
const targetPath = makePath(alias) + (vars ? '/' + vars : '');
|
|
118
|
+
this.on('CLI', targetPath, handler);
|
|
119
|
+
if (options.onRegister) {
|
|
120
|
+
options.onRegister(targetPath, 1, routed);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// register helpCli entry
|
|
124
|
+
const command = routed.getStaticPart().replace(/\//g, ' ').trim();
|
|
125
|
+
const args = Object.assign({}, (options.args || {}));
|
|
126
|
+
for (const arg of routed.getArgs()) {
|
|
127
|
+
if (!args[arg]) {
|
|
128
|
+
args[arg] = '';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
this.cliHelp.addEntry({
|
|
132
|
+
command,
|
|
133
|
+
aliases: (_a = options.aliases) === null || _a === void 0 ? void 0 : _a.map(alias => alias.replace(/\\:/g, ':')), // unescape ":" character
|
|
134
|
+
args,
|
|
135
|
+
description: options.description,
|
|
136
|
+
examples: options.examples,
|
|
137
|
+
options: options.options,
|
|
138
|
+
custom: { handler: options.handler, cb: options.onRegister },
|
|
139
|
+
});
|
|
140
|
+
return routed;
|
|
141
|
+
}
|
|
142
|
+
computeAliases() {
|
|
143
|
+
if (!this.alreadyComputedAliases) {
|
|
144
|
+
this.alreadyComputedAliases = true;
|
|
145
|
+
const aliases = this.cliHelp.getComputedAliases();
|
|
146
|
+
for (const [alias, entry] of Object.entries(aliases)) {
|
|
147
|
+
if (entry.custom) {
|
|
148
|
+
const vars = Object.keys(entry.args || {})
|
|
149
|
+
.map((k) => ':' + k)
|
|
150
|
+
.join('/');
|
|
151
|
+
const path = '/' +
|
|
152
|
+
alias.replace(/\s+/g, '/').replace(/:/g, '\\:') +
|
|
153
|
+
(vars ? '/' + vars : '');
|
|
154
|
+
this.on('CLI', path, entry.custom.handler);
|
|
155
|
+
if (entry.custom.cb) {
|
|
156
|
+
entry.custom.cb(path, 3);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* ## run
|
|
164
|
+
* ### Start command processing
|
|
165
|
+
* Triggers command processing
|
|
166
|
+
*
|
|
167
|
+
* By default takes `process.argv.slice(2)` as a command
|
|
168
|
+
*
|
|
169
|
+
* It's possible to replace the command by passing an argument
|
|
170
|
+
*
|
|
171
|
+
* @param _argv optionally overwrite `process.argv.slice(2)` with your `argv` array
|
|
172
|
+
*/
|
|
173
|
+
run(_argv, _opts) {
|
|
174
|
+
var _a, _b;
|
|
175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
const argv = _argv || process.argv.slice(2);
|
|
177
|
+
const parsedFlags = minimist(argv, _opts);
|
|
178
|
+
const pathParams = parsedFlags._;
|
|
179
|
+
const path = '/' +
|
|
180
|
+
pathParams.map((v) => encodeURI(v).replace(/\//g, '%2F')).join('/');
|
|
181
|
+
const { restoreCtx, clearCtx, store } = createCliContext({ opts: _opts, argv, pathParams, cliHelp: this.cliHelp, command: path.replace(/\//g, ' ').trim() }, this.mergeEventOptions((_a = this.opts) === null || _a === void 0 ? void 0 : _a.eventOptions));
|
|
182
|
+
store('flags').value = parsedFlags;
|
|
183
|
+
this.computeAliases();
|
|
184
|
+
const { handlers: foundHandlers, firstStatic } = this.wooks.lookup('CLI', path);
|
|
185
|
+
if (typeof firstStatic === 'string') {
|
|
186
|
+
// overwriting command with firstStatic to properly search for help
|
|
187
|
+
store('event').set('command', firstStatic.replace(/\//g, ' ').trim());
|
|
188
|
+
}
|
|
189
|
+
const handlers = foundHandlers ||
|
|
190
|
+
(((_b = this.opts) === null || _b === void 0 ? void 0 : _b.onNotFound) && [this.opts.onNotFound]) ||
|
|
191
|
+
null;
|
|
192
|
+
if (handlers) {
|
|
193
|
+
try {
|
|
194
|
+
for (const handler of handlers) {
|
|
195
|
+
restoreCtx();
|
|
196
|
+
const response = yield handler();
|
|
197
|
+
if (typeof response === 'string') {
|
|
198
|
+
console.log(response);
|
|
199
|
+
}
|
|
200
|
+
else if (Array.isArray(response)) {
|
|
201
|
+
response.forEach((r) => console.log(typeof r === 'string'
|
|
202
|
+
? r
|
|
203
|
+
: JSON.stringify(r, null, ' ')));
|
|
204
|
+
}
|
|
205
|
+
else if (response instanceof Error) {
|
|
206
|
+
this.onError(response);
|
|
207
|
+
}
|
|
208
|
+
else if (response) {
|
|
209
|
+
if (response) {
|
|
210
|
+
console.log(JSON.stringify(response, null, ' '));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
this.onError(e);
|
|
217
|
+
}
|
|
218
|
+
clearCtx();
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
this.onUnknownCommand(pathParams);
|
|
222
|
+
clearCtx();
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
onError(e) {
|
|
227
|
+
var _a;
|
|
228
|
+
if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.onError) {
|
|
229
|
+
this.opts.onError(e);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
this.error(e.message);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Triggers `unknown command` processing and callbacks
|
|
238
|
+
* @param pathParams `string[]` containing command
|
|
239
|
+
*/
|
|
240
|
+
onUnknownCommand(pathParams) {
|
|
241
|
+
var _a;
|
|
242
|
+
const raiseError = () => {
|
|
243
|
+
this.error('[0m' + 'Unknown command: ' + pathParams.join(' '));
|
|
244
|
+
process.exit(1);
|
|
245
|
+
};
|
|
246
|
+
if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.onUnknownCommand) {
|
|
247
|
+
this.opts.onUnknownCommand(pathParams, raiseError);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
raiseError();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
error(e) {
|
|
254
|
+
if (typeof e === 'string') {
|
|
255
|
+
console.error('[31m' + 'ERROR: ' + '[0m' + e);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
console.error('[31m' + 'ERROR: ' + '[0m' + e.message);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Factory for WooksCli App
|
|
264
|
+
* @param opts TWooksCliOptions
|
|
265
|
+
* @param wooks Wooks | WooksAdapterBase
|
|
266
|
+
* @returns WooksCli
|
|
267
|
+
*/
|
|
268
|
+
function createCliApp(opts, wooks) {
|
|
269
|
+
return new WooksCli(opts, wooks);
|
|
265
270
|
}
|
|
266
271
|
|
|
267
|
-
/**
|
|
268
|
-
* ## useCliHelp
|
|
269
|
-
* ### Composable
|
|
270
|
-
* ```js
|
|
271
|
-
* // example of printing cli instructions
|
|
272
|
-
* const { print } = useCliHelp()
|
|
273
|
-
* // print with colors
|
|
274
|
-
* print(true)
|
|
275
|
-
* // print with no colors
|
|
276
|
-
* // print(false)
|
|
277
|
-
* ```
|
|
278
|
-
* @returns
|
|
279
|
-
*/
|
|
280
|
-
function useCliHelp() {
|
|
281
|
-
const event = useCliContext().store('event');
|
|
282
|
-
const getCliHelp = () => event.get('cliHelp');
|
|
283
|
-
const getEntry = () => { var _a; return (_a = getCliHelp().match(event.get('command'))) === null || _a === void 0 ? void 0 : _a.main; };
|
|
284
|
-
return {
|
|
285
|
-
getCliHelp,
|
|
286
|
-
getEntry,
|
|
287
|
-
render: (width, withColors) => getCliHelp().render(event.get('command'), width, withColors),
|
|
288
|
-
print: (withColors) => getCliHelp().print(event.get('command'), withColors),
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* ## useAutoHelp
|
|
293
|
-
* ### Composable
|
|
294
|
-
*
|
|
295
|
-
* Prints help if `--help` option provided.
|
|
296
|
-
*
|
|
297
|
-
* ```js
|
|
298
|
-
* // example of use: print help and exit
|
|
299
|
-
* app.cli('test', () => {
|
|
300
|
-
* useAutoHelp() && process.exit(0)
|
|
301
|
-
* return 'hit test command'
|
|
302
|
-
* })
|
|
303
|
-
*
|
|
304
|
-
* // add option -h to print help, no colors
|
|
305
|
-
* app.cli('test/nocolors', () => {
|
|
306
|
-
* useAutoHelp(['help', 'h'], false) && process.exit(0)
|
|
307
|
-
* return 'hit test nocolors command'
|
|
308
|
-
* })
|
|
309
|
-
* ```
|
|
310
|
-
* @param keys default `['help']` - list of options to trigger help render
|
|
311
|
-
* @param colors default `true`, prints with colors when true
|
|
312
|
-
* @returns true when --help was provided. Otherwise returns false
|
|
313
|
-
*/
|
|
314
|
-
function useAutoHelp(keys = ['help'], colors = true) {
|
|
315
|
-
for (const option of keys) {
|
|
316
|
-
if (useCliOption(option) === true) {
|
|
317
|
-
// try {
|
|
318
|
-
useCliHelp().print(colors);
|
|
319
|
-
return true;
|
|
320
|
-
// } catch (e) {
|
|
321
|
-
// throw new
|
|
322
|
-
// }
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* ##useCommandLookupHelp
|
|
328
|
-
* ### Composable
|
|
329
|
-
*
|
|
330
|
-
* Tries to find valid command based on provided command.
|
|
331
|
-
*
|
|
332
|
-
* If manages to find a valid command, throws an error
|
|
333
|
-
* suggesting a list of valid commands
|
|
334
|
-
*
|
|
335
|
-
* Best to use in `onUnknownCommand` callback:
|
|
336
|
-
*
|
|
337
|
-
* ```js
|
|
338
|
-
* const app = createCliApp({
|
|
339
|
-
* onUnknownCommand: (path, raiseError) => {
|
|
340
|
-
* // will throw an error suggesting a list
|
|
341
|
-
* // of valid commands if could find some
|
|
342
|
-
* useCommandLookupHelp()
|
|
343
|
-
* // fallback to a regular error handler
|
|
344
|
-
* raiseError()
|
|
345
|
-
* },
|
|
346
|
-
* })
|
|
347
|
-
* ```
|
|
348
|
-
*
|
|
349
|
-
* @param lookupDepth depth of search in backwards
|
|
350
|
-
* @example
|
|
351
|
-
*
|
|
352
|
-
* For provided command `run test:drive dir`
|
|
353
|
-
* - lookup1: `run test:drive dir` (deep = 0)
|
|
354
|
-
* - lookup2: `run test:drive` (deep = 1)
|
|
355
|
-
* - lookup3: `run test` (deep = 2)
|
|
356
|
-
* - lookup4: `run` (deep = 3)
|
|
357
|
-
* ...
|
|
358
|
-
*/
|
|
359
|
-
function useCommandLookupHelp(lookupDepth = 3) {
|
|
360
|
-
const parts = useCliContext()
|
|
361
|
-
.store('event')
|
|
362
|
-
.get('pathParams')
|
|
363
|
-
.map((p) => (p + ' ').split(':').map((s, i) => (i ? ':' + s : s)))
|
|
364
|
-
.flat();
|
|
365
|
-
const cliHelp = useCliHelp().getCliHelp();
|
|
366
|
-
const cmd = cliHelp.getCliName();
|
|
367
|
-
let data;
|
|
368
|
-
for (let i = 0; i < Math.min(parts.length, lookupDepth + 1); i++) {
|
|
369
|
-
const pathParams = parts
|
|
370
|
-
.slice(0, i ? -i : parts.length)
|
|
371
|
-
.join('')
|
|
372
|
-
.trim();
|
|
373
|
-
try {
|
|
374
|
-
data = cliHelp.match(pathParams);
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
catch (e) {
|
|
378
|
-
const variants = cliHelp.lookup(pathParams);
|
|
379
|
-
if (variants.length) {
|
|
380
|
-
throw new Error(`Wrong command, did you mean:\n${variants
|
|
381
|
-
.slice(0, 7)
|
|
382
|
-
.map((c) => ` $ ${cmd} ${c.main.command}`)
|
|
383
|
-
.join('\n')}`);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
if (data) {
|
|
388
|
-
const { main, children } = data;
|
|
389
|
-
if (main.args && Object.keys(main.args).length) {
|
|
390
|
-
throw new Error(`Arguments expected: ${Object.keys(main.args)
|
|
391
|
-
.map((l) => `<${l}>`)
|
|
392
|
-
.join(', ')}`);
|
|
393
|
-
}
|
|
394
|
-
else if (children && children.length) {
|
|
395
|
-
throw new Error(`Wrong command, did you mean:\n${children
|
|
396
|
-
.slice(0, 7)
|
|
397
|
-
.map((c) => ` $ ${cmd} ${c.command}`)
|
|
398
|
-
.join('\n')}`);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
272
|
+
/**
|
|
273
|
+
* ## useCliHelp
|
|
274
|
+
* ### Composable
|
|
275
|
+
* ```js
|
|
276
|
+
* // example of printing cli instructions
|
|
277
|
+
* const { print } = useCliHelp()
|
|
278
|
+
* // print with colors
|
|
279
|
+
* print(true)
|
|
280
|
+
* // print with no colors
|
|
281
|
+
* // print(false)
|
|
282
|
+
* ```
|
|
283
|
+
* @returns
|
|
284
|
+
*/
|
|
285
|
+
function useCliHelp() {
|
|
286
|
+
const event = useCliContext().store('event');
|
|
287
|
+
const getCliHelp = () => event.get('cliHelp');
|
|
288
|
+
const getEntry = () => { var _a; return (_a = getCliHelp().match(event.get('command'))) === null || _a === void 0 ? void 0 : _a.main; };
|
|
289
|
+
return {
|
|
290
|
+
getCliHelp,
|
|
291
|
+
getEntry,
|
|
292
|
+
render: (width, withColors) => getCliHelp().render(event.get('command'), width, withColors),
|
|
293
|
+
print: (withColors) => getCliHelp().print(event.get('command'), withColors),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* ## useAutoHelp
|
|
298
|
+
* ### Composable
|
|
299
|
+
*
|
|
300
|
+
* Prints help if `--help` option provided.
|
|
301
|
+
*
|
|
302
|
+
* ```js
|
|
303
|
+
* // example of use: print help and exit
|
|
304
|
+
* app.cli('test', () => {
|
|
305
|
+
* useAutoHelp() && process.exit(0)
|
|
306
|
+
* return 'hit test command'
|
|
307
|
+
* })
|
|
308
|
+
*
|
|
309
|
+
* // add option -h to print help, no colors
|
|
310
|
+
* app.cli('test/nocolors', () => {
|
|
311
|
+
* useAutoHelp(['help', 'h'], false) && process.exit(0)
|
|
312
|
+
* return 'hit test nocolors command'
|
|
313
|
+
* })
|
|
314
|
+
* ```
|
|
315
|
+
* @param keys default `['help']` - list of options to trigger help render
|
|
316
|
+
* @param colors default `true`, prints with colors when true
|
|
317
|
+
* @returns true when --help was provided. Otherwise returns false
|
|
318
|
+
*/
|
|
319
|
+
function useAutoHelp(keys = ['help'], colors = true) {
|
|
320
|
+
for (const option of keys) {
|
|
321
|
+
if (useCliOption(option) === true) {
|
|
322
|
+
// try {
|
|
323
|
+
useCliHelp().print(colors);
|
|
324
|
+
return true;
|
|
325
|
+
// } catch (e) {
|
|
326
|
+
// throw new
|
|
327
|
+
// }
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* ##useCommandLookupHelp
|
|
333
|
+
* ### Composable
|
|
334
|
+
*
|
|
335
|
+
* Tries to find valid command based on provided command.
|
|
336
|
+
*
|
|
337
|
+
* If manages to find a valid command, throws an error
|
|
338
|
+
* suggesting a list of valid commands
|
|
339
|
+
*
|
|
340
|
+
* Best to use in `onUnknownCommand` callback:
|
|
341
|
+
*
|
|
342
|
+
* ```js
|
|
343
|
+
* const app = createCliApp({
|
|
344
|
+
* onUnknownCommand: (path, raiseError) => {
|
|
345
|
+
* // will throw an error suggesting a list
|
|
346
|
+
* // of valid commands if could find some
|
|
347
|
+
* useCommandLookupHelp()
|
|
348
|
+
* // fallback to a regular error handler
|
|
349
|
+
* raiseError()
|
|
350
|
+
* },
|
|
351
|
+
* })
|
|
352
|
+
* ```
|
|
353
|
+
*
|
|
354
|
+
* @param lookupDepth depth of search in backwards
|
|
355
|
+
* @example
|
|
356
|
+
*
|
|
357
|
+
* For provided command `run test:drive dir`
|
|
358
|
+
* - lookup1: `run test:drive dir` (deep = 0)
|
|
359
|
+
* - lookup2: `run test:drive` (deep = 1)
|
|
360
|
+
* - lookup3: `run test` (deep = 2)
|
|
361
|
+
* - lookup4: `run` (deep = 3)
|
|
362
|
+
* ...
|
|
363
|
+
*/
|
|
364
|
+
function useCommandLookupHelp(lookupDepth = 3) {
|
|
365
|
+
const parts = useCliContext()
|
|
366
|
+
.store('event')
|
|
367
|
+
.get('pathParams')
|
|
368
|
+
.map((p) => (p + ' ').split(':').map((s, i) => (i ? ':' + s : s)))
|
|
369
|
+
.flat();
|
|
370
|
+
const cliHelp = useCliHelp().getCliHelp();
|
|
371
|
+
const cmd = cliHelp.getCliName();
|
|
372
|
+
let data;
|
|
373
|
+
for (let i = 0; i < Math.min(parts.length, lookupDepth + 1); i++) {
|
|
374
|
+
const pathParams = parts
|
|
375
|
+
.slice(0, i ? -i : parts.length)
|
|
376
|
+
.join('')
|
|
377
|
+
.trim();
|
|
378
|
+
try {
|
|
379
|
+
data = cliHelp.match(pathParams);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
catch (e) {
|
|
383
|
+
const variants = cliHelp.lookup(pathParams);
|
|
384
|
+
if (variants.length) {
|
|
385
|
+
throw new Error(`Wrong command, did you mean:\n${variants
|
|
386
|
+
.slice(0, 7)
|
|
387
|
+
.map((c) => ` $ ${cmd} ${c.main.command}`)
|
|
388
|
+
.join('\n')}`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (data) {
|
|
393
|
+
const { main, children } = data;
|
|
394
|
+
if (main.args && Object.keys(main.args).length) {
|
|
395
|
+
throw new Error(`Arguments expected: ${Object.keys(main.args)
|
|
396
|
+
.map((l) => `<${l}>`)
|
|
397
|
+
.join(', ')}`);
|
|
398
|
+
}
|
|
399
|
+
else if (children && children.length) {
|
|
400
|
+
throw new Error(`Wrong command, did you mean:\n${children
|
|
401
|
+
.slice(0, 7)
|
|
402
|
+
.map((c) => ` $ ${cmd} ${c.command}`)
|
|
403
|
+
.join('\n')}`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
401
406
|
}
|
|
402
407
|
|
|
403
|
-
/**
|
|
404
|
-
* Get CLI Options
|
|
405
|
-
*
|
|
406
|
-
* @returns an object with CLI options
|
|
407
|
-
*/
|
|
408
|
-
function useCliOptions() {
|
|
409
|
-
const { store } = useCliContext();
|
|
410
|
-
const flags = store('flags');
|
|
411
|
-
if (!flags.value) {
|
|
412
|
-
const event = store('event');
|
|
413
|
-
flags.value = minimist(event.value.argv, event.get('opts'));
|
|
414
|
-
}
|
|
415
|
-
return flags.value;
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Getter for Cli Option value
|
|
419
|
-
*
|
|
420
|
-
* @param name name of the option
|
|
421
|
-
* @returns value of a CLI option
|
|
422
|
-
*/
|
|
423
|
-
function useCliOption(name) {
|
|
424
|
-
var _a;
|
|
425
|
-
try {
|
|
426
|
-
const options = ((_a = useCliHelp().getEntry()) === null || _a === void 0 ? void 0 : _a.options) || [];
|
|
427
|
-
const opt = options.find(o => o.keys.includes(name));
|
|
428
|
-
if (opt) {
|
|
429
|
-
for (const key of opt.keys) {
|
|
430
|
-
if (useCliOptions()[key]) {
|
|
431
|
-
return useCliOptions()[key];
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
catch (e) {
|
|
437
|
-
//
|
|
438
|
-
}
|
|
439
|
-
return useCliOptions()[name];
|
|
408
|
+
/**
|
|
409
|
+
* Get CLI Options
|
|
410
|
+
*
|
|
411
|
+
* @returns an object with CLI options
|
|
412
|
+
*/
|
|
413
|
+
function useCliOptions() {
|
|
414
|
+
const { store } = useCliContext();
|
|
415
|
+
const flags = store('flags');
|
|
416
|
+
if (!flags.value) {
|
|
417
|
+
const event = store('event');
|
|
418
|
+
flags.value = minimist(event.value.argv, event.get('opts'));
|
|
419
|
+
}
|
|
420
|
+
return flags.value;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Getter for Cli Option value
|
|
424
|
+
*
|
|
425
|
+
* @param name name of the option
|
|
426
|
+
* @returns value of a CLI option
|
|
427
|
+
*/
|
|
428
|
+
function useCliOption(name) {
|
|
429
|
+
var _a;
|
|
430
|
+
try {
|
|
431
|
+
const options = ((_a = useCliHelp().getEntry()) === null || _a === void 0 ? void 0 : _a.options) || [];
|
|
432
|
+
const opt = options.find(o => o.keys.includes(name));
|
|
433
|
+
if (opt) {
|
|
434
|
+
for (const key of opt.keys) {
|
|
435
|
+
if (useCliOptions()[key]) {
|
|
436
|
+
return useCliOptions()[key];
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
//
|
|
443
|
+
}
|
|
444
|
+
return useCliOptions()[name];
|
|
440
445
|
}
|
|
441
446
|
|
|
442
447
|
export { WooksCli, cliShortcuts, createCliApp, createCliContext, useAutoHelp, useCliContext, useCliHelp, useCliOption, useCliOptions, useCommandLookupHelp };
|