@moostjs/event-cli 0.3.10 → 0.3.11

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.
Files changed (3) hide show
  1. package/dist/index.cjs +289 -317
  2. package/dist/index.mjs +288 -316
  3. package/package.json +5 -5
package/dist/index.cjs CHANGED
@@ -3,336 +3,308 @@
3
3
  var moost = require('moost');
4
4
  var eventCli = require('@wooksjs/event-cli');
5
5
 
6
- /******************************************************************************
7
- Copyright (c) Microsoft Corporation.
8
-
9
- Permission to use, copy, modify, and/or distribute this software for any
10
- purpose with or without fee is hereby granted.
11
-
12
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
14
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
- PERFORMANCE OF THIS SOFTWARE.
19
- ***************************************************************************** */
20
- /* global Reflect, Promise */
21
-
22
-
23
- function __awaiter(thisArg, _arguments, P, generator) {
24
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
25
- return new (P || (P = Promise))(function (resolve, reject) {
26
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
27
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
28
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
29
- step((generator = generator.apply(thisArg, _arguments || [])).next());
30
- });
6
+ function getCliMate() {
7
+ return moost.getMoostMate();
31
8
  }
32
9
 
33
- function getCliMate() {
34
- return moost.getMoostMate();
10
+ const LOGGER_TITLE = 'moost-cli';
11
+ const CONTEXT_TYPE = 'CLI';
12
+ /**
13
+ * ## Moost Cli Adapter
14
+ *
15
+ * Moost Adapter for CLI events
16
+ *
17
+ * ```ts
18
+ * │ // Quick example
19
+ * │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
20
+ * │ import { Moost, Param } from 'moost'
21
+ * │
22
+ * │ class MyApp extends Moost {
23
+ * │ @Cli('command/:arg')
24
+ * │ command(
25
+ * │ @Param('arg')
26
+ * │ arg: string,
27
+ * │ @CliOption('test', 't')
28
+ * │ test: boolean,
29
+ * │ ) {
30
+ * │ return `command run with flag arg=${ arg }, test=${ test }`
31
+ * │ }
32
+ * │ }
33
+ * │
34
+ * │ const app = new MyApp()
35
+ * │ app.applyGlobalInterceptors(cliHelpInterceptor())
36
+ * │
37
+ * │ const cli = new MoostCli()
38
+ * │ app.adapter(cli)
39
+ * │ app.init()
40
+ * ```
41
+ */
42
+ class MoostCli {
43
+ constructor(opts) {
44
+ this.opts = opts;
45
+ this.optionTypes = {};
46
+ const cliAppOpts = opts?.wooksCli;
47
+ if (cliAppOpts && cliAppOpts instanceof eventCli.WooksCli) {
48
+ this.cliApp = cliAppOpts;
49
+ }
50
+ else if (cliAppOpts) {
51
+ this.cliApp = eventCli.createCliApp({
52
+ ...cliAppOpts,
53
+ onNotFound: this.onNotFound.bind(this),
54
+ });
55
+ }
56
+ else {
57
+ this.cliApp = eventCli.createCliApp({
58
+ onNotFound: this.onNotFound.bind(this),
59
+ });
60
+ }
61
+ if (!opts?.debug) {
62
+ moost.getMoostInfact().silent(true);
63
+ }
64
+ }
65
+ async onNotFound() {
66
+ const pathParams = eventCli.useCliContext().store('event').get('pathParams');
67
+ const response = await moost.defineMoostEventHandler({
68
+ loggerTitle: LOGGER_TITLE,
69
+ getIterceptorHandler: () => this.moost?.getGlobalInterceptorHandler(),
70
+ getControllerInstance: () => this.moost,
71
+ callControllerMethod: () => undefined,
72
+ logErrors: this.opts?.debug,
73
+ })();
74
+ if (typeof response === 'undefined') {
75
+ this.cliApp.onUnknownCommand(pathParams);
76
+ }
77
+ return response;
78
+ }
79
+ onInit(moost) {
80
+ this.moost = moost;
81
+ const boolean = Object
82
+ .entries(this.optionTypes)
83
+ .filter(([_key, val]) => val.length === 1 && val[0] === Boolean)
84
+ .map(([key, _val]) => key);
85
+ void this.cliApp.run(undefined, {
86
+ boolean,
87
+ });
88
+ }
89
+ bindHandler(opts) {
90
+ let fn;
91
+ for (const handler of opts.handlers) {
92
+ if (handler.type !== 'CLI')
93
+ continue;
94
+ const path = typeof handler.path === 'string'
95
+ ? handler.path
96
+ : typeof opts.method === 'string'
97
+ ? opts.method
98
+ : '';
99
+ const prefix = opts.prefix.replace(/\s+/g, '/') || '';
100
+ const makePath = (p) => `${prefix}/${p}`
101
+ .replace(/\/\/+/g, '/')
102
+ // avoid interpreting "cmd:tail" as "cmd/:tail"
103
+ .replace(/\/\\:/g, '\\:')
104
+ .replace(/^\/+/g, '');
105
+ if (!fn) {
106
+ fn = moost.defineMoostEventHandler({
107
+ contextType: CONTEXT_TYPE,
108
+ loggerTitle: LOGGER_TITLE,
109
+ getIterceptorHandler: opts.getIterceptorHandler,
110
+ getControllerInstance: opts.getInstance,
111
+ controllerMethod: opts.method,
112
+ resolveArgs: opts.resolveArgs,
113
+ logErrors: this.opts?.debug,
114
+ });
115
+ }
116
+ const targetPath = makePath(path);
117
+ const meta = getCliMate().read(opts.fakeInstance, opts.method);
118
+ const classMeta = getCliMate().read(opts.fakeInstance);
119
+ const cliOptions = new Map();
120
+ [
121
+ ...(this.opts?.globalCliOptions?.length ? this.opts.globalCliOptions : []),
122
+ ...(classMeta?.cliOptions || []),
123
+ ...(meta?.params ? meta.params.filter((param) => param.cliOptionsKeys?.length > 0).map((param) => ({
124
+ keys: param.cliOptionsKeys,
125
+ value: typeof param.value === 'string' ? param.value : '',
126
+ description: param.description || '',
127
+ type: param.type,
128
+ })) : []),
129
+ ].forEach(o => cliOptions.set(o.keys[0], o));
130
+ const aliases = [];
131
+ if (meta?.cliAliases) {
132
+ for (const alias of meta.cliAliases) {
133
+ const targetPath = makePath(alias);
134
+ aliases.push(targetPath);
135
+ }
136
+ }
137
+ const cliOptionsArray = Array.from(cliOptions.values());
138
+ cliOptionsArray.forEach(o => {
139
+ for (const key of o.keys) {
140
+ if (!this.optionTypes[key]) {
141
+ this.optionTypes[key] = [];
142
+ }
143
+ if (!(this.optionTypes[key].includes(o.type))) {
144
+ this.optionTypes[key].push(o.type);
145
+ }
146
+ }
147
+ });
148
+ const args = {};
149
+ meta?.params?.filter(p => p.paramSource === 'ROUTE' && p.description)
150
+ .forEach(p => args[p.paramName] = p.description);
151
+ const routerBinding = this.cliApp.cli(targetPath, {
152
+ description: meta?.description || '',
153
+ options: cliOptionsArray,
154
+ args,
155
+ aliases,
156
+ examples: meta?.cliExamples || [],
157
+ handler: fn,
158
+ onRegister: (path, aliasType, route) => {
159
+ opts.register(handler, path, route?.getArgs() || routerBinding.getArgs());
160
+ if (this.opts?.debug) {
161
+ opts.logHandler(`${''}(${aliasTypes[aliasType]})${''}${path}`);
162
+ }
163
+ },
164
+ });
165
+ opts.register(handler, targetPath, routerBinding.getArgs());
166
+ }
167
+ }
35
168
  }
36
-
37
- const LOGGER_TITLE = 'moost-cli';
38
- const CONTEXT_TYPE = 'CLI';
39
- /**
40
- * ## Moost Cli Adapter
41
- *
42
- * Moost Adapter for CLI events
43
- *
44
- * ```ts
45
- * │ // Quick example
46
- * │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
47
- * │ import { Moost, Param } from 'moost'
48
- * │
49
- * │ class MyApp extends Moost {
50
- * │ @Cli('command/:arg')
51
- * │ command(
52
- * │ @Param('arg')
53
- * │ arg: string,
54
- * │ @CliOption('test', 't')
55
- * │ test: boolean,
56
- * │ ) {
57
- * │ return `command run with flag arg=${ arg }, test=${ test }`
58
- * │ }
59
- * │ }
60
- * │
61
- * │ const app = new MyApp()
62
- * │ app.applyGlobalInterceptors(cliHelpInterceptor())
63
- * │
64
- * │ const cli = new MoostCli()
65
- * │ app.adapter(cli)
66
- * │ app.init()
67
- * ```
68
- */
69
- class MoostCli {
70
- constructor(opts) {
71
- this.opts = opts;
72
- this.optionTypes = {};
73
- const cliAppOpts = opts === null || opts === void 0 ? void 0 : opts.wooksCli;
74
- if (cliAppOpts && cliAppOpts instanceof eventCli.WooksCli) {
75
- this.cliApp = cliAppOpts;
76
- }
77
- else if (cliAppOpts) {
78
- this.cliApp = eventCli.createCliApp(Object.assign(Object.assign({}, cliAppOpts), { onNotFound: this.onNotFound.bind(this) }));
79
- }
80
- else {
81
- this.cliApp = eventCli.createCliApp({
82
- onNotFound: this.onNotFound.bind(this),
83
- });
84
- }
85
- if (!(opts === null || opts === void 0 ? void 0 : opts.debug)) {
86
- moost.getMoostInfact().silent(true);
87
- }
88
- }
89
- onNotFound() {
90
- var _a;
91
- return __awaiter(this, void 0, void 0, function* () {
92
- const pathParams = eventCli.useCliContext().store('event').get('pathParams');
93
- const response = yield moost.defineMoostEventHandler({
94
- loggerTitle: LOGGER_TITLE,
95
- getIterceptorHandler: () => { var _a; return (_a = this.moost) === null || _a === void 0 ? void 0 : _a.getGlobalInterceptorHandler(); },
96
- getControllerInstance: () => this.moost,
97
- callControllerMethod: () => undefined,
98
- logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
99
- })();
100
- if (typeof response === 'undefined') {
101
- this.cliApp.onUnknownCommand(pathParams);
102
- }
103
- return response;
104
- });
105
- }
106
- onInit(moost) {
107
- this.moost = moost;
108
- const boolean = Object
109
- .entries(this.optionTypes)
110
- .filter(([_key, val]) => val.length === 1 && val[0] === Boolean)
111
- .map(([key, _val]) => key);
112
- void this.cliApp.run(undefined, {
113
- boolean,
114
- });
115
- }
116
- bindHandler(opts) {
117
- var _a, _b, _c, _d;
118
- let fn;
119
- for (const handler of opts.handlers) {
120
- if (handler.type !== 'CLI')
121
- continue;
122
- const path = typeof handler.path === 'string'
123
- ? handler.path
124
- : typeof opts.method === 'string'
125
- ? opts.method
126
- : '';
127
- const prefix = opts.prefix.replace(/\s+/g, '/') || '';
128
- const makePath = (p) => `${prefix}/${p}`
129
- .replace(/\/\/+/g, '/')
130
- // avoid interpreting "cmd:tail" as "cmd/:tail"
131
- .replace(/\/\\:/g, '\\:')
132
- .replace(/^\/+/g, '');
133
- if (!fn) {
134
- fn = moost.defineMoostEventHandler({
135
- contextType: CONTEXT_TYPE,
136
- loggerTitle: LOGGER_TITLE,
137
- getIterceptorHandler: opts.getIterceptorHandler,
138
- getControllerInstance: opts.getInstance,
139
- controllerMethod: opts.method,
140
- resolveArgs: opts.resolveArgs,
141
- logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
142
- });
143
- }
144
- const targetPath = makePath(path);
145
- const meta = getCliMate().read(opts.fakeInstance, opts.method);
146
- const classMeta = getCliMate().read(opts.fakeInstance);
147
- const cliOptions = new Map();
148
- [
149
- ...(((_c = (_b = this.opts) === null || _b === void 0 ? void 0 : _b.globalCliOptions) === null || _c === void 0 ? void 0 : _c.length) ? this.opts.globalCliOptions : []),
150
- ...((classMeta === null || classMeta === void 0 ? void 0 : classMeta.cliOptions) || []),
151
- ...((meta === null || meta === void 0 ? void 0 : meta.params) ? meta.params.filter((param) => { var _a; return ((_a = param.cliOptionsKeys) === null || _a === void 0 ? void 0 : _a.length) > 0; }).map((param) => ({
152
- keys: param.cliOptionsKeys,
153
- value: typeof param.value === 'string' ? param.value : '',
154
- description: param.description || '',
155
- type: param.type,
156
- })) : []),
157
- ].forEach(o => cliOptions.set(o.keys[0], o));
158
- const aliases = [];
159
- if (meta === null || meta === void 0 ? void 0 : meta.cliAliases) {
160
- for (const alias of meta.cliAliases) {
161
- const targetPath = makePath(alias);
162
- aliases.push(targetPath);
163
- }
164
- }
165
- const cliOptionsArray = Array.from(cliOptions.values());
166
- cliOptionsArray.forEach(o => {
167
- for (const key of o.keys) {
168
- if (!this.optionTypes[key]) {
169
- this.optionTypes[key] = [];
170
- }
171
- if (!(this.optionTypes[key].includes(o.type))) {
172
- this.optionTypes[key].push(o.type);
173
- }
174
- }
175
- });
176
- const args = {};
177
- (_d = meta === null || meta === void 0 ? void 0 : meta.params) === null || _d === void 0 ? void 0 : _d.filter(p => p.paramSource === 'ROUTE' && p.description).forEach(p => args[p.paramName] = p.description);
178
- const routerBinding = this.cliApp.cli(targetPath, {
179
- description: (meta === null || meta === void 0 ? void 0 : meta.description) || '',
180
- options: cliOptionsArray,
181
- args,
182
- aliases,
183
- examples: (meta === null || meta === void 0 ? void 0 : meta.cliExamples) || [],
184
- handler: fn,
185
- onRegister: (path, aliasType, route) => {
186
- var _a;
187
- opts.register(handler, path, (route === null || route === void 0 ? void 0 : route.getArgs()) || routerBinding.getArgs());
188
- if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug) {
189
- opts.logHandler(`${''}(${aliasTypes[aliasType]})${''}${path}`);
190
- }
191
- },
192
- });
193
- opts.register(handler, targetPath, routerBinding.getArgs());
194
- }
195
- }
196
- }
197
169
  const aliasTypes = ['CLI', 'CLI-alias', 'CLI-alias*', 'CLI-alias*'];
198
170
 
199
- function formatParams(keys) {
200
- const names = [keys].flat();
201
- return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
171
+ function formatParams(keys) {
172
+ const names = [keys].flat();
173
+ return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
202
174
  }
203
175
 
204
- /**
205
- * ## Define CLI Option
206
- * ### @ParameterDecorator
207
- * Use together with @Description('...') to document cli option
208
- *
209
- * ```ts
210
- * │ @Cli('command')
211
- * │ command(
212
- * │ @Description('Test option...')
213
- * │ @CliOption('test', 't')
214
- * │ test: boolean,
215
- * │ ) {
216
- * │ return `test=${ test }`
217
- * │ }
218
- * ```
219
- *
220
- * @param keys list of keys (short and long alternatives)
221
- * @returns
222
- */
223
- function CliOption(...keys) {
224
- const mate = getCliMate();
225
- return mate.apply(mate.decorate('cliOptionsKeys', keys, false), moost.Resolve(() => eventCli.useCliOption(keys[0]), formatParams(keys).join(', ')));
226
- }
227
- /**
228
- * ## Define Global CLI Option
229
- * ### @ClassDecorator
230
- * The option described here will appear in every command instructions
231
- * @param option keys and description of CLI option
232
- * @returns
233
- */
234
- function CliGlobalOption(option) {
235
- const mate = getCliMate();
236
- return mate.decorate('cliOptions', option, true);
176
+ /**
177
+ * ## Define CLI Option
178
+ * ### @ParameterDecorator
179
+ * Use together with @Description('...') to document cli option
180
+ *
181
+ * ```ts
182
+ * │ @Cli('command')
183
+ * │ command(
184
+ * │ @Description('Test option...')
185
+ * │ @CliOption('test', 't')
186
+ * │ test: boolean,
187
+ * │ ) {
188
+ * │ return `test=${ test }`
189
+ * │ }
190
+ * ```
191
+ *
192
+ * @param keys list of keys (short and long alternatives)
193
+ * @returns
194
+ */
195
+ function CliOption(...keys) {
196
+ const mate = getCliMate();
197
+ return mate.apply(mate.decorate('cliOptionsKeys', keys, false), moost.Resolve(() => eventCli.useCliOption(keys[0]), formatParams(keys).join(', ')));
198
+ }
199
+ /**
200
+ * ## Define Global CLI Option
201
+ * ### @ClassDecorator
202
+ * The option described here will appear in every command instructions
203
+ * @param option keys and description of CLI option
204
+ * @returns
205
+ */
206
+ function CliGlobalOption(option) {
207
+ const mate = getCliMate();
208
+ return mate.decorate('cliOptions', option, true);
237
209
  }
238
210
 
239
- /**
240
- * ## Define CLI Command
241
- * ### @MethodDecorator
242
- *
243
- * Command path segments may be separated by / or space.
244
- *
245
- * For example the folowing path are interpreted the same:
246
- * - "command test use:dev :name"
247
- * - "command/test/use:dev/:name"
248
- *
249
- * Where name will become an argument
250
- *
251
- * @param path - command path
252
- * @returns
253
- */
254
- function Cli(path) {
255
- return getCliMate().decorate('handlers', { path: path === null || path === void 0 ? void 0 : path.replace(/\s+/g, '/'), type: 'CLI' }, true);
256
- }
257
- /**
258
- * ## Define CLI Command Alias
259
- * ### @MethodDecorator
260
- *
261
- * Use it to define alias for @Cli('...') command
262
- *
263
- * @param path - command alias path
264
- * @returns
265
- */
266
- function CliAlias(alias) {
267
- return getCliMate().decorate('cliAliases', alias, true);
268
- }
269
- /**
270
- * ## Define CLI Example
271
- * ### @MethodDecorator
272
- *
273
- * Use it to define example for Cli Help display
274
- *
275
- * @param path - command alias path
276
- * @returns
277
- */
278
- function CliExample(cmd, description) {
279
- return getCliMate().decorate('cliExamples', { cmd, description }, true);
211
+ /**
212
+ * ## Define CLI Command
213
+ * ### @MethodDecorator
214
+ *
215
+ * Command path segments may be separated by / or space.
216
+ *
217
+ * For example the folowing path are interpreted the same:
218
+ * - "command test use:dev :name"
219
+ * - "command/test/use:dev/:name"
220
+ *
221
+ * Where name will become an argument
222
+ *
223
+ * @param path - command path
224
+ * @returns
225
+ */
226
+ function Cli(path) {
227
+ return getCliMate().decorate('handlers', { path: path?.replace(/\s+/g, '/'), type: 'CLI' }, true);
228
+ }
229
+ /**
230
+ * ## Define CLI Command Alias
231
+ * ### @MethodDecorator
232
+ *
233
+ * Use it to define alias for @Cli('...') command
234
+ *
235
+ * @param path - command alias path
236
+ * @returns
237
+ */
238
+ function CliAlias(alias) {
239
+ return getCliMate().decorate('cliAliases', alias, true);
240
+ }
241
+ /**
242
+ * ## Define CLI Example
243
+ * ### @MethodDecorator
244
+ *
245
+ * Use it to define example for Cli Help display
246
+ *
247
+ * @param path - command alias path
248
+ * @returns
249
+ */
250
+ function CliExample(cmd, description) {
251
+ return getCliMate().decorate('cliExamples', { cmd, description }, true);
280
252
  }
281
253
 
282
- /**
283
- * ### Interceptor Factory for CliHelpRenderer
284
- *
285
- * By default intercepts cli calls with flag --help
286
- * and prints help.
287
- *
288
- * ```js
289
- * new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
290
- * ```
291
- * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
292
- * @returns TInterceptorFn
293
- */
294
- const cliHelpInterceptor = (opts) => {
295
- return moost.defineInterceptorFn(() => {
296
- try {
297
- if (eventCli.useAutoHelp(opts === null || opts === void 0 ? void 0 : opts.helpOptions, opts === null || opts === void 0 ? void 0 : opts.colors)) {
298
- return '';
299
- }
300
- }
301
- catch (e) {
302
- //
303
- }
304
- if (opts === null || opts === void 0 ? void 0 : opts.lookupLevel) {
305
- const { getMethod } = moost.useControllerContext();
306
- if (!getMethod()) {
307
- eventCli.useCommandLookupHelp(opts.lookupLevel);
308
- }
309
- }
310
- }, moost.TInterceptorPriority.BEFORE_ALL);
311
- };
312
- /**
313
- * ## @Decorator
314
- * ### Interceptor Factory for CliHelpRenderer
315
- *
316
- * By default intercepts cli calls with flag --help
317
- * and prints help.
318
- *
319
- * ```ts
320
- * // default configuration
321
- * • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
322
- *
323
- * // additional option -h to invoke help renderer
324
- * • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
325
- *
326
- * // redefine cli option to invoke help renderer
327
- * • @CliHelpInterceptor({ helpOptions: ['usage'] })
328
- * ```
329
- *
330
- * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
331
- * @returns Decorator
332
- */
254
+ /**
255
+ * ### Interceptor Factory for CliHelpRenderer
256
+ *
257
+ * By default intercepts cli calls with flag --help
258
+ * and prints help.
259
+ *
260
+ * ```js
261
+ * new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
262
+ * ```
263
+ * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
264
+ * @returns TInterceptorFn
265
+ */
266
+ const cliHelpInterceptor = (opts) => {
267
+ return moost.defineInterceptorFn(() => {
268
+ try {
269
+ if (eventCli.useAutoHelp(opts?.helpOptions, opts?.colors)) {
270
+ return '';
271
+ }
272
+ }
273
+ catch (e) {
274
+ //
275
+ }
276
+ if (opts?.lookupLevel) {
277
+ const { getMethod } = moost.useControllerContext();
278
+ if (!getMethod()) {
279
+ eventCli.useCommandLookupHelp(opts.lookupLevel);
280
+ }
281
+ }
282
+ }, moost.TInterceptorPriority.BEFORE_ALL);
283
+ };
284
+ /**
285
+ * ## @Decorator
286
+ * ### Interceptor Factory for CliHelpRenderer
287
+ *
288
+ * By default intercepts cli calls with flag --help
289
+ * and prints help.
290
+ *
291
+ * ```ts
292
+ * // default configuration
293
+ * • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
294
+ *
295
+ * // additional option -h to invoke help renderer
296
+ * • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
297
+ *
298
+ * // redefine cli option to invoke help renderer
299
+ * • @CliHelpInterceptor({ helpOptions: ['usage'] })
300
+ * ```
301
+ *
302
+ * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
303
+ * @returns Decorator
304
+ */
333
305
  const CliHelpInterceptor = (...opts) => moost.Intercept(cliHelpInterceptor(...opts));
334
306
 
335
- Object.defineProperty(exports, 'useCliContext', {
307
+ Object.defineProperty(exports, "useCliContext", {
336
308
  enumerable: true,
337
309
  get: function () { return eventCli.useCliContext; }
338
310
  });
package/dist/index.mjs CHANGED
@@ -2,333 +2,305 @@ import { getMoostMate, getMoostInfact, defineMoostEventHandler, Resolve, defineI
2
2
  import { WooksCli, createCliApp, useCliContext, useCliOption, useAutoHelp, useCommandLookupHelp } from '@wooksjs/event-cli';
3
3
  export { useCliContext } from '@wooksjs/event-cli';
4
4
 
5
- /******************************************************************************
6
- Copyright (c) Microsoft Corporation.
7
-
8
- Permission to use, copy, modify, and/or distribute this software for any
9
- purpose with or without fee is hereby granted.
10
-
11
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
- PERFORMANCE OF THIS SOFTWARE.
18
- ***************************************************************************** */
19
- /* global Reflect, Promise */
20
-
21
-
22
- function __awaiter(thisArg, _arguments, P, generator) {
23
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
24
- return new (P || (P = Promise))(function (resolve, reject) {
25
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
26
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
27
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
28
- step((generator = generator.apply(thisArg, _arguments || [])).next());
29
- });
5
+ function getCliMate() {
6
+ return getMoostMate();
30
7
  }
31
8
 
32
- function getCliMate() {
33
- return getMoostMate();
9
+ const LOGGER_TITLE = 'moost-cli';
10
+ const CONTEXT_TYPE = 'CLI';
11
+ /**
12
+ * ## Moost Cli Adapter
13
+ *
14
+ * Moost Adapter for CLI events
15
+ *
16
+ * ```ts
17
+ * │ // Quick example
18
+ * │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
19
+ * │ import { Moost, Param } from 'moost'
20
+ * │
21
+ * │ class MyApp extends Moost {
22
+ * │ @Cli('command/:arg')
23
+ * │ command(
24
+ * │ @Param('arg')
25
+ * │ arg: string,
26
+ * │ @CliOption('test', 't')
27
+ * │ test: boolean,
28
+ * │ ) {
29
+ * │ return `command run with flag arg=${ arg }, test=${ test }`
30
+ * │ }
31
+ * │ }
32
+ * │
33
+ * │ const app = new MyApp()
34
+ * │ app.applyGlobalInterceptors(cliHelpInterceptor())
35
+ * │
36
+ * │ const cli = new MoostCli()
37
+ * │ app.adapter(cli)
38
+ * │ app.init()
39
+ * ```
40
+ */
41
+ class MoostCli {
42
+ constructor(opts) {
43
+ this.opts = opts;
44
+ this.optionTypes = {};
45
+ const cliAppOpts = opts?.wooksCli;
46
+ if (cliAppOpts && cliAppOpts instanceof WooksCli) {
47
+ this.cliApp = cliAppOpts;
48
+ }
49
+ else if (cliAppOpts) {
50
+ this.cliApp = createCliApp({
51
+ ...cliAppOpts,
52
+ onNotFound: this.onNotFound.bind(this),
53
+ });
54
+ }
55
+ else {
56
+ this.cliApp = createCliApp({
57
+ onNotFound: this.onNotFound.bind(this),
58
+ });
59
+ }
60
+ if (!opts?.debug) {
61
+ getMoostInfact().silent(true);
62
+ }
63
+ }
64
+ async onNotFound() {
65
+ const pathParams = useCliContext().store('event').get('pathParams');
66
+ const response = await defineMoostEventHandler({
67
+ loggerTitle: LOGGER_TITLE,
68
+ getIterceptorHandler: () => this.moost?.getGlobalInterceptorHandler(),
69
+ getControllerInstance: () => this.moost,
70
+ callControllerMethod: () => undefined,
71
+ logErrors: this.opts?.debug,
72
+ })();
73
+ if (typeof response === 'undefined') {
74
+ this.cliApp.onUnknownCommand(pathParams);
75
+ }
76
+ return response;
77
+ }
78
+ onInit(moost) {
79
+ this.moost = moost;
80
+ const boolean = Object
81
+ .entries(this.optionTypes)
82
+ .filter(([_key, val]) => val.length === 1 && val[0] === Boolean)
83
+ .map(([key, _val]) => key);
84
+ void this.cliApp.run(undefined, {
85
+ boolean,
86
+ });
87
+ }
88
+ bindHandler(opts) {
89
+ let fn;
90
+ for (const handler of opts.handlers) {
91
+ if (handler.type !== 'CLI')
92
+ continue;
93
+ const path = typeof handler.path === 'string'
94
+ ? handler.path
95
+ : typeof opts.method === 'string'
96
+ ? opts.method
97
+ : '';
98
+ const prefix = opts.prefix.replace(/\s+/g, '/') || '';
99
+ const makePath = (p) => `${prefix}/${p}`
100
+ .replace(/\/\/+/g, '/')
101
+ // avoid interpreting "cmd:tail" as "cmd/:tail"
102
+ .replace(/\/\\:/g, '\\:')
103
+ .replace(/^\/+/g, '');
104
+ if (!fn) {
105
+ fn = defineMoostEventHandler({
106
+ contextType: CONTEXT_TYPE,
107
+ loggerTitle: LOGGER_TITLE,
108
+ getIterceptorHandler: opts.getIterceptorHandler,
109
+ getControllerInstance: opts.getInstance,
110
+ controllerMethod: opts.method,
111
+ resolveArgs: opts.resolveArgs,
112
+ logErrors: this.opts?.debug,
113
+ });
114
+ }
115
+ const targetPath = makePath(path);
116
+ const meta = getCliMate().read(opts.fakeInstance, opts.method);
117
+ const classMeta = getCliMate().read(opts.fakeInstance);
118
+ const cliOptions = new Map();
119
+ [
120
+ ...(this.opts?.globalCliOptions?.length ? this.opts.globalCliOptions : []),
121
+ ...(classMeta?.cliOptions || []),
122
+ ...(meta?.params ? meta.params.filter((param) => param.cliOptionsKeys?.length > 0).map((param) => ({
123
+ keys: param.cliOptionsKeys,
124
+ value: typeof param.value === 'string' ? param.value : '',
125
+ description: param.description || '',
126
+ type: param.type,
127
+ })) : []),
128
+ ].forEach(o => cliOptions.set(o.keys[0], o));
129
+ const aliases = [];
130
+ if (meta?.cliAliases) {
131
+ for (const alias of meta.cliAliases) {
132
+ const targetPath = makePath(alias);
133
+ aliases.push(targetPath);
134
+ }
135
+ }
136
+ const cliOptionsArray = Array.from(cliOptions.values());
137
+ cliOptionsArray.forEach(o => {
138
+ for (const key of o.keys) {
139
+ if (!this.optionTypes[key]) {
140
+ this.optionTypes[key] = [];
141
+ }
142
+ if (!(this.optionTypes[key].includes(o.type))) {
143
+ this.optionTypes[key].push(o.type);
144
+ }
145
+ }
146
+ });
147
+ const args = {};
148
+ meta?.params?.filter(p => p.paramSource === 'ROUTE' && p.description)
149
+ .forEach(p => args[p.paramName] = p.description);
150
+ const routerBinding = this.cliApp.cli(targetPath, {
151
+ description: meta?.description || '',
152
+ options: cliOptionsArray,
153
+ args,
154
+ aliases,
155
+ examples: meta?.cliExamples || [],
156
+ handler: fn,
157
+ onRegister: (path, aliasType, route) => {
158
+ opts.register(handler, path, route?.getArgs() || routerBinding.getArgs());
159
+ if (this.opts?.debug) {
160
+ opts.logHandler(`${''}(${aliasTypes[aliasType]})${''}${path}`);
161
+ }
162
+ },
163
+ });
164
+ opts.register(handler, targetPath, routerBinding.getArgs());
165
+ }
166
+ }
34
167
  }
35
-
36
- const LOGGER_TITLE = 'moost-cli';
37
- const CONTEXT_TYPE = 'CLI';
38
- /**
39
- * ## Moost Cli Adapter
40
- *
41
- * Moost Adapter for CLI events
42
- *
43
- * ```ts
44
- * │ // Quick example
45
- * │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
46
- * │ import { Moost, Param } from 'moost'
47
- * │
48
- * │ class MyApp extends Moost {
49
- * │ @Cli('command/:arg')
50
- * │ command(
51
- * │ @Param('arg')
52
- * │ arg: string,
53
- * │ @CliOption('test', 't')
54
- * │ test: boolean,
55
- * │ ) {
56
- * │ return `command run with flag arg=${ arg }, test=${ test }`
57
- * │ }
58
- * │ }
59
- * │
60
- * │ const app = new MyApp()
61
- * │ app.applyGlobalInterceptors(cliHelpInterceptor())
62
- * │
63
- * │ const cli = new MoostCli()
64
- * │ app.adapter(cli)
65
- * │ app.init()
66
- * ```
67
- */
68
- class MoostCli {
69
- constructor(opts) {
70
- this.opts = opts;
71
- this.optionTypes = {};
72
- const cliAppOpts = opts === null || opts === void 0 ? void 0 : opts.wooksCli;
73
- if (cliAppOpts && cliAppOpts instanceof WooksCli) {
74
- this.cliApp = cliAppOpts;
75
- }
76
- else if (cliAppOpts) {
77
- this.cliApp = createCliApp(Object.assign(Object.assign({}, cliAppOpts), { onNotFound: this.onNotFound.bind(this) }));
78
- }
79
- else {
80
- this.cliApp = createCliApp({
81
- onNotFound: this.onNotFound.bind(this),
82
- });
83
- }
84
- if (!(opts === null || opts === void 0 ? void 0 : opts.debug)) {
85
- getMoostInfact().silent(true);
86
- }
87
- }
88
- onNotFound() {
89
- var _a;
90
- return __awaiter(this, void 0, void 0, function* () {
91
- const pathParams = useCliContext().store('event').get('pathParams');
92
- const response = yield defineMoostEventHandler({
93
- loggerTitle: LOGGER_TITLE,
94
- getIterceptorHandler: () => { var _a; return (_a = this.moost) === null || _a === void 0 ? void 0 : _a.getGlobalInterceptorHandler(); },
95
- getControllerInstance: () => this.moost,
96
- callControllerMethod: () => undefined,
97
- logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
98
- })();
99
- if (typeof response === 'undefined') {
100
- this.cliApp.onUnknownCommand(pathParams);
101
- }
102
- return response;
103
- });
104
- }
105
- onInit(moost) {
106
- this.moost = moost;
107
- const boolean = Object
108
- .entries(this.optionTypes)
109
- .filter(([_key, val]) => val.length === 1 && val[0] === Boolean)
110
- .map(([key, _val]) => key);
111
- void this.cliApp.run(undefined, {
112
- boolean,
113
- });
114
- }
115
- bindHandler(opts) {
116
- var _a, _b, _c, _d;
117
- let fn;
118
- for (const handler of opts.handlers) {
119
- if (handler.type !== 'CLI')
120
- continue;
121
- const path = typeof handler.path === 'string'
122
- ? handler.path
123
- : typeof opts.method === 'string'
124
- ? opts.method
125
- : '';
126
- const prefix = opts.prefix.replace(/\s+/g, '/') || '';
127
- const makePath = (p) => `${prefix}/${p}`
128
- .replace(/\/\/+/g, '/')
129
- // avoid interpreting "cmd:tail" as "cmd/:tail"
130
- .replace(/\/\\:/g, '\\:')
131
- .replace(/^\/+/g, '');
132
- if (!fn) {
133
- fn = defineMoostEventHandler({
134
- contextType: CONTEXT_TYPE,
135
- loggerTitle: LOGGER_TITLE,
136
- getIterceptorHandler: opts.getIterceptorHandler,
137
- getControllerInstance: opts.getInstance,
138
- controllerMethod: opts.method,
139
- resolveArgs: opts.resolveArgs,
140
- logErrors: (_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug,
141
- });
142
- }
143
- const targetPath = makePath(path);
144
- const meta = getCliMate().read(opts.fakeInstance, opts.method);
145
- const classMeta = getCliMate().read(opts.fakeInstance);
146
- const cliOptions = new Map();
147
- [
148
- ...(((_c = (_b = this.opts) === null || _b === void 0 ? void 0 : _b.globalCliOptions) === null || _c === void 0 ? void 0 : _c.length) ? this.opts.globalCliOptions : []),
149
- ...((classMeta === null || classMeta === void 0 ? void 0 : classMeta.cliOptions) || []),
150
- ...((meta === null || meta === void 0 ? void 0 : meta.params) ? meta.params.filter((param) => { var _a; return ((_a = param.cliOptionsKeys) === null || _a === void 0 ? void 0 : _a.length) > 0; }).map((param) => ({
151
- keys: param.cliOptionsKeys,
152
- value: typeof param.value === 'string' ? param.value : '',
153
- description: param.description || '',
154
- type: param.type,
155
- })) : []),
156
- ].forEach(o => cliOptions.set(o.keys[0], o));
157
- const aliases = [];
158
- if (meta === null || meta === void 0 ? void 0 : meta.cliAliases) {
159
- for (const alias of meta.cliAliases) {
160
- const targetPath = makePath(alias);
161
- aliases.push(targetPath);
162
- }
163
- }
164
- const cliOptionsArray = Array.from(cliOptions.values());
165
- cliOptionsArray.forEach(o => {
166
- for (const key of o.keys) {
167
- if (!this.optionTypes[key]) {
168
- this.optionTypes[key] = [];
169
- }
170
- if (!(this.optionTypes[key].includes(o.type))) {
171
- this.optionTypes[key].push(o.type);
172
- }
173
- }
174
- });
175
- const args = {};
176
- (_d = meta === null || meta === void 0 ? void 0 : meta.params) === null || _d === void 0 ? void 0 : _d.filter(p => p.paramSource === 'ROUTE' && p.description).forEach(p => args[p.paramName] = p.description);
177
- const routerBinding = this.cliApp.cli(targetPath, {
178
- description: (meta === null || meta === void 0 ? void 0 : meta.description) || '',
179
- options: cliOptionsArray,
180
- args,
181
- aliases,
182
- examples: (meta === null || meta === void 0 ? void 0 : meta.cliExamples) || [],
183
- handler: fn,
184
- onRegister: (path, aliasType, route) => {
185
- var _a;
186
- opts.register(handler, path, (route === null || route === void 0 ? void 0 : route.getArgs()) || routerBinding.getArgs());
187
- if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.debug) {
188
- opts.logHandler(`${''}(${aliasTypes[aliasType]})${''}${path}`);
189
- }
190
- },
191
- });
192
- opts.register(handler, targetPath, routerBinding.getArgs());
193
- }
194
- }
195
- }
196
168
  const aliasTypes = ['CLI', 'CLI-alias', 'CLI-alias*', 'CLI-alias*'];
197
169
 
198
- function formatParams(keys) {
199
- const names = [keys].flat();
200
- return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
170
+ function formatParams(keys) {
171
+ const names = [keys].flat();
172
+ return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
201
173
  }
202
174
 
203
- /**
204
- * ## Define CLI Option
205
- * ### @ParameterDecorator
206
- * Use together with @Description('...') to document cli option
207
- *
208
- * ```ts
209
- * │ @Cli('command')
210
- * │ command(
211
- * │ @Description('Test option...')
212
- * │ @CliOption('test', 't')
213
- * │ test: boolean,
214
- * │ ) {
215
- * │ return `test=${ test }`
216
- * │ }
217
- * ```
218
- *
219
- * @param keys list of keys (short and long alternatives)
220
- * @returns
221
- */
222
- function CliOption(...keys) {
223
- const mate = getCliMate();
224
- return mate.apply(mate.decorate('cliOptionsKeys', keys, false), Resolve(() => useCliOption(keys[0]), formatParams(keys).join(', ')));
225
- }
226
- /**
227
- * ## Define Global CLI Option
228
- * ### @ClassDecorator
229
- * The option described here will appear in every command instructions
230
- * @param option keys and description of CLI option
231
- * @returns
232
- */
233
- function CliGlobalOption(option) {
234
- const mate = getCliMate();
235
- return mate.decorate('cliOptions', option, true);
175
+ /**
176
+ * ## Define CLI Option
177
+ * ### @ParameterDecorator
178
+ * Use together with @Description('...') to document cli option
179
+ *
180
+ * ```ts
181
+ * │ @Cli('command')
182
+ * │ command(
183
+ * │ @Description('Test option...')
184
+ * │ @CliOption('test', 't')
185
+ * │ test: boolean,
186
+ * │ ) {
187
+ * │ return `test=${ test }`
188
+ * │ }
189
+ * ```
190
+ *
191
+ * @param keys list of keys (short and long alternatives)
192
+ * @returns
193
+ */
194
+ function CliOption(...keys) {
195
+ const mate = getCliMate();
196
+ return mate.apply(mate.decorate('cliOptionsKeys', keys, false), Resolve(() => useCliOption(keys[0]), formatParams(keys).join(', ')));
197
+ }
198
+ /**
199
+ * ## Define Global CLI Option
200
+ * ### @ClassDecorator
201
+ * The option described here will appear in every command instructions
202
+ * @param option keys and description of CLI option
203
+ * @returns
204
+ */
205
+ function CliGlobalOption(option) {
206
+ const mate = getCliMate();
207
+ return mate.decorate('cliOptions', option, true);
236
208
  }
237
209
 
238
- /**
239
- * ## Define CLI Command
240
- * ### @MethodDecorator
241
- *
242
- * Command path segments may be separated by / or space.
243
- *
244
- * For example the folowing path are interpreted the same:
245
- * - "command test use:dev :name"
246
- * - "command/test/use:dev/:name"
247
- *
248
- * Where name will become an argument
249
- *
250
- * @param path - command path
251
- * @returns
252
- */
253
- function Cli(path) {
254
- return getCliMate().decorate('handlers', { path: path === null || path === void 0 ? void 0 : path.replace(/\s+/g, '/'), type: 'CLI' }, true);
255
- }
256
- /**
257
- * ## Define CLI Command Alias
258
- * ### @MethodDecorator
259
- *
260
- * Use it to define alias for @Cli('...') command
261
- *
262
- * @param path - command alias path
263
- * @returns
264
- */
265
- function CliAlias(alias) {
266
- return getCliMate().decorate('cliAliases', alias, true);
267
- }
268
- /**
269
- * ## Define CLI Example
270
- * ### @MethodDecorator
271
- *
272
- * Use it to define example for Cli Help display
273
- *
274
- * @param path - command alias path
275
- * @returns
276
- */
277
- function CliExample(cmd, description) {
278
- return getCliMate().decorate('cliExamples', { cmd, description }, true);
210
+ /**
211
+ * ## Define CLI Command
212
+ * ### @MethodDecorator
213
+ *
214
+ * Command path segments may be separated by / or space.
215
+ *
216
+ * For example the folowing path are interpreted the same:
217
+ * - "command test use:dev :name"
218
+ * - "command/test/use:dev/:name"
219
+ *
220
+ * Where name will become an argument
221
+ *
222
+ * @param path - command path
223
+ * @returns
224
+ */
225
+ function Cli(path) {
226
+ return getCliMate().decorate('handlers', { path: path?.replace(/\s+/g, '/'), type: 'CLI' }, true);
227
+ }
228
+ /**
229
+ * ## Define CLI Command Alias
230
+ * ### @MethodDecorator
231
+ *
232
+ * Use it to define alias for @Cli('...') command
233
+ *
234
+ * @param path - command alias path
235
+ * @returns
236
+ */
237
+ function CliAlias(alias) {
238
+ return getCliMate().decorate('cliAliases', alias, true);
239
+ }
240
+ /**
241
+ * ## Define CLI Example
242
+ * ### @MethodDecorator
243
+ *
244
+ * Use it to define example for Cli Help display
245
+ *
246
+ * @param path - command alias path
247
+ * @returns
248
+ */
249
+ function CliExample(cmd, description) {
250
+ return getCliMate().decorate('cliExamples', { cmd, description }, true);
279
251
  }
280
252
 
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
- try {
296
- if (useAutoHelp(opts === null || opts === void 0 ? void 0 : opts.helpOptions, opts === null || opts === void 0 ? void 0 : opts.colors)) {
297
- return '';
298
- }
299
- }
300
- catch (e) {
301
- //
302
- }
303
- if (opts === null || opts === void 0 ? void 0 : opts.lookupLevel) {
304
- const { getMethod } = useControllerContext();
305
- if (!getMethod()) {
306
- useCommandLookupHelp(opts.lookupLevel);
307
- }
308
- }
309
- }, TInterceptorPriority.BEFORE_ALL);
310
- };
311
- /**
312
- * ## @Decorator
313
- * ### Interceptor Factory for CliHelpRenderer
314
- *
315
- * By default intercepts cli calls with flag --help
316
- * and prints help.
317
- *
318
- * ```ts
319
- * // default configuration
320
- * • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
321
- *
322
- * // additional option -h to invoke help renderer
323
- * • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
324
- *
325
- * // redefine cli option to invoke help renderer
326
- * • @CliHelpInterceptor({ helpOptions: ['usage'] })
327
- * ```
328
- *
329
- * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
330
- * @returns Decorator
331
- */
253
+ /**
254
+ * ### Interceptor Factory for CliHelpRenderer
255
+ *
256
+ * By default intercepts cli calls with flag --help
257
+ * and prints help.
258
+ *
259
+ * ```js
260
+ * new Moost().applyGlobalInterceptors(cliHelpInterceptor({ colors: true }))
261
+ * ```
262
+ * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
263
+ * @returns TInterceptorFn
264
+ */
265
+ const cliHelpInterceptor = (opts) => {
266
+ return defineInterceptorFn(() => {
267
+ try {
268
+ if (useAutoHelp(opts?.helpOptions, opts?.colors)) {
269
+ return '';
270
+ }
271
+ }
272
+ catch (e) {
273
+ //
274
+ }
275
+ if (opts?.lookupLevel) {
276
+ const { getMethod } = useControllerContext();
277
+ if (!getMethod()) {
278
+ useCommandLookupHelp(opts.lookupLevel);
279
+ }
280
+ }
281
+ }, TInterceptorPriority.BEFORE_ALL);
282
+ };
283
+ /**
284
+ * ## @Decorator
285
+ * ### Interceptor Factory for CliHelpRenderer
286
+ *
287
+ * By default intercepts cli calls with flag --help
288
+ * and prints help.
289
+ *
290
+ * ```ts
291
+ * // default configuration
292
+ * • @CliHelpInterceptor({ helpOptions: 'help', colors: true })
293
+ *
294
+ * // additional option -h to invoke help renderer
295
+ * • @CliHelpInterceptor({ helpOptions: ['help', 'h'], colors: true })
296
+ *
297
+ * // redefine cli option to invoke help renderer
298
+ * • @CliHelpInterceptor({ helpOptions: ['usage'] })
299
+ * ```
300
+ *
301
+ * @param opts {} { helpOptions: ['help', 'h'], colors: true } cli options to invoke help renderer
302
+ * @returns Decorator
303
+ */
332
304
  const CliHelpInterceptor = (...opts) => Intercept(cliHelpInterceptor(...opts));
333
305
 
334
306
  export { Cli, CliAlias, CliExample, CliGlobalOption, CliHelpInterceptor, CliOption, MoostCli, cliHelpInterceptor };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moostjs/event-cli",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "description": "@moostjs/event-cli",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -37,9 +37,9 @@
37
37
  "homepage": "https://github.com/moostjs/moostjs/tree/main/packages/event-cli#readme",
38
38
  "peerDependencies": {},
39
39
  "dependencies": {
40
- "moost": "0.3.10",
41
- "wooks": "^0.4.9",
42
- "@wooksjs/event-core": "^0.4.9",
43
- "@wooksjs/event-cli": "^0.4.9"
40
+ "moost": "0.3.11",
41
+ "wooks": "^0.4.11",
42
+ "@wooksjs/event-core": "^0.4.11",
43
+ "@wooksjs/event-cli": "^0.4.11"
44
44
  }
45
45
  }