@moostjs/event-cli 0.2.27 → 0.2.29
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 +0 -2
- package/dist/index.cjs +355 -80
- package/dist/index.d.ts +233 -12
- package/dist/index.mjs +349 -79
- package/package.json +6 -5
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var eventCli = require('@wooksjs/event-cli');
|
|
4
|
-
var eventCore = require('@wooksjs/event-core');
|
|
5
3
|
var moost = require('moost');
|
|
4
|
+
var eventCli = require('@wooksjs/event-cli');
|
|
5
|
+
var cliHelp = require('@prostojs/cli-help');
|
|
6
6
|
|
|
7
7
|
/******************************************************************************
|
|
8
8
|
Copyright (c) Microsoft Corporation.
|
|
@@ -18,6 +18,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
18
18
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
19
19
|
PERFORMANCE OF THIS SOFTWARE.
|
|
20
20
|
***************************************************************************** */
|
|
21
|
+
/* global Reflect, Promise */
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
23
25
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -29,106 +31,241 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
29
31
|
});
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
function getCliMate() {
|
|
35
|
+
return moost.getMoostMate();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* ### setCliHelpForEvent
|
|
40
|
+
* Used internally to set CliHelpRenderer instance for an event state
|
|
41
|
+
* @param cliHelp CliHelpRenderer
|
|
42
|
+
*/
|
|
43
|
+
function setCliHelpForEvent(cliHelp) {
|
|
44
|
+
eventCli.useCliContext().store('event').set('cliHelp', cliHelp);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* ## useCliHelp
|
|
48
|
+
* ### Composable
|
|
49
|
+
* ```js
|
|
50
|
+
* // example of printing cli instructions
|
|
51
|
+
* const { print } = useCliHelp()
|
|
52
|
+
* print(true)
|
|
53
|
+
* ```
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
function useCliHelp() {
|
|
57
|
+
const event = eventCli.useCliContext().store('event');
|
|
58
|
+
const getCliHelp = () => event.get('cliHelp');
|
|
59
|
+
return {
|
|
60
|
+
getCliHelp,
|
|
61
|
+
render: (width, withColors) => getCliHelp().render(event.get('pathParams').join(' '), width, withColors),
|
|
62
|
+
print: (withColors) => getCliHelp().print(event.get('pathParams').join(' '), withColors),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const LOGGER_TITLE = 'moost-cli';
|
|
67
|
+
const CONTEXT_TYPE = 'CLI';
|
|
68
|
+
/**
|
|
69
|
+
* ## Moost Cli Adapter
|
|
70
|
+
*
|
|
71
|
+
* Moost Adapter for CLI events
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* │ // Quick example
|
|
75
|
+
* │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
|
|
76
|
+
* │ import { Moost, Param } from 'moost'
|
|
77
|
+
* │
|
|
78
|
+
* │ class MyApp extends Moost {
|
|
79
|
+
* │ @Cli('command/:arg')
|
|
80
|
+
* │ command(
|
|
81
|
+
* │ @Param('arg')
|
|
82
|
+
* │ arg: string,
|
|
83
|
+
* │ @CliOption('test', 't')
|
|
84
|
+
* │ test: boolean,
|
|
85
|
+
* │ ) {
|
|
86
|
+
* │ return `command run with flag arg=${ arg }, test=${ test }`
|
|
87
|
+
* │ }
|
|
88
|
+
* │ }
|
|
89
|
+
* │
|
|
90
|
+
* │ const app = new MyApp()
|
|
91
|
+
* │ app.applyGlobalInterceptors(cliHelpInterceptor())
|
|
92
|
+
* │
|
|
93
|
+
* │ const cli = new MoostCli()
|
|
94
|
+
* │ app.adapter(cli)
|
|
95
|
+
* │ app.init()
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
32
98
|
class MoostCli {
|
|
33
|
-
constructor(
|
|
34
|
-
|
|
35
|
-
|
|
99
|
+
constructor(opts) {
|
|
100
|
+
this.opts = opts;
|
|
101
|
+
const cliAppOpts = opts === null || opts === void 0 ? void 0 : opts.wooksCli;
|
|
102
|
+
if (cliAppOpts && cliAppOpts instanceof eventCli.WooksCli) {
|
|
103
|
+
this.cliApp = cliAppOpts;
|
|
104
|
+
}
|
|
105
|
+
else if (cliAppOpts) {
|
|
106
|
+
this.cliApp = eventCli.createCliApp(Object.assign(Object.assign({}, cliAppOpts), { onNotFound: this.onNotFound.bind(this) }));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.cliApp = eventCli.createCliApp({
|
|
110
|
+
onNotFound: this.onNotFound.bind(this),
|
|
111
|
+
});
|
|
36
112
|
}
|
|
37
|
-
|
|
38
|
-
|
|
113
|
+
const cliHelpOpts = opts === null || opts === void 0 ? void 0 : opts.cliHelp;
|
|
114
|
+
if (cliHelpOpts && cliHelpOpts instanceof cliHelp.CliHelpRenderer) {
|
|
115
|
+
this.cliHelp = cliHelpOpts;
|
|
116
|
+
}
|
|
117
|
+
else if (cliHelpOpts) {
|
|
118
|
+
this.cliHelp = new cliHelp.CliHelpRenderer(cliHelpOpts);
|
|
39
119
|
}
|
|
40
120
|
else {
|
|
41
|
-
this.
|
|
121
|
+
this.cliHelp = new cliHelp.CliHelpRenderer();
|
|
122
|
+
}
|
|
123
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.debug)) {
|
|
124
|
+
moost.getMoostInfact().silent(true);
|
|
42
125
|
}
|
|
43
126
|
}
|
|
44
|
-
|
|
127
|
+
onNotFound() {
|
|
128
|
+
var _a;
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
const pathParams = eventCli.useCliContext().store('event').get('pathParams');
|
|
131
|
+
const response = yield moost.defineMoostEventHandler({
|
|
132
|
+
loggerTitle: LOGGER_TITLE,
|
|
133
|
+
getIterceptorHandler: () => { var _a; return (_a = this.moost) === null || _a === void 0 ? void 0 : _a.getGlobalInterceptorHandler(); },
|
|
134
|
+
getControllerInstance: () => this.moost,
|
|
135
|
+
callControllerMethod: () => undefined,
|
|
136
|
+
logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
|
|
137
|
+
hooks: {
|
|
138
|
+
init: () => setCliHelpForEvent(this.cliHelp),
|
|
139
|
+
},
|
|
140
|
+
})();
|
|
141
|
+
if (typeof response === 'undefined') {
|
|
142
|
+
this.cliApp.onUnknownCommand(pathParams);
|
|
143
|
+
}
|
|
144
|
+
return response;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
onInit(moost) {
|
|
148
|
+
var _a;
|
|
149
|
+
this.moost = moost;
|
|
150
|
+
for (const [alias, entry] of Object.entries(this.cliHelp.getComputedAliases())) {
|
|
151
|
+
if (entry.custom) {
|
|
152
|
+
const vars = Object.keys(entry.args || {}).map(k => ':' + k).join('/');
|
|
153
|
+
const path = '/' + alias.replace(/\s+/g, '/').replace(/:/g, '\\:') + (vars ? '/' + vars : '');
|
|
154
|
+
this.cliApp.cli(path, entry.custom.fn);
|
|
155
|
+
if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug) {
|
|
156
|
+
entry.custom.log(`${'[36m'}(CLI-alias*)${'[32m'}${path}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
45
160
|
void this.cliApp.run();
|
|
46
161
|
}
|
|
47
162
|
bindHandler(opts) {
|
|
163
|
+
var _a, _b, _c, _d, _e, _f;
|
|
48
164
|
let fn;
|
|
49
165
|
for (const handler of opts.handlers) {
|
|
50
166
|
if (handler.type !== 'CLI')
|
|
51
167
|
continue;
|
|
52
|
-
const path = typeof handler.path === 'string'
|
|
53
|
-
|
|
168
|
+
const path = typeof handler.path === 'string'
|
|
169
|
+
? handler.path
|
|
170
|
+
: typeof opts.method === 'string'
|
|
171
|
+
? opts.method
|
|
172
|
+
: '';
|
|
173
|
+
const makePath = (p) => `${opts.prefix.replace(/\s+/g, '/') || ''}/${p}`
|
|
174
|
+
.replace(/\/\/+/g, '/')
|
|
175
|
+
// avoid interpreting "cmd:tail" as "cmd/:tail"
|
|
176
|
+
.replace(/\/\\:/g, '\\:');
|
|
177
|
+
let cliCommand = '';
|
|
54
178
|
if (!fn) {
|
|
55
|
-
fn = (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
let args = [];
|
|
67
|
-
try {
|
|
68
|
-
restoreCtx();
|
|
69
|
-
args = yield opts.resolveArgs();
|
|
70
|
-
}
|
|
71
|
-
catch (e) {
|
|
72
|
-
response = e;
|
|
73
|
-
}
|
|
74
|
-
if (!response) {
|
|
75
|
-
restoreCtx();
|
|
76
|
-
// fire before interceptors
|
|
77
|
-
response = yield interceptorHandler.fireBefore(response);
|
|
78
|
-
// fire request handler
|
|
79
|
-
if (!interceptorHandler.responseOverwritten) {
|
|
80
|
-
try {
|
|
81
|
-
restoreCtx();
|
|
82
|
-
response = yield instance[opts.method](...args);
|
|
83
|
-
}
|
|
84
|
-
catch (e) {
|
|
85
|
-
response = e;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
restoreCtx();
|
|
90
|
-
// fire after interceptors
|
|
91
|
-
response = yield interceptorHandler.fireAfter(response);
|
|
92
|
-
unscope();
|
|
93
|
-
return response;
|
|
179
|
+
fn = moost.defineMoostEventHandler({
|
|
180
|
+
contextType: CONTEXT_TYPE,
|
|
181
|
+
loggerTitle: LOGGER_TITLE,
|
|
182
|
+
getIterceptorHandler: opts.getIterceptorHandler,
|
|
183
|
+
getControllerInstance: opts.getInstance,
|
|
184
|
+
controllerMethod: opts.method,
|
|
185
|
+
resolveArgs: opts.resolveArgs,
|
|
186
|
+
logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
|
|
187
|
+
hooks: {
|
|
188
|
+
init: () => setCliHelpForEvent(this.cliHelp),
|
|
189
|
+
},
|
|
94
190
|
});
|
|
95
191
|
}
|
|
96
|
-
|
|
97
|
-
|
|
192
|
+
const targetPath = makePath(path);
|
|
193
|
+
const { getArgs, getStaticPart } = this.cliApp.cli(targetPath, fn);
|
|
194
|
+
const meta = getCliMate().read(opts.fakeInstance, opts.method);
|
|
195
|
+
const classMeta = getCliMate().read(opts.fakeInstance);
|
|
196
|
+
const args = {};
|
|
197
|
+
getArgs().forEach(a => {
|
|
198
|
+
var _a;
|
|
199
|
+
const argParam = (_a = meta === null || meta === void 0 ? void 0 : meta.params) === null || _a === void 0 ? void 0 : _a.find(p => p.label === a && p.description);
|
|
200
|
+
args[a] = (argParam === null || argParam === void 0 ? void 0 : argParam.description) || '';
|
|
201
|
+
});
|
|
202
|
+
cliCommand = getStaticPart().replace(/\//g, ' ').trim();
|
|
203
|
+
const cliOptions = new Map();
|
|
204
|
+
[
|
|
205
|
+
...(((_c = (_b = this.opts) === null || _b === void 0 ? void 0 : _b.globalCliOptions) === null || _c === void 0 ? void 0 : _c.length) ? this.opts.globalCliOptions : []),
|
|
206
|
+
...((classMeta === null || classMeta === void 0 ? void 0 : classMeta.cliOptions) || []),
|
|
207
|
+
...(((_d = meta === null || meta === void 0 ? void 0 : meta.params) === null || _d === void 0 ? void 0 : _d.filter(param => !!param.cliParamKeys && param.cliParamKeys.length > 0).map(param => ({
|
|
208
|
+
keys: param.cliParamKeys,
|
|
209
|
+
value: typeof param.value === 'string' ? param.value : '',
|
|
210
|
+
description: param.description || '',
|
|
211
|
+
}))) || []),
|
|
212
|
+
].forEach(o => cliOptions.set(o.keys[0], o));
|
|
213
|
+
if ((_e = this.opts) === null || _e === void 0 ? void 0 : _e.debug) {
|
|
214
|
+
opts.logHandler(`${'[36m'}(CLI)${'[32m'}${targetPath}`);
|
|
215
|
+
}
|
|
216
|
+
const aliases = [];
|
|
217
|
+
if (meta === null || meta === void 0 ? void 0 : meta.cliAliases) {
|
|
218
|
+
for (const alias of meta.cliAliases) {
|
|
219
|
+
const targetPath = makePath(alias);
|
|
220
|
+
const { getStaticPart } = this.cliApp.cli(targetPath, fn);
|
|
221
|
+
aliases.push(getStaticPart().replace(/\//g, ' ').trim());
|
|
222
|
+
if ((_f = this.opts) === null || _f === void 0 ? void 0 : _f.debug) {
|
|
223
|
+
opts.logHandler(`${'[36m'}(CLI-alias)${'[32m'}${targetPath}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
this.cliHelp.addEntry({
|
|
228
|
+
description: (meta === null || meta === void 0 ? void 0 : meta.description) || '',
|
|
229
|
+
command: cliCommand,
|
|
230
|
+
options: Array.from(cliOptions.values()),
|
|
231
|
+
args,
|
|
232
|
+
aliases: aliases,
|
|
233
|
+
custom: { fn, log: opts.logHandler },
|
|
234
|
+
examples: (meta === null || meta === void 0 ? void 0 : meta.cliExamples) || [],
|
|
235
|
+
});
|
|
98
236
|
}
|
|
99
237
|
}
|
|
100
238
|
}
|
|
101
239
|
|
|
102
|
-
function
|
|
103
|
-
|
|
240
|
+
function formatParams(keys) {
|
|
241
|
+
const names = [keys].flat();
|
|
242
|
+
return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
|
|
104
243
|
}
|
|
105
244
|
|
|
106
245
|
/**
|
|
107
|
-
*
|
|
108
|
-
* @
|
|
109
|
-
* @
|
|
110
|
-
*
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
246
|
+
* ## Define CLI Option
|
|
247
|
+
* ### @ParameterDecorator
|
|
248
|
+
* Use together with @Description('...') to document cli option
|
|
249
|
+
*
|
|
250
|
+
* ```ts
|
|
251
|
+
* │ @Cli('command')
|
|
252
|
+
* │ command(
|
|
253
|
+
* │ @Description('Test flag...')
|
|
254
|
+
* │ @CliOption('test', 't')
|
|
255
|
+
* │ test: boolean,
|
|
256
|
+
* │ ) {
|
|
257
|
+
* │ return `test=${ test }`
|
|
258
|
+
* │ }
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* @param keys list of keys (short and long alternatives)
|
|
262
|
+
* @returns
|
|
119
263
|
*/
|
|
120
|
-
function
|
|
121
|
-
return moost.Resolve(() => eventCli.useFlags(), 'flags');
|
|
122
|
-
}
|
|
123
|
-
function formatParams(keys) {
|
|
124
|
-
const names = [keys].flat();
|
|
125
|
-
return names.map(n => n.length === 1 ? '-' + n : '--' + n);
|
|
126
|
-
}
|
|
127
|
-
function CliParam(keys, descr) {
|
|
264
|
+
function CliOption(...keys) {
|
|
128
265
|
const mate = getCliMate();
|
|
129
|
-
return mate.apply(mate.decorate('
|
|
266
|
+
return mate.apply(mate.decorate('cliParamKeys', keys, false), moost.Resolve(() => {
|
|
130
267
|
const flags = eventCli.useFlags();
|
|
131
|
-
const names =
|
|
268
|
+
const names = keys;
|
|
132
269
|
const vals = [];
|
|
133
270
|
for (const name of names) {
|
|
134
271
|
if (flags[name]) {
|
|
@@ -143,14 +280,152 @@ function CliParam(keys, descr) {
|
|
|
143
280
|
}
|
|
144
281
|
return vals[0];
|
|
145
282
|
}, formatParams(keys).join(', ')));
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* ## Define Global CLI Option
|
|
286
|
+
* ### @ClassDecorator
|
|
287
|
+
* The option described here will appear in every command instructions
|
|
288
|
+
* @param option keys and description of CLI option
|
|
289
|
+
* @returns
|
|
290
|
+
*/
|
|
291
|
+
function CliGlobalOption(option) {
|
|
292
|
+
const mate = getCliMate();
|
|
293
|
+
return mate.decorate('cliOptions', option, true);
|
|
146
294
|
}
|
|
147
295
|
|
|
296
|
+
/**
|
|
297
|
+
* ## Define CLI Command
|
|
298
|
+
* ### @MethodDecorator
|
|
299
|
+
*
|
|
300
|
+
* Command path segments may be separated by / or space.
|
|
301
|
+
*
|
|
302
|
+
* For example the folowing path are interpreted the same:
|
|
303
|
+
* - "command test use:dev :name"
|
|
304
|
+
* - "command/test/use:dev/:name"
|
|
305
|
+
* Where name will become an argument
|
|
306
|
+
*
|
|
307
|
+
* @param path - command path
|
|
308
|
+
* @returns
|
|
309
|
+
*/
|
|
148
310
|
function Cli(path) {
|
|
149
|
-
return getCliMate().decorate('handlers', { path, type: 'CLI' }, true);
|
|
311
|
+
return getCliMate().decorate('handlers', { path: path === null || path === void 0 ? void 0 : path.replace(/\s+/g, '/'), type: 'CLI' }, true);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* ## Define CLI Command Alias
|
|
315
|
+
* ### @MethodDecorator
|
|
316
|
+
*
|
|
317
|
+
* Use it to define alias for @Cli('...') command
|
|
318
|
+
*
|
|
319
|
+
* @param path - command alias path
|
|
320
|
+
* @returns
|
|
321
|
+
*/
|
|
322
|
+
function CliAlias(alias) {
|
|
323
|
+
return getCliMate().decorate('cliAliases', alias, true);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* ## Define CLI Example
|
|
327
|
+
* ### @MethodDecorator
|
|
328
|
+
*
|
|
329
|
+
* Use it to define example for Cli Help display
|
|
330
|
+
*
|
|
331
|
+
* @param path - command alias path
|
|
332
|
+
* @returns
|
|
333
|
+
*/
|
|
334
|
+
function CliExample(cmd, description) {
|
|
335
|
+
return getCliMate().decorate('cliExamples', { cmd, description }, true);
|
|
150
336
|
}
|
|
151
337
|
|
|
338
|
+
/**
|
|
339
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
340
|
+
*
|
|
341
|
+
* By default intercepts cli calls with flag --help
|
|
342
|
+
* and prints help.
|
|
343
|
+
*
|
|
344
|
+
* ```js
|
|
345
|
+
* new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
|
|
346
|
+
* ```
|
|
347
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
348
|
+
* @returns TInterceptorFn
|
|
349
|
+
*/
|
|
350
|
+
const cliHelpInterceptor = (opts) => {
|
|
351
|
+
return moost.defineInterceptorFn(() => {
|
|
352
|
+
const helpOptions = (opts === null || opts === void 0 ? void 0 : opts.helpOptions) || ['help'];
|
|
353
|
+
for (const option of helpOptions) {
|
|
354
|
+
if (eventCli.useFlag(option) === true) {
|
|
355
|
+
try {
|
|
356
|
+
useCliHelp().print(opts === null || opts === void 0 ? void 0 : opts.colors);
|
|
357
|
+
return '';
|
|
358
|
+
}
|
|
359
|
+
catch (e) {
|
|
360
|
+
//
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) || (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd)) {
|
|
365
|
+
const { getMethod } = moost.useControllerContext();
|
|
366
|
+
if (!getMethod()) {
|
|
367
|
+
const parts = eventCli.useCliContext().store('event').get('pathParams');
|
|
368
|
+
const cliHelp = useCliHelp().getCliHelp();
|
|
369
|
+
const cmd = cliHelp.getCliName();
|
|
370
|
+
let data;
|
|
371
|
+
for (let i = 0; i < Math.min(parts.length, 4); i++) {
|
|
372
|
+
const pathParams = parts.slice(0, i ? -i : parts.length).join(' ');
|
|
373
|
+
try {
|
|
374
|
+
data = cliHelp.match(pathParams);
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
catch (e) {
|
|
378
|
+
if (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) {
|
|
379
|
+
const variants = cliHelp.lookup(pathParams);
|
|
380
|
+
if (variants.length) {
|
|
381
|
+
throw new Error(`Wrong command, did you mean:\n${variants.slice(0, 7).map(c => ` $ ${cmd} ${c.main.command}`).join('\n')}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (data) {
|
|
387
|
+
const { main, children } = data;
|
|
388
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) && main.args && Object.keys(main.args).length) {
|
|
389
|
+
throw new Error(`Arguments expected: ${Object.keys(main.args).map(l => `<${l}>`).join(', ')}`);
|
|
390
|
+
}
|
|
391
|
+
else if ((opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) && children && children.length) {
|
|
392
|
+
throw new Error(`Wrong command, did you mean:\n${children.slice(0, 7).map(c => ` $ ${cmd} ${c.command}`).join('\n')}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}, moost.TInterceptorPriority.BEFORE_ALL);
|
|
398
|
+
};
|
|
399
|
+
/**
|
|
400
|
+
* ## @Decorator
|
|
401
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
402
|
+
*
|
|
403
|
+
* By default intercepts cli calls with flag --help
|
|
404
|
+
* and prints help.
|
|
405
|
+
*
|
|
406
|
+
* ```ts
|
|
407
|
+
* // default configuration
|
|
408
|
+
* • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
|
|
409
|
+
*
|
|
410
|
+
* // additional option -h to invoke help renderer
|
|
411
|
+
* • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
|
|
412
|
+
*
|
|
413
|
+
* // redefine cli option to invoke help renderer
|
|
414
|
+
* • @CliHelpInterceptor({ helpOptions: ['usage'] })
|
|
415
|
+
* ```
|
|
416
|
+
*
|
|
417
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
418
|
+
* @returns Decorator
|
|
419
|
+
*/
|
|
420
|
+
const CliHelpInterceptor = (...opts) => moost.Intercept(cliHelpInterceptor(...opts));
|
|
421
|
+
|
|
152
422
|
exports.Cli = Cli;
|
|
153
|
-
exports.
|
|
154
|
-
exports.
|
|
155
|
-
exports.
|
|
423
|
+
exports.CliAlias = CliAlias;
|
|
424
|
+
exports.CliExample = CliExample;
|
|
425
|
+
exports.CliGlobalOption = CliGlobalOption;
|
|
426
|
+
exports.CliHelpInterceptor = CliHelpInterceptor;
|
|
427
|
+
exports.CliOption = CliOption;
|
|
156
428
|
exports.MoostCli = MoostCli;
|
|
429
|
+
exports.cliHelpInterceptor = cliHelpInterceptor;
|
|
430
|
+
exports.setCliHelpForEvent = setCliHelpForEvent;
|
|
431
|
+
exports.useCliHelp = useCliHelp;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,36 +1,257 @@
|
|
|
1
|
+
import { CliHelpRenderer } from '@prostojs/cli-help';
|
|
2
|
+
import { Moost } from 'moost';
|
|
3
|
+
import { TCliHelpOptions } from '@prostojs/cli-help';
|
|
4
|
+
import { TInterceptorFn } from 'moost';
|
|
1
5
|
import { TMoostAdapter } from 'moost';
|
|
2
6
|
import { TMoostAdapterOptions } from 'moost';
|
|
3
7
|
import { TWooksCliOptions } from '@wooksjs/event-cli';
|
|
8
|
+
import { TWooksHandler } from 'wooks';
|
|
4
9
|
import { WooksCli } from '@wooksjs/event-cli';
|
|
5
10
|
|
|
11
|
+
/**
|
|
12
|
+
* ## Define CLI Command
|
|
13
|
+
* ### @MethodDecorator
|
|
14
|
+
*
|
|
15
|
+
* Command path segments may be separated by / or space.
|
|
16
|
+
*
|
|
17
|
+
* For example the folowing path are interpreted the same:
|
|
18
|
+
* - "command test use:dev :name"
|
|
19
|
+
* - "command/test/use:dev/:name"
|
|
20
|
+
* Where name will become an argument
|
|
21
|
+
*
|
|
22
|
+
* @param path - command path
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
6
25
|
export declare function Cli(path?: string): MethodDecorator;
|
|
7
26
|
|
|
8
|
-
|
|
27
|
+
/**
|
|
28
|
+
* ## Define CLI Command Alias
|
|
29
|
+
* ### @MethodDecorator
|
|
30
|
+
*
|
|
31
|
+
* Use it to define alias for @Cli('...') command
|
|
32
|
+
*
|
|
33
|
+
* @param path - command alias path
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
export declare function CliAlias(alias: string): MethodDecorator;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* ## Define CLI Example
|
|
40
|
+
* ### @MethodDecorator
|
|
41
|
+
*
|
|
42
|
+
* Use it to define example for Cli Help display
|
|
43
|
+
*
|
|
44
|
+
* @param path - command alias path
|
|
45
|
+
* @returns
|
|
46
|
+
*/
|
|
47
|
+
export declare function CliExample(cmd: string, description?: string): MethodDecorator;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* ## Define Global CLI Option
|
|
51
|
+
* ### @ClassDecorator
|
|
52
|
+
* The option described here will appear in every command instructions
|
|
53
|
+
* @param option keys and description of CLI option
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
export declare function CliGlobalOption(option: {
|
|
57
|
+
keys: string[];
|
|
58
|
+
description?: string;
|
|
59
|
+
value?: string;
|
|
60
|
+
}): ClassDecorator;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* ## @Decorator
|
|
64
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
65
|
+
*
|
|
66
|
+
* By default intercepts cli calls with flag --help
|
|
67
|
+
* and prints help.
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* // default configuration
|
|
71
|
+
* • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
|
|
72
|
+
*
|
|
73
|
+
* // additional option -h to invoke help renderer
|
|
74
|
+
* • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
|
|
75
|
+
*
|
|
76
|
+
* // redefine cli option to invoke help renderer
|
|
77
|
+
* • @CliHelpInterceptor({ helpOptions: ['usage'] })
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
81
|
+
* @returns Decorator
|
|
82
|
+
*/
|
|
83
|
+
export declare const CliHelpInterceptor: (opts?: {
|
|
84
|
+
/**
|
|
85
|
+
* CLI Options that invoke help
|
|
86
|
+
* ```js
|
|
87
|
+
* helpOptions: ['help', 'h']
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
helpOptions?: string[] | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Enable colored help
|
|
93
|
+
*/
|
|
94
|
+
colors?: boolean | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Enable help message when arguments are missing
|
|
97
|
+
*/
|
|
98
|
+
helpWithArgs?: boolean | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Enable help message when command is incomplete
|
|
101
|
+
* and it is possible to suggest related commands
|
|
102
|
+
*/
|
|
103
|
+
helpWithIncompleteCmd?: boolean | undefined;
|
|
104
|
+
} | undefined) => ClassDecorator & MethodDecorator;
|
|
9
105
|
|
|
10
106
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
107
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
108
|
+
*
|
|
109
|
+
* By default intercepts cli calls with flag --help
|
|
110
|
+
* and prints help.
|
|
111
|
+
*
|
|
112
|
+
* ```js
|
|
113
|
+
* new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
|
|
114
|
+
* ```
|
|
115
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
116
|
+
* @returns TInterceptorFn
|
|
15
117
|
*/
|
|
16
|
-
export declare
|
|
118
|
+
export declare const cliHelpInterceptor: (opts?: {
|
|
119
|
+
/**
|
|
120
|
+
* CLI Options that invoke help
|
|
121
|
+
* ```js
|
|
122
|
+
* helpOptions: ['help', 'h']
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
helpOptions?: string[];
|
|
126
|
+
/**
|
|
127
|
+
* Enable colored help
|
|
128
|
+
*/
|
|
129
|
+
colors?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Enable help message when arguments are missing
|
|
132
|
+
*/
|
|
133
|
+
helpWithArgs?: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Enable help message when command is incomplete
|
|
136
|
+
* and it is possible to suggest related commands
|
|
137
|
+
*/
|
|
138
|
+
helpWithIncompleteCmd?: boolean;
|
|
139
|
+
}) => TInterceptorFn;
|
|
140
|
+
|
|
141
|
+
declare type CliHelpRendererWithFn = CliHelpRenderer<{
|
|
142
|
+
fn: TWooksHandler;
|
|
143
|
+
log: ((eventName: string) => void);
|
|
144
|
+
}>;
|
|
17
145
|
|
|
18
146
|
/**
|
|
19
|
-
*
|
|
20
|
-
* @
|
|
21
|
-
* @
|
|
147
|
+
* ## Define CLI Option
|
|
148
|
+
* ### @ParameterDecorator
|
|
149
|
+
* Use together with @Description('...') to document cli option
|
|
150
|
+
*
|
|
151
|
+
* ```ts
|
|
152
|
+
* │ @Cli('command')
|
|
153
|
+
* │ command(
|
|
154
|
+
* │ @Description('Test flag...')
|
|
155
|
+
* │ @CliOption('test', 't')
|
|
156
|
+
* │ test: boolean,
|
|
157
|
+
* │ ) {
|
|
158
|
+
* │ return `test=${ test }`
|
|
159
|
+
* │ }
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* @param keys list of keys (short and long alternatives)
|
|
163
|
+
* @returns
|
|
22
164
|
*/
|
|
23
|
-
export declare function
|
|
165
|
+
export declare function CliOption(...keys: string[]): ParameterDecorator;
|
|
24
166
|
|
|
167
|
+
/**
|
|
168
|
+
* ## Moost Cli Adapter
|
|
169
|
+
*
|
|
170
|
+
* Moost Adapter for CLI events
|
|
171
|
+
*
|
|
172
|
+
* ```ts
|
|
173
|
+
* │ // Quick example
|
|
174
|
+
* │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
|
|
175
|
+
* │ import { Moost, Param } from 'moost'
|
|
176
|
+
* │
|
|
177
|
+
* │ class MyApp extends Moost {
|
|
178
|
+
* │ @Cli('command/:arg')
|
|
179
|
+
* │ command(
|
|
180
|
+
* │ @Param('arg')
|
|
181
|
+
* │ arg: string,
|
|
182
|
+
* │ @CliOption('test', 't')
|
|
183
|
+
* │ test: boolean,
|
|
184
|
+
* │ ) {
|
|
185
|
+
* │ return `command run with flag arg=${ arg }, test=${ test }`
|
|
186
|
+
* │ }
|
|
187
|
+
* │ }
|
|
188
|
+
* │
|
|
189
|
+
* │ const app = new MyApp()
|
|
190
|
+
* │ app.applyGlobalInterceptors(cliHelpInterceptor())
|
|
191
|
+
* │
|
|
192
|
+
* │ const cli = new MoostCli()
|
|
193
|
+
* │ app.adapter(cli)
|
|
194
|
+
* │ app.init()
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
25
197
|
export declare class MoostCli implements TMoostAdapter<TCliHandlerMeta> {
|
|
198
|
+
protected opts?: TMoostCliOpts | undefined;
|
|
26
199
|
protected cliApp: WooksCli;
|
|
27
|
-
|
|
28
|
-
|
|
200
|
+
protected cliHelp: CliHelpRendererWithFn;
|
|
201
|
+
constructor(opts?: TMoostCliOpts | undefined);
|
|
202
|
+
onNotFound(): Promise<unknown>;
|
|
203
|
+
protected moost?: Moost;
|
|
204
|
+
onInit(moost: Moost): void;
|
|
29
205
|
bindHandler<T extends object = object>(opts: TMoostAdapterOptions<TCliHandlerMeta, T>): void | Promise<void>;
|
|
30
206
|
}
|
|
31
207
|
|
|
208
|
+
/**
|
|
209
|
+
* ### setCliHelpForEvent
|
|
210
|
+
* Used internally to set CliHelpRenderer instance for an event state
|
|
211
|
+
* @param cliHelp CliHelpRenderer
|
|
212
|
+
*/
|
|
213
|
+
export declare function setCliHelpForEvent(cliHelp: CliHelpRendererWithFn): void;
|
|
214
|
+
|
|
32
215
|
export declare interface TCliHandlerMeta {
|
|
33
216
|
path: string;
|
|
34
217
|
}
|
|
35
218
|
|
|
219
|
+
export declare interface TMoostCliOpts {
|
|
220
|
+
/**
|
|
221
|
+
* WooksCli options or instance
|
|
222
|
+
*/
|
|
223
|
+
wooksCli?: WooksCli | TWooksCliOptions;
|
|
224
|
+
/**
|
|
225
|
+
* CliHelpRenderer options or instance
|
|
226
|
+
*/
|
|
227
|
+
cliHelp?: CliHelpRendererWithFn | TCliHelpOptions;
|
|
228
|
+
/**
|
|
229
|
+
* more internal logs are printed when true
|
|
230
|
+
*/
|
|
231
|
+
debug?: boolean;
|
|
232
|
+
/**
|
|
233
|
+
* Array of cli options applicable to every cli command
|
|
234
|
+
*/
|
|
235
|
+
globalCliOptions?: {
|
|
236
|
+
keys: string[];
|
|
237
|
+
description?: string;
|
|
238
|
+
}[];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* ## useCliHelp
|
|
243
|
+
* ### Composable
|
|
244
|
+
* ```js
|
|
245
|
+
* // example of printing cli instructions
|
|
246
|
+
* const { print } = useCliHelp()
|
|
247
|
+
* print(true)
|
|
248
|
+
* ```
|
|
249
|
+
* @returns
|
|
250
|
+
*/
|
|
251
|
+
export declare function useCliHelp(): {
|
|
252
|
+
getCliHelp: () => CliHelpRendererWithFn;
|
|
253
|
+
render: (width?: number, withColors?: boolean) => string[];
|
|
254
|
+
print: (withColors?: boolean) => void;
|
|
255
|
+
};
|
|
256
|
+
|
|
36
257
|
export { }
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getMoostMate, getMoostInfact, defineMoostEventHandler, Resolve, defineInterceptorFn, useControllerContext, TInterceptorPriority, Intercept } from 'moost';
|
|
2
|
+
import { useCliContext, WooksCli, createCliApp, useFlags, useFlag } from '@wooksjs/event-cli';
|
|
3
|
+
import { CliHelpRenderer } from '@prostojs/cli-help';
|
|
4
4
|
|
|
5
5
|
/******************************************************************************
|
|
6
6
|
Copyright (c) Microsoft Corporation.
|
|
@@ -16,6 +16,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
16
16
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
17
17
|
PERFORMANCE OF THIS SOFTWARE.
|
|
18
18
|
***************************************************************************** */
|
|
19
|
+
/* global Reflect, Promise */
|
|
20
|
+
|
|
19
21
|
|
|
20
22
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
21
23
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -27,106 +29,241 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
function getCliMate() {
|
|
33
|
+
return getMoostMate();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* ### setCliHelpForEvent
|
|
38
|
+
* Used internally to set CliHelpRenderer instance for an event state
|
|
39
|
+
* @param cliHelp CliHelpRenderer
|
|
40
|
+
*/
|
|
41
|
+
function setCliHelpForEvent(cliHelp) {
|
|
42
|
+
useCliContext().store('event').set('cliHelp', cliHelp);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* ## useCliHelp
|
|
46
|
+
* ### Composable
|
|
47
|
+
* ```js
|
|
48
|
+
* // example of printing cli instructions
|
|
49
|
+
* const { print } = useCliHelp()
|
|
50
|
+
* print(true)
|
|
51
|
+
* ```
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
54
|
+
function useCliHelp() {
|
|
55
|
+
const event = useCliContext().store('event');
|
|
56
|
+
const getCliHelp = () => event.get('cliHelp');
|
|
57
|
+
return {
|
|
58
|
+
getCliHelp,
|
|
59
|
+
render: (width, withColors) => getCliHelp().render(event.get('pathParams').join(' '), width, withColors),
|
|
60
|
+
print: (withColors) => getCliHelp().print(event.get('pathParams').join(' '), withColors),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const LOGGER_TITLE = 'moost-cli';
|
|
65
|
+
const CONTEXT_TYPE = 'CLI';
|
|
66
|
+
/**
|
|
67
|
+
* ## Moost Cli Adapter
|
|
68
|
+
*
|
|
69
|
+
* Moost Adapter for CLI events
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* │ // Quick example
|
|
73
|
+
* │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
|
|
74
|
+
* │ import { Moost, Param } from 'moost'
|
|
75
|
+
* │
|
|
76
|
+
* │ class MyApp extends Moost {
|
|
77
|
+
* │ @Cli('command/:arg')
|
|
78
|
+
* │ command(
|
|
79
|
+
* │ @Param('arg')
|
|
80
|
+
* │ arg: string,
|
|
81
|
+
* │ @CliOption('test', 't')
|
|
82
|
+
* │ test: boolean,
|
|
83
|
+
* │ ) {
|
|
84
|
+
* │ return `command run with flag arg=${ arg }, test=${ test }`
|
|
85
|
+
* │ }
|
|
86
|
+
* │ }
|
|
87
|
+
* │
|
|
88
|
+
* │ const app = new MyApp()
|
|
89
|
+
* │ app.applyGlobalInterceptors(cliHelpInterceptor())
|
|
90
|
+
* │
|
|
91
|
+
* │ const cli = new MoostCli()
|
|
92
|
+
* │ app.adapter(cli)
|
|
93
|
+
* │ app.init()
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
30
96
|
class MoostCli {
|
|
31
|
-
constructor(
|
|
32
|
-
|
|
33
|
-
|
|
97
|
+
constructor(opts) {
|
|
98
|
+
this.opts = opts;
|
|
99
|
+
const cliAppOpts = opts === null || opts === void 0 ? void 0 : opts.wooksCli;
|
|
100
|
+
if (cliAppOpts && cliAppOpts instanceof WooksCli) {
|
|
101
|
+
this.cliApp = cliAppOpts;
|
|
34
102
|
}
|
|
35
|
-
else if (
|
|
36
|
-
this.cliApp = createCliApp(
|
|
103
|
+
else if (cliAppOpts) {
|
|
104
|
+
this.cliApp = createCliApp(Object.assign(Object.assign({}, cliAppOpts), { onNotFound: this.onNotFound.bind(this) }));
|
|
37
105
|
}
|
|
38
106
|
else {
|
|
39
|
-
this.cliApp = createCliApp(
|
|
107
|
+
this.cliApp = createCliApp({
|
|
108
|
+
onNotFound: this.onNotFound.bind(this),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const cliHelpOpts = opts === null || opts === void 0 ? void 0 : opts.cliHelp;
|
|
112
|
+
if (cliHelpOpts && cliHelpOpts instanceof CliHelpRenderer) {
|
|
113
|
+
this.cliHelp = cliHelpOpts;
|
|
114
|
+
}
|
|
115
|
+
else if (cliHelpOpts) {
|
|
116
|
+
this.cliHelp = new CliHelpRenderer(cliHelpOpts);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
this.cliHelp = new CliHelpRenderer();
|
|
120
|
+
}
|
|
121
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.debug)) {
|
|
122
|
+
getMoostInfact().silent(true);
|
|
40
123
|
}
|
|
41
124
|
}
|
|
42
|
-
|
|
125
|
+
onNotFound() {
|
|
126
|
+
var _a;
|
|
127
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
const pathParams = useCliContext().store('event').get('pathParams');
|
|
129
|
+
const response = yield defineMoostEventHandler({
|
|
130
|
+
loggerTitle: LOGGER_TITLE,
|
|
131
|
+
getIterceptorHandler: () => { var _a; return (_a = this.moost) === null || _a === void 0 ? void 0 : _a.getGlobalInterceptorHandler(); },
|
|
132
|
+
getControllerInstance: () => this.moost,
|
|
133
|
+
callControllerMethod: () => undefined,
|
|
134
|
+
logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
|
|
135
|
+
hooks: {
|
|
136
|
+
init: () => setCliHelpForEvent(this.cliHelp),
|
|
137
|
+
},
|
|
138
|
+
})();
|
|
139
|
+
if (typeof response === 'undefined') {
|
|
140
|
+
this.cliApp.onUnknownCommand(pathParams);
|
|
141
|
+
}
|
|
142
|
+
return response;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
onInit(moost) {
|
|
146
|
+
var _a;
|
|
147
|
+
this.moost = moost;
|
|
148
|
+
for (const [alias, entry] of Object.entries(this.cliHelp.getComputedAliases())) {
|
|
149
|
+
if (entry.custom) {
|
|
150
|
+
const vars = Object.keys(entry.args || {}).map(k => ':' + k).join('/');
|
|
151
|
+
const path = '/' + alias.replace(/\s+/g, '/').replace(/:/g, '\\:') + (vars ? '/' + vars : '');
|
|
152
|
+
this.cliApp.cli(path, entry.custom.fn);
|
|
153
|
+
if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug) {
|
|
154
|
+
entry.custom.log(`${'[36m'}(CLI-alias*)${'[32m'}${path}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
43
158
|
void this.cliApp.run();
|
|
44
159
|
}
|
|
45
160
|
bindHandler(opts) {
|
|
161
|
+
var _a, _b, _c, _d, _e, _f;
|
|
46
162
|
let fn;
|
|
47
163
|
for (const handler of opts.handlers) {
|
|
48
164
|
if (handler.type !== 'CLI')
|
|
49
165
|
continue;
|
|
50
|
-
const path = typeof handler.path === 'string'
|
|
51
|
-
|
|
166
|
+
const path = typeof handler.path === 'string'
|
|
167
|
+
? handler.path
|
|
168
|
+
: typeof opts.method === 'string'
|
|
169
|
+
? opts.method
|
|
170
|
+
: '';
|
|
171
|
+
const makePath = (p) => `${opts.prefix.replace(/\s+/g, '/') || ''}/${p}`
|
|
172
|
+
.replace(/\/\/+/g, '/')
|
|
173
|
+
// avoid interpreting "cmd:tail" as "cmd/:tail"
|
|
174
|
+
.replace(/\/\\:/g, '\\:');
|
|
175
|
+
let cliCommand = '';
|
|
52
176
|
if (!fn) {
|
|
53
|
-
fn = (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
let args = [];
|
|
65
|
-
try {
|
|
66
|
-
restoreCtx();
|
|
67
|
-
args = yield opts.resolveArgs();
|
|
68
|
-
}
|
|
69
|
-
catch (e) {
|
|
70
|
-
response = e;
|
|
71
|
-
}
|
|
72
|
-
if (!response) {
|
|
73
|
-
restoreCtx();
|
|
74
|
-
// fire before interceptors
|
|
75
|
-
response = yield interceptorHandler.fireBefore(response);
|
|
76
|
-
// fire request handler
|
|
77
|
-
if (!interceptorHandler.responseOverwritten) {
|
|
78
|
-
try {
|
|
79
|
-
restoreCtx();
|
|
80
|
-
response = yield instance[opts.method](...args);
|
|
81
|
-
}
|
|
82
|
-
catch (e) {
|
|
83
|
-
response = e;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
restoreCtx();
|
|
88
|
-
// fire after interceptors
|
|
89
|
-
response = yield interceptorHandler.fireAfter(response);
|
|
90
|
-
unscope();
|
|
91
|
-
return response;
|
|
177
|
+
fn = defineMoostEventHandler({
|
|
178
|
+
contextType: CONTEXT_TYPE,
|
|
179
|
+
loggerTitle: LOGGER_TITLE,
|
|
180
|
+
getIterceptorHandler: opts.getIterceptorHandler,
|
|
181
|
+
getControllerInstance: opts.getInstance,
|
|
182
|
+
controllerMethod: opts.method,
|
|
183
|
+
resolveArgs: opts.resolveArgs,
|
|
184
|
+
logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
|
|
185
|
+
hooks: {
|
|
186
|
+
init: () => setCliHelpForEvent(this.cliHelp),
|
|
187
|
+
},
|
|
92
188
|
});
|
|
93
189
|
}
|
|
94
|
-
|
|
95
|
-
|
|
190
|
+
const targetPath = makePath(path);
|
|
191
|
+
const { getArgs, getStaticPart } = this.cliApp.cli(targetPath, fn);
|
|
192
|
+
const meta = getCliMate().read(opts.fakeInstance, opts.method);
|
|
193
|
+
const classMeta = getCliMate().read(opts.fakeInstance);
|
|
194
|
+
const args = {};
|
|
195
|
+
getArgs().forEach(a => {
|
|
196
|
+
var _a;
|
|
197
|
+
const argParam = (_a = meta === null || meta === void 0 ? void 0 : meta.params) === null || _a === void 0 ? void 0 : _a.find(p => p.label === a && p.description);
|
|
198
|
+
args[a] = (argParam === null || argParam === void 0 ? void 0 : argParam.description) || '';
|
|
199
|
+
});
|
|
200
|
+
cliCommand = getStaticPart().replace(/\//g, ' ').trim();
|
|
201
|
+
const cliOptions = new Map();
|
|
202
|
+
[
|
|
203
|
+
...(((_c = (_b = this.opts) === null || _b === void 0 ? void 0 : _b.globalCliOptions) === null || _c === void 0 ? void 0 : _c.length) ? this.opts.globalCliOptions : []),
|
|
204
|
+
...((classMeta === null || classMeta === void 0 ? void 0 : classMeta.cliOptions) || []),
|
|
205
|
+
...(((_d = meta === null || meta === void 0 ? void 0 : meta.params) === null || _d === void 0 ? void 0 : _d.filter(param => !!param.cliParamKeys && param.cliParamKeys.length > 0).map(param => ({
|
|
206
|
+
keys: param.cliParamKeys,
|
|
207
|
+
value: typeof param.value === 'string' ? param.value : '',
|
|
208
|
+
description: param.description || '',
|
|
209
|
+
}))) || []),
|
|
210
|
+
].forEach(o => cliOptions.set(o.keys[0], o));
|
|
211
|
+
if ((_e = this.opts) === null || _e === void 0 ? void 0 : _e.debug) {
|
|
212
|
+
opts.logHandler(`${'[36m'}(CLI)${'[32m'}${targetPath}`);
|
|
213
|
+
}
|
|
214
|
+
const aliases = [];
|
|
215
|
+
if (meta === null || meta === void 0 ? void 0 : meta.cliAliases) {
|
|
216
|
+
for (const alias of meta.cliAliases) {
|
|
217
|
+
const targetPath = makePath(alias);
|
|
218
|
+
const { getStaticPart } = this.cliApp.cli(targetPath, fn);
|
|
219
|
+
aliases.push(getStaticPart().replace(/\//g, ' ').trim());
|
|
220
|
+
if ((_f = this.opts) === null || _f === void 0 ? void 0 : _f.debug) {
|
|
221
|
+
opts.logHandler(`${'[36m'}(CLI-alias)${'[32m'}${targetPath}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
this.cliHelp.addEntry({
|
|
226
|
+
description: (meta === null || meta === void 0 ? void 0 : meta.description) || '',
|
|
227
|
+
command: cliCommand,
|
|
228
|
+
options: Array.from(cliOptions.values()),
|
|
229
|
+
args,
|
|
230
|
+
aliases: aliases,
|
|
231
|
+
custom: { fn, log: opts.logHandler },
|
|
232
|
+
examples: (meta === null || meta === void 0 ? void 0 : meta.cliExamples) || [],
|
|
233
|
+
});
|
|
96
234
|
}
|
|
97
235
|
}
|
|
98
236
|
}
|
|
99
237
|
|
|
100
|
-
function
|
|
101
|
-
|
|
238
|
+
function formatParams(keys) {
|
|
239
|
+
const names = [keys].flat();
|
|
240
|
+
return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
|
|
102
241
|
}
|
|
103
242
|
|
|
104
243
|
/**
|
|
105
|
-
*
|
|
106
|
-
* @
|
|
107
|
-
* @
|
|
108
|
-
*
|
|
244
|
+
* ## Define CLI Option
|
|
245
|
+
* ### @ParameterDecorator
|
|
246
|
+
* Use together with @Description('...') to document cli option
|
|
247
|
+
*
|
|
248
|
+
* ```ts
|
|
249
|
+
* │ @Cli('command')
|
|
250
|
+
* │ command(
|
|
251
|
+
* │ @Description('Test flag...')
|
|
252
|
+
* │ @CliOption('test', 't')
|
|
253
|
+
* │ test: boolean,
|
|
254
|
+
* │ ) {
|
|
255
|
+
* │ return `test=${ test }`
|
|
256
|
+
* │ }
|
|
257
|
+
* ```
|
|
258
|
+
*
|
|
259
|
+
* @param keys list of keys (short and long alternatives)
|
|
260
|
+
* @returns
|
|
109
261
|
*/
|
|
110
|
-
function
|
|
111
|
-
return Resolve(() => useFlags()[name], name);
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Get Cli Flags
|
|
115
|
-
* @decorator
|
|
116
|
-
* @paramType object
|
|
117
|
-
*/
|
|
118
|
-
function Flags() {
|
|
119
|
-
return Resolve(() => useFlags(), 'flags');
|
|
120
|
-
}
|
|
121
|
-
function formatParams(keys) {
|
|
122
|
-
const names = [keys].flat();
|
|
123
|
-
return names.map(n => n.length === 1 ? '-' + n : '--' + n);
|
|
124
|
-
}
|
|
125
|
-
function CliParam(keys, descr) {
|
|
262
|
+
function CliOption(...keys) {
|
|
126
263
|
const mate = getCliMate();
|
|
127
|
-
return mate.apply(mate.decorate('
|
|
264
|
+
return mate.apply(mate.decorate('cliParamKeys', keys, false), Resolve(() => {
|
|
128
265
|
const flags = useFlags();
|
|
129
|
-
const names =
|
|
266
|
+
const names = keys;
|
|
130
267
|
const vals = [];
|
|
131
268
|
for (const name of names) {
|
|
132
269
|
if (flags[name]) {
|
|
@@ -141,10 +278,143 @@ function CliParam(keys, descr) {
|
|
|
141
278
|
}
|
|
142
279
|
return vals[0];
|
|
143
280
|
}, formatParams(keys).join(', ')));
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* ## Define Global CLI Option
|
|
284
|
+
* ### @ClassDecorator
|
|
285
|
+
* The option described here will appear in every command instructions
|
|
286
|
+
* @param option keys and description of CLI option
|
|
287
|
+
* @returns
|
|
288
|
+
*/
|
|
289
|
+
function CliGlobalOption(option) {
|
|
290
|
+
const mate = getCliMate();
|
|
291
|
+
return mate.decorate('cliOptions', option, true);
|
|
144
292
|
}
|
|
145
293
|
|
|
294
|
+
/**
|
|
295
|
+
* ## Define CLI Command
|
|
296
|
+
* ### @MethodDecorator
|
|
297
|
+
*
|
|
298
|
+
* Command path segments may be separated by / or space.
|
|
299
|
+
*
|
|
300
|
+
* For example the folowing path are interpreted the same:
|
|
301
|
+
* - "command test use:dev :name"
|
|
302
|
+
* - "command/test/use:dev/:name"
|
|
303
|
+
* Where name will become an argument
|
|
304
|
+
*
|
|
305
|
+
* @param path - command path
|
|
306
|
+
* @returns
|
|
307
|
+
*/
|
|
146
308
|
function Cli(path) {
|
|
147
|
-
return getCliMate().decorate('handlers', { path, type: 'CLI' }, true);
|
|
309
|
+
return getCliMate().decorate('handlers', { path: path === null || path === void 0 ? void 0 : path.replace(/\s+/g, '/'), type: 'CLI' }, true);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* ## Define CLI Command Alias
|
|
313
|
+
* ### @MethodDecorator
|
|
314
|
+
*
|
|
315
|
+
* Use it to define alias for @Cli('...') command
|
|
316
|
+
*
|
|
317
|
+
* @param path - command alias path
|
|
318
|
+
* @returns
|
|
319
|
+
*/
|
|
320
|
+
function CliAlias(alias) {
|
|
321
|
+
return getCliMate().decorate('cliAliases', alias, true);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* ## Define CLI Example
|
|
325
|
+
* ### @MethodDecorator
|
|
326
|
+
*
|
|
327
|
+
* Use it to define example for Cli Help display
|
|
328
|
+
*
|
|
329
|
+
* @param path - command alias path
|
|
330
|
+
* @returns
|
|
331
|
+
*/
|
|
332
|
+
function CliExample(cmd, description) {
|
|
333
|
+
return getCliMate().decorate('cliExamples', { cmd, description }, true);
|
|
148
334
|
}
|
|
149
335
|
|
|
150
|
-
|
|
336
|
+
/**
|
|
337
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
338
|
+
*
|
|
339
|
+
* By default intercepts cli calls with flag --help
|
|
340
|
+
* and prints help.
|
|
341
|
+
*
|
|
342
|
+
* ```js
|
|
343
|
+
* new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
|
|
344
|
+
* ```
|
|
345
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
346
|
+
* @returns TInterceptorFn
|
|
347
|
+
*/
|
|
348
|
+
const cliHelpInterceptor = (opts) => {
|
|
349
|
+
return defineInterceptorFn(() => {
|
|
350
|
+
const helpOptions = (opts === null || opts === void 0 ? void 0 : opts.helpOptions) || ['help'];
|
|
351
|
+
for (const option of helpOptions) {
|
|
352
|
+
if (useFlag(option) === true) {
|
|
353
|
+
try {
|
|
354
|
+
useCliHelp().print(opts === null || opts === void 0 ? void 0 : opts.colors);
|
|
355
|
+
return '';
|
|
356
|
+
}
|
|
357
|
+
catch (e) {
|
|
358
|
+
//
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) || (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd)) {
|
|
363
|
+
const { getMethod } = useControllerContext();
|
|
364
|
+
if (!getMethod()) {
|
|
365
|
+
const parts = useCliContext().store('event').get('pathParams');
|
|
366
|
+
const cliHelp = useCliHelp().getCliHelp();
|
|
367
|
+
const cmd = cliHelp.getCliName();
|
|
368
|
+
let data;
|
|
369
|
+
for (let i = 0; i < Math.min(parts.length, 4); i++) {
|
|
370
|
+
const pathParams = parts.slice(0, i ? -i : parts.length).join(' ');
|
|
371
|
+
try {
|
|
372
|
+
data = cliHelp.match(pathParams);
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
catch (e) {
|
|
376
|
+
if (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) {
|
|
377
|
+
const variants = cliHelp.lookup(pathParams);
|
|
378
|
+
if (variants.length) {
|
|
379
|
+
throw new Error(`Wrong command, did you mean:\n${variants.slice(0, 7).map(c => ` $ ${cmd} ${c.main.command}`).join('\n')}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (data) {
|
|
385
|
+
const { main, children } = data;
|
|
386
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) && main.args && Object.keys(main.args).length) {
|
|
387
|
+
throw new Error(`Arguments expected: ${Object.keys(main.args).map(l => `<${l}>`).join(', ')}`);
|
|
388
|
+
}
|
|
389
|
+
else if ((opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) && children && children.length) {
|
|
390
|
+
throw new Error(`Wrong command, did you mean:\n${children.slice(0, 7).map(c => ` $ ${cmd} ${c.command}`).join('\n')}`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}, TInterceptorPriority.BEFORE_ALL);
|
|
396
|
+
};
|
|
397
|
+
/**
|
|
398
|
+
* ## @Decorator
|
|
399
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
400
|
+
*
|
|
401
|
+
* By default intercepts cli calls with flag --help
|
|
402
|
+
* and prints help.
|
|
403
|
+
*
|
|
404
|
+
* ```ts
|
|
405
|
+
* // default configuration
|
|
406
|
+
* • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
|
|
407
|
+
*
|
|
408
|
+
* // additional option -h to invoke help renderer
|
|
409
|
+
* • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
|
|
410
|
+
*
|
|
411
|
+
* // redefine cli option to invoke help renderer
|
|
412
|
+
* • @CliHelpInterceptor({ helpOptions: ['usage'] })
|
|
413
|
+
* ```
|
|
414
|
+
*
|
|
415
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
416
|
+
* @returns Decorator
|
|
417
|
+
*/
|
|
418
|
+
const CliHelpInterceptor = (...opts) => Intercept(cliHelpInterceptor(...opts));
|
|
419
|
+
|
|
420
|
+
export { Cli, CliAlias, CliExample, CliGlobalOption, CliHelpInterceptor, CliOption, MoostCli, cliHelpInterceptor, setCliHelpForEvent, useCliHelp };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moostjs/event-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.29",
|
|
4
4
|
"description": "@moostjs/event-cli",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/moostjs/moostjs/tree/main/packages/event-cli#readme",
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"moost": "0.2.
|
|
32
|
-
"wooks": "^0.2.
|
|
33
|
-
"@wooksjs/event-core": "^0.2.
|
|
31
|
+
"moost": "0.2.29",
|
|
32
|
+
"wooks": "^0.2.23",
|
|
33
|
+
"@wooksjs/event-core": "^0.2.23"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@wooksjs/event-cli": "^0.2.
|
|
36
|
+
"@wooksjs/event-cli": "^0.2.23",
|
|
37
|
+
"@prostojs/cli-help": "^0.0.9"
|
|
37
38
|
}
|
|
38
39
|
}
|