@moostjs/event-cli 0.3.10 → 0.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3,336 +3,184 @@
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
+ class MoostCli {
13
+ constructor(opts) {
14
+ this.opts = opts;
15
+ this.optionTypes = {};
16
+ const cliAppOpts = opts?.wooksCli;
17
+ if (cliAppOpts && cliAppOpts instanceof eventCli.WooksCli) {
18
+ this.cliApp = cliAppOpts;
19
+ }
20
+ else if (cliAppOpts) {
21
+ this.cliApp = eventCli.createCliApp({
22
+ ...cliAppOpts,
23
+ onNotFound: this.onNotFound.bind(this),
24
+ });
25
+ }
26
+ else {
27
+ this.cliApp = eventCli.createCliApp({
28
+ onNotFound: this.onNotFound.bind(this),
29
+ });
30
+ }
31
+ if (!opts?.debug) {
32
+ moost.getMoostInfact().silent(true);
33
+ }
34
+ }
35
+ async onNotFound() {
36
+ const pathParams = eventCli.useCliContext().store('event').get('pathParams');
37
+ const response = await moost.defineMoostEventHandler({
38
+ loggerTitle: LOGGER_TITLE,
39
+ getIterceptorHandler: () => this.moost?.getGlobalInterceptorHandler(),
40
+ getControllerInstance: () => this.moost,
41
+ callControllerMethod: () => undefined,
42
+ logErrors: this.opts?.debug,
43
+ })();
44
+ if (typeof response === 'undefined') {
45
+ this.cliApp.onUnknownCommand(pathParams);
46
+ }
47
+ return response;
48
+ }
49
+ onInit(moost) {
50
+ this.moost = moost;
51
+ const boolean = Object
52
+ .entries(this.optionTypes)
53
+ .filter(([_key, val]) => val.length === 1 && val[0] === Boolean)
54
+ .map(([key, _val]) => key);
55
+ void this.cliApp.run(undefined, {
56
+ boolean,
57
+ });
58
+ }
59
+ bindHandler(opts) {
60
+ let fn;
61
+ for (const handler of opts.handlers) {
62
+ if (handler.type !== 'CLI')
63
+ continue;
64
+ const path = typeof handler.path === 'string'
65
+ ? handler.path
66
+ : typeof opts.method === 'string'
67
+ ? opts.method
68
+ : '';
69
+ const prefix = opts.prefix.replace(/\s+/g, '/') || '';
70
+ const makePath = (p) => `${prefix}/${p}`
71
+ .replace(/\/\/+/g, '/')
72
+ .replace(/\/\\:/g, '\\:')
73
+ .replace(/^\/+/g, '');
74
+ if (!fn) {
75
+ fn = moost.defineMoostEventHandler({
76
+ contextType: CONTEXT_TYPE,
77
+ loggerTitle: LOGGER_TITLE,
78
+ getIterceptorHandler: opts.getIterceptorHandler,
79
+ getControllerInstance: opts.getInstance,
80
+ controllerMethod: opts.method,
81
+ resolveArgs: opts.resolveArgs,
82
+ logErrors: this.opts?.debug,
83
+ });
84
+ }
85
+ const targetPath = makePath(path);
86
+ const meta = getCliMate().read(opts.fakeInstance, opts.method);
87
+ const classMeta = getCliMate().read(opts.fakeInstance);
88
+ const cliOptions = new Map();
89
+ [
90
+ ...(this.opts?.globalCliOptions?.length ? this.opts.globalCliOptions : []),
91
+ ...(classMeta?.cliOptions || []),
92
+ ...(meta?.params ? meta.params.filter((param) => param.cliOptionsKeys?.length > 0).map((param) => ({
93
+ keys: param.cliOptionsKeys,
94
+ value: typeof param.value === 'string' ? param.value : '',
95
+ description: param.description || '',
96
+ type: param.type,
97
+ })) : []),
98
+ ].forEach(o => cliOptions.set(o.keys[0], o));
99
+ const aliases = [];
100
+ if (meta?.cliAliases) {
101
+ for (const alias of meta.cliAliases) {
102
+ const targetPath = makePath(alias);
103
+ aliases.push(targetPath);
104
+ }
105
+ }
106
+ const cliOptionsArray = Array.from(cliOptions.values());
107
+ cliOptionsArray.forEach(o => {
108
+ for (const key of o.keys) {
109
+ if (!this.optionTypes[key]) {
110
+ this.optionTypes[key] = [];
111
+ }
112
+ if (!(this.optionTypes[key].includes(o.type))) {
113
+ this.optionTypes[key].push(o.type);
114
+ }
115
+ }
116
+ });
117
+ const args = {};
118
+ meta?.params?.filter(p => p.paramSource === 'ROUTE' && p.description)
119
+ .forEach(p => args[p.paramName] = p.description);
120
+ const routerBinding = this.cliApp.cli(targetPath, {
121
+ description: meta?.description || '',
122
+ options: cliOptionsArray,
123
+ args,
124
+ aliases,
125
+ examples: meta?.cliExamples || [],
126
+ handler: fn,
127
+ onRegister: (path, aliasType, route) => {
128
+ opts.register(handler, path, route?.getArgs() || routerBinding.getArgs());
129
+ if (this.opts?.debug) {
130
+ opts.logHandler(`${''}(${aliasTypes[aliasType]})${''}${path}`);
131
+ }
132
+ },
133
+ });
134
+ opts.register(handler, targetPath, routerBinding.getArgs());
135
+ }
136
+ }
35
137
  }
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
138
  const aliasTypes = ['CLI', 'CLI-alias', 'CLI-alias*', 'CLI-alias*'];
