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