@moostjs/event-cli 0.2.26 → 0.2.28
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 +294 -80
- package/dist/index.d.ts +196 -12
- package/dist/index.mjs +290 -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,209 @@ 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;
|
|
36
104
|
}
|
|
37
|
-
else if (
|
|
38
|
-
this.cliApp = eventCli.createCliApp(
|
|
105
|
+
else if (cliAppOpts) {
|
|
106
|
+
this.cliApp = eventCli.createCliApp(Object.assign(Object.assign({}, cliAppOpts), { onNotFound: this.onNotFound.bind(this) }));
|
|
39
107
|
}
|
|
40
108
|
else {
|
|
41
|
-
this.cliApp = eventCli.createCliApp(
|
|
109
|
+
this.cliApp = eventCli.createCliApp({
|
|
110
|
+
onNotFound: this.onNotFound.bind(this),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const cliHelpOpts = opts === null || opts === void 0 ? void 0 : opts.cliHelp;
|
|
114
|
+
if (cliHelpOpts && cliHelpOpts instanceof cliHelp.CliHelpRenderer) {
|
|
115
|
+
this.cliHelp = cliHelpOpts;
|
|
42
116
|
}
|
|
117
|
+
else if (cliHelpOpts) {
|
|
118
|
+
this.cliHelp = new cliHelp.CliHelpRenderer(cliHelpOpts);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
this.cliHelp = new cliHelp.CliHelpRenderer();
|
|
122
|
+
}
|
|
123
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.debug)) {
|
|
124
|
+
moost.getMoostInfact().silent(true);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
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
|
+
});
|
|
43
146
|
}
|
|
44
|
-
onInit() {
|
|
147
|
+
onInit(moost) {
|
|
148
|
+
this.moost = moost;
|
|
45
149
|
void this.cliApp.run();
|
|
46
150
|
}
|
|
47
151
|
bindHandler(opts) {
|
|
152
|
+
var _a, _b, _c;
|
|
48
153
|
let fn;
|
|
49
154
|
for (const handler of opts.handlers) {
|
|
50
155
|
if (handler.type !== 'CLI')
|
|
51
156
|
continue;
|
|
52
|
-
const path = typeof handler.path === 'string'
|
|
53
|
-
|
|
157
|
+
const path = typeof handler.path === 'string'
|
|
158
|
+
? handler.path
|
|
159
|
+
: typeof opts.method === 'string'
|
|
160
|
+
? opts.method
|
|
161
|
+
: '';
|
|
162
|
+
const targetPath = `${opts.prefix.replace(/\s+/g, '/') || ''}/${path}`
|
|
163
|
+
.replace(/\/\/+/g, '/')
|
|
164
|
+
// avoid interpreting "cmd:tail" as "cmd/:tail"
|
|
165
|
+
.replace(/\/\\:/g, '\\:');
|
|
166
|
+
let cliCommand = '';
|
|
54
167
|
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;
|
|
168
|
+
fn = moost.defineMoostEventHandler({
|
|
169
|
+
contextType: CONTEXT_TYPE,
|
|
170
|
+
loggerTitle: LOGGER_TITLE,
|
|
171
|
+
getIterceptorHandler: opts.getIterceptorHandler,
|
|
172
|
+
getControllerInstance: opts.getInstance,
|
|
173
|
+
controllerMethod: opts.method,
|
|
174
|
+
resolveArgs: opts.resolveArgs,
|
|
175
|
+
logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
|
|
176
|
+
hooks: {
|
|
177
|
+
init: () => setCliHelpForEvent(this.cliHelp),
|
|
178
|
+
},
|
|
94
179
|
});
|
|
95
180
|
}
|
|
96
|
-
this.cliApp.cli(targetPath, fn);
|
|
97
|
-
opts.
|
|
181
|
+
const { getArgs, getStaticPart } = this.cliApp.cli(targetPath, fn);
|
|
182
|
+
const meta = getCliMate().read(opts.fakeInstance, opts.method);
|
|
183
|
+
const args = {};
|
|
184
|
+
getArgs().forEach(a => {
|
|
185
|
+
var _a;
|
|
186
|
+
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);
|
|
187
|
+
args[a] = (argParam === null || argParam === void 0 ? void 0 : argParam.description) || '';
|
|
188
|
+
});
|
|
189
|
+
cliCommand = getStaticPart().replace(/\//g, ' ').trim();
|
|
190
|
+
this.cliHelp.addEntry({
|
|
191
|
+
description: (meta === null || meta === void 0 ? void 0 : meta.description) || '',
|
|
192
|
+
command: cliCommand,
|
|
193
|
+
options: ((_b = meta === null || meta === void 0 ? void 0 : meta.params) === null || _b === void 0 ? void 0 : _b.filter(param => !!param.cliParamKeys && param.cliParamKeys.length > 0).map(param => ({
|
|
194
|
+
keys: param.cliParamKeys,
|
|
195
|
+
value: typeof param.value === 'string' ? param.value : '',
|
|
196
|
+
description: param.description || '',
|
|
197
|
+
}))) || [],
|
|
198
|
+
args,
|
|
199
|
+
aliases: meta === null || meta === void 0 ? void 0 : meta.cliAliases,
|
|
200
|
+
});
|
|
201
|
+
if ((_c = this.opts) === null || _c === void 0 ? void 0 : _c.debug) {
|
|
202
|
+
opts.logHandler(`${'[36m'}(CLI)${'[32m'}${targetPath}`);
|
|
203
|
+
}
|
|
98
204
|
}
|
|
99
205
|
}
|
|
100
206
|
}
|
|
101
207
|
|
|
102
|
-
function
|
|
103
|
-
|
|
208
|
+
function formatParams(keys) {
|
|
209
|
+
const names = [keys].flat();
|
|
210
|
+
return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
|
|
104
211
|
}
|
|
105
212
|
|
|
106
213
|
/**
|
|
107
|
-
*
|
|
108
|
-
* @
|
|
109
|
-
* @
|
|
110
|
-
*
|
|
214
|
+
* ## Define CLI Option
|
|
215
|
+
* ### @ParameterDecorator
|
|
216
|
+
* Use together with @Description('...') to document cli option
|
|
217
|
+
*
|
|
218
|
+
* ```ts
|
|
219
|
+
* │ @Cli('command')
|
|
220
|
+
* │ command(
|
|
221
|
+
* │ @Description('Test flag...')
|
|
222
|
+
* │ @CliOption('test', 't')
|
|
223
|
+
* │ test: boolean,
|
|
224
|
+
* │ ) {
|
|
225
|
+
* │ return `test=${ test }`
|
|
226
|
+
* │ }
|
|
227
|
+
* ```
|
|
228
|
+
*
|
|
229
|
+
* @param keys list of keys (short and long alternatives)
|
|
230
|
+
* @returns
|
|
111
231
|
*/
|
|
112
|
-
function
|
|
113
|
-
return moost.Resolve(() => eventCli.useFlags()[name], name);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Get Cli Flags
|
|
117
|
-
* @decorator
|
|
118
|
-
* @paramType object
|
|
119
|
-
*/
|
|
120
|
-
function Flags() {
|
|
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) {
|
|
232
|
+
function CliOption(...keys) {
|
|
128
233
|
const mate = getCliMate();
|
|
129
|
-
return mate.apply(mate.decorate('
|
|
234
|
+
return mate.apply(mate.decorate('cliParamKeys', keys, false), moost.Resolve(() => {
|
|
130
235
|
const flags = eventCli.useFlags();
|
|
131
|
-
const names =
|
|
236
|
+
const names = keys;
|
|
132
237
|
const vals = [];
|
|
133
238
|
for (const name of names) {
|
|
134
239
|
if (flags[name]) {
|
|
@@ -145,12 +250,121 @@ function CliParam(keys, descr) {
|
|
|
145
250
|
}, formatParams(keys).join(', ')));
|
|
146
251
|
}
|
|
147
252
|
|
|
253
|
+
/**
|
|
254
|
+
* ## Define CLI Command
|
|
255
|
+
* ### @MethodDecorator
|
|
256
|
+
*
|
|
257
|
+
* Command path segments may be separated by / or space.
|
|
258
|
+
*
|
|
259
|
+
* For example the folowing path are interpreted the same:
|
|
260
|
+
* - "command test use:dev :name"
|
|
261
|
+
* - "command/test/use:dev/:name"
|
|
262
|
+
* Where name will become an argument
|
|
263
|
+
*
|
|
264
|
+
* @param path - command path
|
|
265
|
+
* @returns
|
|
266
|
+
*/
|
|
148
267
|
function Cli(path) {
|
|
149
|
-
return getCliMate().decorate('handlers', { path, type: 'CLI' }, true);
|
|
268
|
+
return getCliMate().decorate('handlers', { path: path === null || path === void 0 ? void 0 : path.replace(/\s+/g, '/'), type: 'CLI' }, true);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* ## Define CLI Command Alias
|
|
272
|
+
* ### @MethodDecorator
|
|
273
|
+
*
|
|
274
|
+
* Use it to define alias for @Cli('...') command
|
|
275
|
+
*
|
|
276
|
+
* @param path - command alias path
|
|
277
|
+
* @returns
|
|
278
|
+
*/
|
|
279
|
+
function CliAlias(alias) {
|
|
280
|
+
return getCliMate().decorate('cliAliases', alias, true);
|
|
150
281
|
}
|
|
151
282
|
|
|
283
|
+
/**
|
|
284
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
285
|
+
*
|
|
286
|
+
* By default intercepts cli calls with flag --help
|
|
287
|
+
* and prints help.
|
|
288
|
+
*
|
|
289
|
+
* ```js
|
|
290
|
+
* new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
|
|
291
|
+
* ```
|
|
292
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
293
|
+
* @returns TInterceptorFn
|
|
294
|
+
*/
|
|
295
|
+
const cliHelpInterceptor = (opts) => {
|
|
296
|
+
return moost.defineInterceptorFn(() => {
|
|
297
|
+
const helpOptions = (opts === null || opts === void 0 ? void 0 : opts.helpOptions) || ['help'];
|
|
298
|
+
for (const option of helpOptions) {
|
|
299
|
+
if (eventCli.useFlag(option) === true) {
|
|
300
|
+
try {
|
|
301
|
+
useCliHelp().print(opts === null || opts === void 0 ? void 0 : opts.colors);
|
|
302
|
+
return '';
|
|
303
|
+
}
|
|
304
|
+
catch (e) {
|
|
305
|
+
//
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) || (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd)) {
|
|
310
|
+
const { getMethod } = moost.useControllerContext();
|
|
311
|
+
if (!getMethod()) {
|
|
312
|
+
const pathParams = eventCli.useCliContext().store('event').get('pathParams').join(' ');
|
|
313
|
+
const cliHelp = useCliHelp().getCliHelp();
|
|
314
|
+
const cmd = cliHelp.getCliName();
|
|
315
|
+
let data;
|
|
316
|
+
try {
|
|
317
|
+
data = cliHelp.match(pathParams);
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
if (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) {
|
|
321
|
+
const variants = cliHelp.lookup(pathParams);
|
|
322
|
+
if (variants.length) {
|
|
323
|
+
throw new Error(`Command is incomplete, did you mean:\n${variants.slice(0, 7).map(c => ` $ ${cmd} ${c.main.command}`).join('\n')}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (data) {
|
|
328
|
+
const { main, children } = data;
|
|
329
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) && main.args && Object.keys(main.args).length) {
|
|
330
|
+
throw new Error(`Arguments expected: ${Object.keys(main.args).map(l => `<${l}>`).join(', ')}`);
|
|
331
|
+
}
|
|
332
|
+
else if ((opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) && children) {
|
|
333
|
+
throw new Error(`Command is incomplete, did you mean:\n${children.slice(0, 7).map(c => ` $ ${cmd} ${c.command}`).join('\n')}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}, moost.TInterceptorPriority.BEFORE_ALL);
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* ## @Decorator
|
|
342
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
343
|
+
*
|
|
344
|
+
* By default intercepts cli calls with flag --help
|
|
345
|
+
* and prints help.
|
|
346
|
+
*
|
|
347
|
+
* ```ts
|
|
348
|
+
* // default configuration
|
|
349
|
+
* • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
|
|
350
|
+
*
|
|
351
|
+
* // additional option -h to invoke help renderer
|
|
352
|
+
* • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
|
|
353
|
+
*
|
|
354
|
+
* // redefine cli option to invoke help renderer
|
|
355
|
+
* • @CliHelpInterceptor({ helpOptions: ['usage'] })
|
|
356
|
+
* ```
|
|
357
|
+
*
|
|
358
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
359
|
+
* @returns Decorator
|
|
360
|
+
*/
|
|
361
|
+
const CliHelpInterceptor = (...opts) => moost.Intercept(cliHelpInterceptor(...opts));
|
|
362
|
+
|
|
152
363
|
exports.Cli = Cli;
|
|
153
|
-
exports.
|
|
154
|
-
exports.
|
|
155
|
-
exports.
|
|
364
|
+
exports.CliAlias = CliAlias;
|
|
365
|
+
exports.CliHelpInterceptor = CliHelpInterceptor;
|
|
366
|
+
exports.CliOption = CliOption;
|
|
156
367
|
exports.MoostCli = MoostCli;
|
|
368
|
+
exports.cliHelpInterceptor = cliHelpInterceptor;
|
|
369
|
+
exports.setCliHelpForEvent = setCliHelpForEvent;
|
|
370
|
+
exports.useCliHelp = useCliHelp;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,36 +1,220 @@
|
|
|
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';
|
|
4
8
|
import { WooksCli } from '@wooksjs/event-cli';
|
|
5
9
|
|
|
10
|
+
/**
|
|
11
|
+
* ## Define CLI Command
|
|
12
|
+
* ### @MethodDecorator
|
|
13
|
+
*
|
|
14
|
+
* Command path segments may be separated by / or space.
|
|
15
|
+
*
|
|
16
|
+
* For example the folowing path are interpreted the same:
|
|
17
|
+
* - "command test use:dev :name"
|
|
18
|
+
* - "command/test/use:dev/:name"
|
|
19
|
+
* Where name will become an argument
|
|
20
|
+
*
|
|
21
|
+
* @param path - command path
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
6
24
|
export declare function Cli(path?: string): MethodDecorator;
|
|
7
25
|
|
|
8
|
-
|
|
26
|
+
/**
|
|
27
|
+
* ## Define CLI Command Alias
|
|
28
|
+
* ### @MethodDecorator
|
|
29
|
+
*
|
|
30
|
+
* Use it to define alias for @Cli('...') command
|
|
31
|
+
*
|
|
32
|
+
* @param path - command alias path
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
export declare function CliAlias(alias: string): MethodDecorator;
|
|
9
36
|
|
|
10
37
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
38
|
+
* ## @Decorator
|
|
39
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
40
|
+
*
|
|
41
|
+
* By default intercepts cli calls with flag --help
|
|
42
|
+
* and prints help.
|
|
43
|
+
*
|
|
44
|
+
* ```ts
|
|
45
|
+
* // default configuration
|
|
46
|
+
* • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
|
|
47
|
+
*
|
|
48
|
+
* // additional option -h to invoke help renderer
|
|
49
|
+
* • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
|
|
50
|
+
*
|
|
51
|
+
* // redefine cli option to invoke help renderer
|
|
52
|
+
* • @CliHelpInterceptor({ helpOptions: ['usage'] })
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
56
|
+
* @returns Decorator
|
|
15
57
|
*/
|
|
16
|
-
export declare
|
|
58
|
+
export declare const CliHelpInterceptor: (opts?: {
|
|
59
|
+
/**
|
|
60
|
+
* CLI Options that invoke help
|
|
61
|
+
* ```js
|
|
62
|
+
* helpOptions: ['help', 'h']
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
helpOptions?: string[] | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Enable colored help
|
|
68
|
+
*/
|
|
69
|
+
colors?: boolean | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Enable help message when arguments are missing
|
|
72
|
+
*/
|
|
73
|
+
helpWithArgs?: boolean | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Enable help message when command is incomplete
|
|
76
|
+
* and it is possible to suggest related commands
|
|
77
|
+
*/
|
|
78
|
+
helpWithIncompleteCmd?: boolean | undefined;
|
|
79
|
+
} | undefined) => ClassDecorator & MethodDecorator;
|
|
17
80
|
|
|
18
81
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
82
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
83
|
+
*
|
|
84
|
+
* By default intercepts cli calls with flag --help
|
|
85
|
+
* and prints help.
|
|
86
|
+
*
|
|
87
|
+
* ```js
|
|
88
|
+
* new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
|
|
89
|
+
* ```
|
|
90
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
91
|
+
* @returns TInterceptorFn
|
|
22
92
|
*/
|
|
23
|
-
export declare
|
|
93
|
+
export declare const cliHelpInterceptor: (opts?: {
|
|
94
|
+
/**
|
|
95
|
+
* CLI Options that invoke help
|
|
96
|
+
* ```js
|
|
97
|
+
* helpOptions: ['help', 'h']
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
helpOptions?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* Enable colored help
|
|
103
|
+
*/
|
|
104
|
+
colors?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Enable help message when arguments are missing
|
|
107
|
+
*/
|
|
108
|
+
helpWithArgs?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Enable help message when command is incomplete
|
|
111
|
+
* and it is possible to suggest related commands
|
|
112
|
+
*/
|
|
113
|
+
helpWithIncompleteCmd?: boolean;
|
|
114
|
+
}) => TInterceptorFn;
|
|
24
115
|
|
|
116
|
+
/**
|
|
117
|
+
* ## Define CLI Option
|
|
118
|
+
* ### @ParameterDecorator
|
|
119
|
+
* Use together with @Description('...') to document cli option
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* │ @Cli('command')
|
|
123
|
+
* │ command(
|
|
124
|
+
* │ @Description('Test flag...')
|
|
125
|
+
* │ @CliOption('test', 't')
|
|
126
|
+
* │ test: boolean,
|
|
127
|
+
* │ ) {
|
|
128
|
+
* │ return `test=${ test }`
|
|
129
|
+
* │ }
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* @param keys list of keys (short and long alternatives)
|
|
133
|
+
* @returns
|
|
134
|
+
*/
|
|
135
|
+
export declare function CliOption(...keys: string[]): ParameterDecorator;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* ## Moost Cli Adapter
|
|
139
|
+
*
|
|
140
|
+
* Moost Adapter for CLI events
|
|
141
|
+
*
|
|
142
|
+
* ```ts
|
|
143
|
+
* │ // Quick example
|
|
144
|
+
* │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
|
|
145
|
+
* │ import { Moost, Param } from 'moost'
|
|
146
|
+
* │
|
|
147
|
+
* │ class MyApp extends Moost {
|
|
148
|
+
* │ @Cli('command/:arg')
|
|
149
|
+
* │ command(
|
|
150
|
+
* │ @Param('arg')
|
|
151
|
+
* │ arg: string,
|
|
152
|
+
* │ @CliOption('test', 't')
|
|
153
|
+
* │ test: boolean,
|
|
154
|
+
* │ ) {
|
|
155
|
+
* │ return `command run with flag arg=${ arg }, test=${ test }`
|
|
156
|
+
* │ }
|
|
157
|
+
* │ }
|
|
158
|
+
* │
|
|
159
|
+
* │ const app = new MyApp()
|
|
160
|
+
* │ app.applyGlobalInterceptors(cliHelpInterceptor())
|
|
161
|
+
* │
|
|
162
|
+
* │ const cli = new MoostCli()
|
|
163
|
+
* │ app.adapter(cli)
|
|
164
|
+
* │ app.init()
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
25
167
|
export declare class MoostCli implements TMoostAdapter<TCliHandlerMeta> {
|
|
168
|
+
protected opts?: TMoostCliOpts | undefined;
|
|
26
169
|
protected cliApp: WooksCli;
|
|
27
|
-
|
|
28
|
-
|
|
170
|
+
protected cliHelp: CliHelpRenderer;
|
|
171
|
+
constructor(opts?: TMoostCliOpts | undefined);
|
|
172
|
+
onNotFound(): Promise<unknown>;
|
|
173
|
+
protected moost?: Moost;
|
|
174
|
+
onInit(moost: Moost): void;
|
|
29
175
|
bindHandler<T extends object = object>(opts: TMoostAdapterOptions<TCliHandlerMeta, T>): void | Promise<void>;
|
|
30
176
|
}
|
|
31
177
|
|
|
178
|
+
/**
|
|
179
|
+
* ### setCliHelpForEvent
|
|
180
|
+
* Used internally to set CliHelpRenderer instance for an event state
|
|
181
|
+
* @param cliHelp CliHelpRenderer
|
|
182
|
+
*/
|
|
183
|
+
export declare function setCliHelpForEvent(cliHelp: CliHelpRenderer): void;
|
|
184
|
+
|
|
32
185
|
export declare interface TCliHandlerMeta {
|
|
33
186
|
path: string;
|
|
34
187
|
}
|
|
35
188
|
|
|
189
|
+
export declare interface TMoostCliOpts {
|
|
190
|
+
/**
|
|
191
|
+
* WooksCli options or instance
|
|
192
|
+
*/
|
|
193
|
+
wooksCli?: WooksCli | TWooksCliOptions;
|
|
194
|
+
/**
|
|
195
|
+
* CliHelpRenderer options or instance
|
|
196
|
+
*/
|
|
197
|
+
cliHelp?: CliHelpRenderer | TCliHelpOptions;
|
|
198
|
+
/**
|
|
199
|
+
* more internal logs are printed when true
|
|
200
|
+
*/
|
|
201
|
+
debug?: boolean;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* ## useCliHelp
|
|
206
|
+
* ### Composable
|
|
207
|
+
* ```js
|
|
208
|
+
* // example of printing cli instructions
|
|
209
|
+
* const { print } = useCliHelp()
|
|
210
|
+
* print(true)
|
|
211
|
+
* ```
|
|
212
|
+
* @returns
|
|
213
|
+
*/
|
|
214
|
+
export declare function useCliHelp(): {
|
|
215
|
+
getCliHelp: () => CliHelpRenderer;
|
|
216
|
+
render: (width?: number, withColors?: boolean) => string[];
|
|
217
|
+
print: (withColors?: boolean) => void;
|
|
218
|
+
};
|
|
219
|
+
|
|
36
220
|
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,209 @@ 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
|
+
});
|
|
40
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);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
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
|
+
});
|
|
41
144
|
}
|
|
42
|
-
onInit() {
|
|
145
|
+
onInit(moost) {
|
|
146
|
+
this.moost = moost;
|
|
43
147
|
void this.cliApp.run();
|
|
44
148
|
}
|
|
45
149
|
bindHandler(opts) {
|
|
150
|
+
var _a, _b, _c;
|
|
46
151
|
let fn;
|
|
47
152
|
for (const handler of opts.handlers) {
|
|
48
153
|
if (handler.type !== 'CLI')
|
|
49
154
|
continue;
|
|
50
|
-
const path = typeof handler.path === 'string'
|
|
51
|
-
|
|
155
|
+
const path = typeof handler.path === 'string'
|
|
156
|
+
? handler.path
|
|
157
|
+
: typeof opts.method === 'string'
|
|
158
|
+
? opts.method
|
|
159
|
+
: '';
|
|
160
|
+
const targetPath = `${opts.prefix.replace(/\s+/g, '/') || ''}/${path}`
|
|
161
|
+
.replace(/\/\/+/g, '/')
|
|
162
|
+
// avoid interpreting "cmd:tail" as "cmd/:tail"
|
|
163
|
+
.replace(/\/\\:/g, '\\:');
|
|
164
|
+
let cliCommand = '';
|
|
52
165
|
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;
|
|
166
|
+
fn = defineMoostEventHandler({
|
|
167
|
+
contextType: CONTEXT_TYPE,
|
|
168
|
+
loggerTitle: LOGGER_TITLE,
|
|
169
|
+
getIterceptorHandler: opts.getIterceptorHandler,
|
|
170
|
+
getControllerInstance: opts.getInstance,
|
|
171
|
+
controllerMethod: opts.method,
|
|
172
|
+
resolveArgs: opts.resolveArgs,
|
|
173
|
+
logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
|
|
174
|
+
hooks: {
|
|
175
|
+
init: () => setCliHelpForEvent(this.cliHelp),
|
|
176
|
+
},
|
|
92
177
|
});
|
|
93
178
|
}
|
|
94
|
-
this.cliApp.cli(targetPath, fn);
|
|
95
|
-
opts.
|
|
179
|
+
const { getArgs, getStaticPart } = this.cliApp.cli(targetPath, fn);
|
|
180
|
+
const meta = getCliMate().read(opts.fakeInstance, opts.method);
|
|
181
|
+
const args = {};
|
|
182
|
+
getArgs().forEach(a => {
|
|
183
|
+
var _a;
|
|
184
|
+
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);
|
|
185
|
+
args[a] = (argParam === null || argParam === void 0 ? void 0 : argParam.description) || '';
|
|
186
|
+
});
|
|
187
|
+
cliCommand = getStaticPart().replace(/\//g, ' ').trim();
|
|
188
|
+
this.cliHelp.addEntry({
|
|
189
|
+
description: (meta === null || meta === void 0 ? void 0 : meta.description) || '',
|
|
190
|
+
command: cliCommand,
|
|
191
|
+
options: ((_b = meta === null || meta === void 0 ? void 0 : meta.params) === null || _b === void 0 ? void 0 : _b.filter(param => !!param.cliParamKeys && param.cliParamKeys.length > 0).map(param => ({
|
|
192
|
+
keys: param.cliParamKeys,
|
|
193
|
+
value: typeof param.value === 'string' ? param.value : '',
|
|
194
|
+
description: param.description || '',
|
|
195
|
+
}))) || [],
|
|
196
|
+
args,
|
|
197
|
+
aliases: meta === null || meta === void 0 ? void 0 : meta.cliAliases,
|
|
198
|
+
});
|
|
199
|
+
if ((_c = this.opts) === null || _c === void 0 ? void 0 : _c.debug) {
|
|
200
|
+
opts.logHandler(`${'[36m'}(CLI)${'[32m'}${targetPath}`);
|
|
201
|
+
}
|
|
96
202
|
}
|
|
97
203
|
}
|
|
98
204
|
}
|
|
99
205
|
|
|
100
|
-
function
|
|
101
|
-
|
|
206
|
+
function formatParams(keys) {
|
|
207
|
+
const names = [keys].flat();
|
|
208
|
+
return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
|
|
102
209
|
}
|
|
103
210
|
|
|
104
211
|
/**
|
|
105
|
-
*
|
|
106
|
-
* @
|
|
107
|
-
* @
|
|
108
|
-
*
|
|
212
|
+
* ## Define CLI Option
|
|
213
|
+
* ### @ParameterDecorator
|
|
214
|
+
* Use together with @Description('...') to document cli option
|
|
215
|
+
*
|
|
216
|
+
* ```ts
|
|
217
|
+
* │ @Cli('command')
|
|
218
|
+
* │ command(
|
|
219
|
+
* │ @Description('Test flag...')
|
|
220
|
+
* │ @CliOption('test', 't')
|
|
221
|
+
* │ test: boolean,
|
|
222
|
+
* │ ) {
|
|
223
|
+
* │ return `test=${ test }`
|
|
224
|
+
* │ }
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
227
|
+
* @param keys list of keys (short and long alternatives)
|
|
228
|
+
* @returns
|
|
109
229
|
*/
|
|
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) {
|
|
230
|
+
function CliOption(...keys) {
|
|
126
231
|
const mate = getCliMate();
|
|
127
|
-
return mate.apply(mate.decorate('
|
|
232
|
+
return mate.apply(mate.decorate('cliParamKeys', keys, false), Resolve(() => {
|
|
128
233
|
const flags = useFlags();
|
|
129
|
-
const names =
|
|
234
|
+
const names = keys;
|
|
130
235
|
const vals = [];
|
|
131
236
|
for (const name of names) {
|
|
132
237
|
if (flags[name]) {
|
|
@@ -143,8 +248,114 @@ function CliParam(keys, descr) {
|
|
|
143
248
|
}, formatParams(keys).join(', ')));
|
|
144
249
|
}
|
|
145
250
|
|
|
251
|
+
/**
|
|
252
|
+
* ## Define CLI Command
|
|
253
|
+
* ### @MethodDecorator
|
|
254
|
+
*
|
|
255
|
+
* Command path segments may be separated by / or space.
|
|
256
|
+
*
|
|
257
|
+
* For example the folowing path are interpreted the same:
|
|
258
|
+
* - "command test use:dev :name"
|
|
259
|
+
* - "command/test/use:dev/:name"
|
|
260
|
+
* Where name will become an argument
|
|
261
|
+
*
|
|
262
|
+
* @param path - command path
|
|
263
|
+
* @returns
|
|
264
|
+
*/
|
|
146
265
|
function Cli(path) {
|
|
147
|
-
return getCliMate().decorate('handlers', { path, type: 'CLI' }, true);
|
|
266
|
+
return getCliMate().decorate('handlers', { path: path === null || path === void 0 ? void 0 : path.replace(/\s+/g, '/'), type: 'CLI' }, true);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* ## Define CLI Command Alias
|
|
270
|
+
* ### @MethodDecorator
|
|
271
|
+
*
|
|
272
|
+
* Use it to define alias for @Cli('...') command
|
|
273
|
+
*
|
|
274
|
+
* @param path - command alias path
|
|
275
|
+
* @returns
|
|
276
|
+
*/
|
|
277
|
+
function CliAlias(alias) {
|
|
278
|
+
return getCliMate().decorate('cliAliases', alias, true);
|
|
148
279
|
}
|
|
149
280
|
|
|
150
|
-
|
|
281
|
+
/**
|
|
282
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
283
|
+
*
|
|
284
|
+
* By default intercepts cli calls with flag --help
|
|
285
|
+
* and prints help.
|
|
286
|
+
*
|
|
287
|
+
* ```js
|
|
288
|
+
* new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
|
|
289
|
+
* ```
|
|
290
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
291
|
+
* @returns TInterceptorFn
|
|
292
|
+
*/
|
|
293
|
+
const cliHelpInterceptor = (opts) => {
|
|
294
|
+
return defineInterceptorFn(() => {
|
|
295
|
+
const helpOptions = (opts === null || opts === void 0 ? void 0 : opts.helpOptions) || ['help'];
|
|
296
|
+
for (const option of helpOptions) {
|
|
297
|
+
if (useFlag(option) === true) {
|
|
298
|
+
try {
|
|
299
|
+
useCliHelp().print(opts === null || opts === void 0 ? void 0 : opts.colors);
|
|
300
|
+
return '';
|
|
301
|
+
}
|
|
302
|
+
catch (e) {
|
|
303
|
+
//
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) || (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd)) {
|
|
308
|
+
const { getMethod } = useControllerContext();
|
|
309
|
+
if (!getMethod()) {
|
|
310
|
+
const pathParams = useCliContext().store('event').get('pathParams').join(' ');
|
|
311
|
+
const cliHelp = useCliHelp().getCliHelp();
|
|
312
|
+
const cmd = cliHelp.getCliName();
|
|
313
|
+
let data;
|
|
314
|
+
try {
|
|
315
|
+
data = cliHelp.match(pathParams);
|
|
316
|
+
}
|
|
317
|
+
catch (e) {
|
|
318
|
+
if (opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) {
|
|
319
|
+
const variants = cliHelp.lookup(pathParams);
|
|
320
|
+
if (variants.length) {
|
|
321
|
+
throw new Error(`Command is incomplete, did you mean:\n${variants.slice(0, 7).map(c => ` $ ${cmd} ${c.main.command}`).join('\n')}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (data) {
|
|
326
|
+
const { main, children } = data;
|
|
327
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.helpWithArgs) && main.args && Object.keys(main.args).length) {
|
|
328
|
+
throw new Error(`Arguments expected: ${Object.keys(main.args).map(l => `<${l}>`).join(', ')}`);
|
|
329
|
+
}
|
|
330
|
+
else if ((opts === null || opts === void 0 ? void 0 : opts.helpWithIncompleteCmd) && children) {
|
|
331
|
+
throw new Error(`Command is incomplete, did you mean:\n${children.slice(0, 7).map(c => ` $ ${cmd} ${c.command}`).join('\n')}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}, TInterceptorPriority.BEFORE_ALL);
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* ## @Decorator
|
|
340
|
+
* ### Interceptor Factory for CliHelpRenderer
|
|
341
|
+
*
|
|
342
|
+
* By default intercepts cli calls with flag --help
|
|
343
|
+
* and prints help.
|
|
344
|
+
*
|
|
345
|
+
* ```ts
|
|
346
|
+
* // default configuration
|
|
347
|
+
* • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
|
|
348
|
+
*
|
|
349
|
+
* // additional option -h to invoke help renderer
|
|
350
|
+
* • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
|
|
351
|
+
*
|
|
352
|
+
* // redefine cli option to invoke help renderer
|
|
353
|
+
* • @CliHelpInterceptor({ helpOptions: ['usage'] })
|
|
354
|
+
* ```
|
|
355
|
+
*
|
|
356
|
+
* @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
|
|
357
|
+
* @returns Decorator
|
|
358
|
+
*/
|
|
359
|
+
const CliHelpInterceptor = (...opts) => Intercept(cliHelpInterceptor(...opts));
|
|
360
|
+
|
|
361
|
+
export { Cli, CliAlias, 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.28",
|
|
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.28",
|
|
32
|
+
"wooks": "^0.2.22",
|
|
33
|
+
"@wooksjs/event-core": "^0.2.22"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@wooksjs/event-cli": "^0.2.
|
|
36
|
+
"@wooksjs/event-cli": "^0.2.22",
|
|
37
|
+
"@prostojs/cli-help": "^0.0.7"
|
|
37
38
|
}
|
|
38
39
|
}
|