198
139
 
199
- function formatParams(keys) {
200
- const names = [keys].flat();
201
- return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
140
+ function formatParams(keys) {
141
+ const names = [keys].flat();
142
+ return names.map((n) => (n.length === 1 ? '-' + n : '--' + n));
202
143
  }
203
144
 
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);
145
+ function CliOption(...keys) {
146
+ const mate = getCliMate();
147
+ return mate.apply(mate.decorate('cliOptionsKeys', keys, false), moost.Resolve(() => eventCli.useCliOption(keys[0]), formatParams(keys).join(', ')));
148
+ }
149
+ function CliGlobalOption(option) {
150
+ const mate = getCliMate();
151
+ return mate.decorate('cliOptions', option, true);
237
152
  }
238
153
 
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);
154
+ function Cli(path) {
155
+ return getCliMate().decorate('handlers', { path: path?.replace(/\s+/g, '/'), type: 'CLI' }, true);
156
+ }
157
+ function CliAlias(alias) {
158
+ return getCliMate().decorate('cliAliases', alias, true);
159
+ }
160
+ function CliExample(cmd, description) {
161
+ return getCliMate().decorate('cliExamples', { cmd, description }, true);
280
162
  }
281
163
 
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
- */
164
+ const cliHelpInterceptor = (opts) => {
165
+ return moost.defineInterceptorFn(() => {
166
+ try {
167
+ if (eventCli.useAutoHelp(opts?.helpOptions, opts?.colors)) {
168
+ return '';
169
+ }
170
+ }
171
+ catch (e) {
172
+ }
173
+ if (opts?.lookupLevel) {
174
+ const { getMethod } = moost.useControllerContext();
175
+ if (!getMethod()) {
176
+ eventCli.useCommandLookupHelp(opts.lookupLevel);
177
+ }
178
+ }
179
+ }, moost.TInterceptorPriority.BEFORE_ALL);
180
+ };
333
181
  const CliHelpInterceptor = (...opts) => moost.Intercept(cliHelpInterceptor(...opts));
334
182
 
335
- Object.defineProperty(exports, 'useCliContext', {
183
+ Object.defineProperty(exports, "useCliContext", {
336
184
  enumerable: true,
337
185
  get: function () { return eventCli.useCliContext; }
338
186
  });