juisy 2.0.0-beta.15 → 2.0.0-beta.16

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.
@@ -52,5 +52,7 @@ export type PluginAPI = {
52
52
  export declare function CLIFactory(builder: CLIBuilder, options?: CLIFactoryOptions): Promise<(argv?: typeof process.argv) => CLIEngine>;
53
53
  export declare namespace CLIFactory {
54
54
  var use: (plugin: Plugin) => void;
55
+ var removePlugin: (name: string) => void;
56
+ var getRegisteredPlugins: () => Plugin[];
55
57
  }
56
58
  export {};
@@ -1,11 +1,12 @@
1
- import { CommandObject } from './types';
1
+ import { OutputUtils } from './OutputUtils';
2
+ import { CLIEngine, CommandObject, CommandHandlerArgs } from './types';
2
3
  type CommandOptions = {
3
4
  command: CommandObject['command'];
4
5
  aliases?: CommandObject['aliases'];
5
6
  describe?: CommandObject['describe'];
6
7
  deprecated?: CommandObject['deprecated'];
7
- builder?: CommandObject['builder'];
8
- handler?: CommandObject['handler'];
8
+ builder?: Command['builder'];
9
+ handler?: Command['handler'];
9
10
  middlewares?: CommandObject['middlewares'];
10
11
  meta?: CommandObject['meta'];
11
12
  };
@@ -17,7 +18,7 @@ export declare class Command implements CommandObject {
17
18
  * Creates a Command instance from object (CommandObject)
18
19
  * @param {CommandObject} commandObject - The command definition object
19
20
  */
20
- constructor(commandObject: CommandOptions);
21
+ constructor(commandObject?: CommandOptions);
21
22
  /**
22
23
  * The command
23
24
  */
@@ -41,14 +42,53 @@ export declare class Command implements CommandObject {
41
42
  /**
42
43
  * Command builder
43
44
  */
44
- builder: (cli: import('./types').CLIEngine) => import('./types').CLIEngine | PromiseLike<import('./types').CLIEngine>;
45
+ builder(cli: CLIEngine): CLIEngine | PromiseLike<CLIEngine>;
45
46
  /**
46
47
  * Command handler
47
48
  */
48
- handler: import('./types').CommandHandler | undefined;
49
+ handler(this: this, argv: CommandHandlerArgs): void | Promise<void>;
49
50
  /**
50
51
  * Command middlewares
51
52
  */
52
53
  middlewares: import('yargs').MiddlewareFunction[] | undefined;
54
+ /**
55
+ * Log a message in the console output. Uses OutputUtils.log method.
56
+ * @param msg The message to log. Can be empty to log blank line
57
+ * @param options The options to pass to OutputUtils.log second argument
58
+ */
59
+ log(msg?: string, options?: Parameters<typeof OutputUtils.log>[1]): void;
60
+ /**
61
+ * Get the process.argv without bin
62
+ * @returns An array of command line arguments
63
+ */
64
+ getProcessArgv(): string[];
65
+ /**
66
+ * Get Command instance as plain object
67
+ * @returns The command definition object to pass to yargs
68
+ */
69
+ toObject(): {
70
+ command: string | readonly string[] | undefined;
71
+ aliases: string | readonly string[] | undefined;
72
+ describe: string | false | undefined;
73
+ deprecated: string | boolean | undefined;
74
+ meta: Partial<import('./types').CommandMeta> | undefined;
75
+ builder: (cli: CLIEngine) => CLIEngine | PromiseLike<CLIEngine>;
76
+ handler: OmitThisParameter<(this: this, argv: CommandHandlerArgs) => void | Promise<void>>;
77
+ middlewares: import('yargs').MiddlewareFunction[] | undefined;
78
+ };
79
+ /**
80
+ * Getters
81
+ */
82
+ /**
83
+ * Get the CLI engine
84
+ */
85
+ get engine(): CLIEngine;
86
+ /**
87
+ * Static properties
88
+ */
89
+ /**
90
+ * The CLI engine. Will be set by createEngine method
91
+ */
92
+ static engine: CLIEngine;
53
93
  }
54
94
  export {};
@@ -13,6 +13,7 @@ declare global {
13
13
  };
14
14
  }
15
15
  export { CLIFactory } from './CLIFactory';
16
+ export { Plugin } from './Plugin';
16
17
  export * from './Command';
17
18
  export * from './InterfaceUtils';
18
19
  export * from './OutputUtils';
@@ -27,6 +28,5 @@ export type * from './plugins/register-git-hooks-commands/augment';
27
28
  export type * from './plugins/register-lint-commands/augment';
28
29
  export type * from './plugins/register-release-command/augment';
29
30
  export type * from './plugins/default-command-fallbacks/augment';
30
- export type * from './plugins/command-handler-injections/augment';
31
31
  export type * from './plugins/command-meta/augment';
32
32
  export type * from './plugins/private-commands/augment';
package/dist/cli/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.15
2
+ * juisy v2.0.0-beta.16
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
@@ -11,11 +11,11 @@ import Yargs from 'yargs/yargs';
11
11
  import { findUpSync } from 'find-up';
12
12
  import { importSingleTs } from 'import-single-ts';
13
13
  import lodashGet from 'lodash.get';
14
- import { execa } from 'execa';
15
- import _prompts from 'prompts';
16
14
  import chalk from 'chalk';
17
15
  import indent from 'indent-string';
18
16
  import _stripAnsi from 'strip-ansi';
17
+ import { execa } from 'execa';
18
+ import _prompts from 'prompts';
19
19
  import dotenv from '@dotenvx/dotenvx';
20
20
  import semver from 'semver';
21
21
  import fs$1 from 'node:fs';
@@ -56,6 +56,285 @@ class Plugin {
56
56
  created;
57
57
  }
58
58
 
59
+ const loading = {
60
+ // Duration of each character displaying (in ms)
61
+ velocity: 250,
62
+ // Reference to call setInterval and clearInterval
63
+ intervalRef: null,
64
+ // Display loading to STDOUT
65
+ display: function(message) {
66
+ const P = ["\\", "|", "/", "-"];
67
+ const S = [" ", ". ", ".. ", "..."];
68
+ let x = 0;
69
+ let y = 0;
70
+ const velocity = this.velocity;
71
+ this.intervalRef = setInterval(function() {
72
+ process.stdout.write("\r" + P[x++] + " " + message + " : " + S[y++]);
73
+ x &= 3;
74
+ y &= 3;
75
+ }, velocity);
76
+ },
77
+ stop: function() {
78
+ clearInterval(this.intervalRef);
79
+ try {
80
+ process.stdout.clearLine(0);
81
+ process.stdout.cursorTo(0);
82
+ } catch (err) {
83
+ console.log("Warn: process.stdout.clearLine (or cursorTo) function is non-TTY. Skipped...");
84
+ }
85
+ }
86
+ };
87
+ class OutputUtils {
88
+ /**
89
+ * To automatically increment step index
90
+ * @ignore
91
+ */
92
+ static stepsCache = {
93
+ index: 0
94
+ // 0 by default
95
+ };
96
+ /**
97
+ * Use `chalk` package to style output in console/stdout
98
+ * @example
99
+ * const { $style } = OutputUtils
100
+ * console.log($style.green('Green text!')) // => '[32mGreen text![0m'
101
+ */
102
+ static $style = chalk;
103
+ /**
104
+ * Format a message for console output
105
+ * @param msg - The message to format
106
+ * @param options - Format options
107
+ * @returns The formatted message
108
+ * @example
109
+ * formatOutputMessage('laundry\nshopping', { indentChar: '- ' })
110
+ * // => '- laundry\n- shopping'
111
+ *
112
+ * formatOutputMessage('foo\nbar', { indent: 2, indentChar: '❤' })
113
+ * // => '❤❤foo\n❤❤bar'
114
+ */
115
+ static formatOutputMessage(msg, options = {}) {
116
+ let formatted = `${msg}`;
117
+ if (options.indentChar) {
118
+ if (options.indent === void 0) {
119
+ options.indent = 1;
120
+ }
121
+ } else {
122
+ options.indentChar = " ";
123
+ options.indent = options.indent || 0;
124
+ }
125
+ if (options.indent) {
126
+ formatted = indent(msg, options.indent, { indent: options.indentChar });
127
+ }
128
+ return formatted;
129
+ }
130
+ /**
131
+ * @param msg - The message
132
+ * @param options - (Optional) Options object
133
+ * @param options.indent - How many repeat indent (see `indent-string` package)
134
+ * @param options.indentChar - Indent character(s). If `options.indent` not provided, will be repeated only 1 time
135
+ * @description
136
+ * Log message in console
137
+ * @example
138
+ * const { log } = OutputUtils
139
+ * log() // => blank line
140
+ * log('Hello world! =)') // => 'Hello world! =)'
141
+ * log('To do:', { indent: 2 }) // => ' To do:'
142
+ */
143
+ static log(msg, options = {}) {
144
+ const loggerInstance = options.loggerInstance || console;
145
+ if (msg) {
146
+ loggerInstance.log(OutputUtils.formatOutputMessage(msg, options));
147
+ } else {
148
+ loggerInstance.log();
149
+ }
150
+ }
151
+ /**
152
+ * Display warning message
153
+ * @param msg - The message to display
154
+ * @example
155
+ * const { warn } = OutputUtils
156
+ * warn('No configuration file') // => '[33m⚠ Warning: No configuration file[0m'
157
+ */
158
+ static warn(msg) {
159
+ OutputUtils.log(OutputUtils.$style.yellow(`⚠ Warning: ${msg}`));
160
+ }
161
+ /**
162
+ * @param msg - The message to display
163
+ * @param err - If provided, throw the error
164
+ * @description
165
+ * Display error message. Throws `err` if provided.
166
+ * @example
167
+ * const { error } = require('@hperchec/juisy').utils
168
+ * error('No configuration file') // => '[31m⨉ ERROR: No configuration file[0m'
169
+ * error('No configuration file', error) // => Log and throws error
170
+ */
171
+ static error(msg, err) {
172
+ OutputUtils.log(OutputUtils.$style.red(`⨉ ERROR: ${msg}`));
173
+ if (err !== void 0) {
174
+ OutputUtils.log();
175
+ throw err;
176
+ }
177
+ }
178
+ /**
179
+ * Log step title
180
+ * @param msg - The message to display
181
+ * @param options - Options object
182
+ * @param options.index - Custom index. If `null`, no index prepended to string
183
+ * @example
184
+ * step('Important step') // => '● 1 - Important step'
185
+ * step('Very important step') // => '● 2 - Very important step'
186
+ */
187
+ static step(msg, options = {}) {
188
+ OutputUtils.stepsCache.index++;
189
+ if (options.index === void 0) {
190
+ options.index = OutputUtils.stepsCache.index;
191
+ }
192
+ OutputUtils.log(`${options.index !== null ? options.index + " - " : ""}${msg}`, { indentChar: "● " });
193
+ }
194
+ /**
195
+ * Log substep title
196
+ * @param msg - The message to display
197
+ * @param options - Options object
198
+ * @param options.last - Defines if it is the last substep
199
+ * @example
200
+ * const { substep } = require('@hperchec/juisy').utils
201
+ * substep('Awesome substep') // => '├ Awesome substep'
202
+ * substep('Last substep', { last: true }) // => '└ Last substep'
203
+ */
204
+ static substep(msg, options = {}) {
205
+ OutputUtils.log(msg, { indentChar: options.last ? "└ " : "├ " });
206
+ }
207
+ /**
208
+ * @param {string} message - Message to display
209
+ * @param {Function} fct - The function to execute
210
+ * @returns {Promise<void>}
211
+ * @description
212
+ * Wait function: display loading during 'fct' execution
213
+ * @example
214
+ * const { wait } = require('@hperchec/juisy').utils
215
+ * await wait('Waiting', async () => {
216
+ * // Do async logic
217
+ * })
218
+ */
219
+ static async wait(message, fct) {
220
+ loading.display(message);
221
+ await fct();
222
+ loading.stop();
223
+ }
224
+ /**
225
+ * See `strip-ansi` package documentation
226
+ * @see https://www.npmjs.com/package/strip-ansi
227
+ */
228
+ static stripAnsi = _stripAnsi;
229
+ }
230
+
231
+ class Command {
232
+ /**
233
+ * Creates a Command instance from object (CommandObject)
234
+ * @param {CommandObject} commandObject - The command definition object
235
+ */
236
+ constructor(commandObject) {
237
+ if (commandObject) {
238
+ this.command = commandObject.command;
239
+ this.aliases = commandObject.aliases;
240
+ this.describe = commandObject.describe;
241
+ this.deprecated = commandObject.deprecated;
242
+ this.meta = commandObject.meta;
243
+ if (commandObject.builder)
244
+ this.builder = commandObject.builder;
245
+ if (commandObject.handler)
246
+ this.handler = commandObject.handler;
247
+ this.middlewares = commandObject.middlewares;
248
+ }
249
+ }
250
+ /**
251
+ * The command
252
+ */
253
+ command;
254
+ /**
255
+ * The aliases
256
+ */
257
+ aliases;
258
+ /**
259
+ * Command description
260
+ */
261
+ describe;
262
+ /**
263
+ * Is deprecated?
264
+ */
265
+ deprecated;
266
+ /**
267
+ * Command meta
268
+ */
269
+ meta;
270
+ /**
271
+ * Command builder
272
+ */
273
+ builder(cli) {
274
+ return cli;
275
+ }
276
+ /**
277
+ * Command handler
278
+ */
279
+ handler(argv) {
280
+ throw new Error("Command handler is not implemented");
281
+ }
282
+ /**
283
+ * Command middlewares
284
+ */
285
+ middlewares;
286
+ /**
287
+ * Log a message in the console output. Uses OutputUtils.log method.
288
+ * @param msg The message to log. Can be empty to log blank line
289
+ * @param options The options to pass to OutputUtils.log second argument
290
+ */
291
+ log(msg, options = {}) {
292
+ OutputUtils.log(msg, {
293
+ ...options,
294
+ loggerInstance: this.constructor.engine.getInternalMethods().getLoggerInstance()
295
+ });
296
+ }
297
+ /**
298
+ * Get the process.argv without bin
299
+ * @returns An array of command line arguments
300
+ */
301
+ getProcessArgv() {
302
+ return hideBin(process.argv);
303
+ }
304
+ /**
305
+ * Get Command instance as plain object
306
+ * @returns The command definition object to pass to yargs
307
+ */
308
+ toObject() {
309
+ return {
310
+ command: this.command,
311
+ aliases: this.aliases,
312
+ describe: this.describe,
313
+ deprecated: this.deprecated,
314
+ meta: this.meta,
315
+ builder: this.builder,
316
+ handler: this.handler.bind(this),
317
+ middlewares: this.middlewares
318
+ };
319
+ }
320
+ /**
321
+ * Getters
322
+ */
323
+ /**
324
+ * Get the CLI engine
325
+ */
326
+ get engine() {
327
+ return this.constructor.engine;
328
+ }
329
+ /**
330
+ * Static properties
331
+ */
332
+ /**
333
+ * The CLI engine. Will be set by createEngine method
334
+ */
335
+ static engine;
336
+ }
337
+
59
338
  function createEngine(yargs) {
60
339
  const xargs = yargs;
61
340
  xargs._isPrivate = false;
@@ -78,7 +357,8 @@ function createEngine(yargs) {
78
357
  xargs.enableGlobalCommandVisitors = enableGlobalCommandVisitors;
79
358
  xargs.isPrivate = isPrivate;
80
359
  xargs.getSettings = getSettings;
81
- return xargs.strict().help();
360
+ Command.engine = xargs.strict().help();
361
+ return Command.engine;
82
362
  }
83
363
  function command(...args) {
84
364
  const self = this;
@@ -96,10 +376,13 @@ function command(...args) {
96
376
  }
97
377
  return failOnFalsyReturn ? false : cmdObj;
98
378
  };
379
+ const isClass = (value) => {
380
+ return typeof value === "function" && value.toString().startsWith("class ");
381
+ };
99
382
  if (args[0] instanceof Array) {
100
383
  const cmdsArray = [];
101
384
  for (const commandModule of args[0]) {
102
- const visited = visit(commandModule);
385
+ const visited = visit((isClass(commandModule) ? new commandModule() : commandModule).toObject());
103
386
  if (visited)
104
387
  cmdsArray.push(visited);
105
388
  }
@@ -273,18 +556,7 @@ async function CLIFactory(builder, options) {
273
556
  }
274
557
  for (const defaultCommand of defaultCommands) {
275
558
  if (engine.hasDefaultCommand(defaultCommand.fullSignature)) {
276
- engine.command({
277
- // @ts-ignore
278
- aliases: defaultCommand.commandObject.aliases,
279
- command: defaultCommand.commandObject.command,
280
- describe: defaultCommand.commandObject.describe,
281
- builder: (cli2) => {
282
- return defaultCommand.commandObject.builder(cli2);
283
- },
284
- handler: defaultCommand.commandObject.handler,
285
- meta: defaultCommand.commandObject.meta,
286
- middlewares: defaultCommand.commandObject.middlewares
287
- });
559
+ engine.command(defaultCommand.commandObject.toObject());
288
560
  }
289
561
  }
290
562
  return engine;
@@ -302,228 +574,17 @@ CLIFactory.use = function(plugin) {
302
574
  throw new Error(`Provided plugin is not an instance of Plugin`);
303
575
  }
304
576
  };
305
-
306
- class Command {
307
- /**
308
- * Creates a Command instance from object (CommandObject)
309
- * @param {CommandObject} commandObject - The command definition object
310
- */
311
- constructor(commandObject) {
312
- this.command = commandObject.command;
313
- this.aliases = commandObject.aliases;
314
- this.describe = commandObject.describe;
315
- this.deprecated = commandObject.deprecated;
316
- this.meta = commandObject.meta;
317
- this.builder = commandObject.builder || ((cli) => cli);
318
- this.handler = commandObject.handler;
319
- this.middlewares = commandObject.middlewares;
320
- }
321
- /**
322
- * The command
323
- */
324
- command;
325
- /**
326
- * The aliases
327
- */
328
- aliases;
329
- /**
330
- * Command description
331
- */
332
- describe;
333
- /**
334
- * Is deprecated?
335
- */
336
- deprecated;
337
- /**
338
- * Command meta
339
- */
340
- meta;
341
- /**
342
- * Command builder
343
- */
344
- builder;
345
- /**
346
- * Command handler
347
- */
348
- // @ts-ignore
349
- handler;
350
- /**
351
- * Command middlewares
352
- */
353
- middlewares;
354
- }
355
-
356
- const loading = {
357
- // Duration of each character displaying (in ms)
358
- velocity: 250,
359
- // Reference to call setInterval and clearInterval
360
- intervalRef: null,
361
- // Display loading to STDOUT
362
- display: function(message) {
363
- const P = ["\\", "|", "/", "-"];
364
- const S = [" ", ". ", ".. ", "..."];
365
- let x = 0;
366
- let y = 0;
367
- const velocity = this.velocity;
368
- this.intervalRef = setInterval(function() {
369
- process.stdout.write("\r" + P[x++] + " " + message + " : " + S[y++]);
370
- x &= 3;
371
- y &= 3;
372
- }, velocity);
373
- },
374
- stop: function() {
375
- clearInterval(this.intervalRef);
376
- try {
377
- process.stdout.clearLine(0);
378
- process.stdout.cursorTo(0);
379
- } catch (err) {
380
- console.log("Warn: process.stdout.clearLine (or cursorTo) function is non-TTY. Skipped...");
381
- }
577
+ CLIFactory.removePlugin = function(name) {
578
+ const index = registeredPlugins.findIndex((rp) => rp.name === name);
579
+ if (index > -1) {
580
+ registeredPlugins.splice(index, 1);
581
+ } else {
582
+ throw new Error(`CLI plugin "${name}" is not registered`);
382
583
  }
383
584
  };
384
- class OutputUtils {
385
- /**
386
- * To automatically increment step index
387
- * @ignore
388
- */
389
- static stepsCache = {
390
- index: 0
391
- // 0 by default
392
- };
393
- /**
394
- * Use `chalk` package to style output in console/stdout
395
- * @example
396
- * const { $style } = OutputUtils
397
- * console.log($style.green('Green text!')) // => '[32mGreen text![0m'
398
- */
399
- static $style = chalk;
400
- /**
401
- * Format a message for console output
402
- * @param msg - The message to format
403
- * @param options - Format options
404
- * @returns The formatted message
405
- * @example
406
- * formatOutputMessage('laundry\nshopping', { indentChar: '- ' })
407
- * // => '- laundry\n- shopping'
408
- *
409
- * formatOutputMessage('foo\nbar', { indent: 2, indentChar: '❤' })
410
- * // => '❤❤foo\n❤❤bar'
411
- */
412
- static formatOutputMessage(msg, options = {}) {
413
- let formatted = `${msg}`;
414
- if (options.indentChar) {
415
- if (options.indent === void 0) {
416
- options.indent = 1;
417
- }
418
- } else {
419
- options.indentChar = " ";
420
- options.indent = options.indent || 0;
421
- }
422
- if (options.indent) {
423
- formatted = indent(msg, options.indent, { indent: options.indentChar });
424
- }
425
- return formatted;
426
- }
427
- /**
428
- * @param msg - The message
429
- * @param options - (Optional) Options object
430
- * @param options.indent - How many repeat indent (see `indent-string` package)
431
- * @param options.indentChar - Indent character(s). If `options.indent` not provided, will be repeated only 1 time
432
- * @description
433
- * Log message in console
434
- * @example
435
- * const { log } = OutputUtils
436
- * log() // => blank line
437
- * log('Hello world! =)') // => 'Hello world! =)'
438
- * log('To do:', { indent: 2 }) // => ' To do:'
439
- */
440
- static log(msg, options = {}) {
441
- const loggerInstance = options.loggerInstance || console;
442
- if (msg) {
443
- loggerInstance.log(OutputUtils.formatOutputMessage(msg, options));
444
- } else {
445
- loggerInstance.log();
446
- }
447
- }
448
- /**
449
- * Display warning message
450
- * @param msg - The message to display
451
- * @example
452
- * const { warn } = OutputUtils
453
- * warn('No configuration file') // => '[33m⚠ Warning: No configuration file[0m'
454
- */
455
- static warn(msg) {
456
- OutputUtils.log(OutputUtils.$style.yellow(`⚠ Warning: ${msg}`));
457
- }
458
- /**
459
- * @param msg - The message to display
460
- * @param err - If provided, throw the error
461
- * @description
462
- * Display error message. Throws `err` if provided.
463
- * @example
464
- * const { error } = require('@hperchec/juisy').utils
465
- * error('No configuration file') // => '[31m⨉ ERROR: No configuration file[0m'
466
- * error('No configuration file', error) // => Log and throws error
467
- */
468
- static error(msg, err) {
469
- OutputUtils.log(OutputUtils.$style.red(`⨉ ERROR: ${msg}`));
470
- if (err !== void 0) {
471
- OutputUtils.log();
472
- throw err;
473
- }
474
- }
475
- /**
476
- * Log step title
477
- * @param msg - The message to display
478
- * @param options - Options object
479
- * @param options.index - Custom index. If `null`, no index prepended to string
480
- * @example
481
- * step('Important step') // => '● 1 - Important step'
482
- * step('Very important step') // => '● 2 - Very important step'
483
- */
484
- static step(msg, options = {}) {
485
- OutputUtils.stepsCache.index++;
486
- if (options.index === void 0) {
487
- options.index = OutputUtils.stepsCache.index;
488
- }
489
- OutputUtils.log(`${options.index !== null ? options.index + " - " : ""}${msg}`, { indentChar: "● " });
490
- }
491
- /**
492
- * Log substep title
493
- * @param msg - The message to display
494
- * @param options - Options object
495
- * @param options.last - Defines if it is the last substep
496
- * @example
497
- * const { substep } = require('@hperchec/juisy').utils
498
- * substep('Awesome substep') // => '├ Awesome substep'
499
- * substep('Last substep', { last: true }) // => '└ Last substep'
500
- */
501
- static substep(msg, options = {}) {
502
- OutputUtils.log(msg, { indentChar: options.last ? "└ " : "├ " });
503
- }
504
- /**
505
- * @param {string} message - Message to display
506
- * @param {Function} fct - The function to execute
507
- * @returns {Promise<void>}
508
- * @description
509
- * Wait function: display loading during 'fct' execution
510
- * @example
511
- * const { wait } = require('@hperchec/juisy').utils
512
- * await wait('Waiting', async () => {
513
- * // Do async logic
514
- * })
515
- */
516
- static async wait(message, fct) {
517
- loading.display(message);
518
- await fct();
519
- loading.stop();
520
- }
521
- /**
522
- * See `strip-ansi` package documentation
523
- * @see https://www.npmjs.com/package/strip-ansi
524
- */
525
- static stripAnsi = _stripAnsi;
526
- }
585
+ CLIFactory.getRegisteredPlugins = function() {
586
+ return [...registeredPlugins];
587
+ };
527
588
 
528
589
  const { log, $style } = OutputUtils;
529
590
  class InterfaceUtils {
@@ -627,13 +688,13 @@ const LoadEnvFile = new Plugin("built-in:load-env-file", {
627
688
  }
628
689
  });
629
690
 
630
- const bumpVersion = new Command({
631
- command: "bump-version [targetVersion]",
632
- describe: "Bump version in package.json file",
633
- meta: {
691
+ class BumpVersionCommand extends Command {
692
+ command = "bump-version [targetVersion]";
693
+ describe = "Bump version in package.json file";
694
+ meta = {
634
695
  private: true
635
- },
636
- builder: function(cli) {
696
+ };
697
+ builder(cli) {
637
698
  cli.positional("targetVersion", {
638
699
  describe: "The target version to set manually",
639
700
  type: "string"
@@ -657,7 +718,7 @@ const bumpVersion = new Command({
657
718
  requiresArg: true
658
719
  });
659
720
  return cli;
660
- },
721
+ }
661
722
  async handler(argv) {
662
723
  const { $style, step, substep, error } = OutputUtils;
663
724
  const { confirm, prompts, abort } = InterfaceUtils;
@@ -724,13 +785,13 @@ const bumpVersion = new Command({
724
785
  this.log();
725
786
  }
726
787
  }
727
- });
788
+ }
728
789
 
729
790
  const RegisterBumpVersionCommand = new Plugin("built-in:register-bump-version-command", {
730
791
  beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
731
792
  defineDefaultCommand({
732
793
  fullSignature: "bump-version",
733
- commandObject: bumpVersion,
794
+ commandObject: new BumpVersionCommand(),
734
795
  children: []
735
796
  });
736
797
  }
@@ -1320,6 +1381,9 @@ const RegisterLintCommands = new Plugin("built-in:register-lint-commands", {
1320
1381
  const release = new Command({
1321
1382
  command: "release",
1322
1383
  describe: "Make a release",
1384
+ meta: {
1385
+ private: true
1386
+ },
1323
1387
  builder(cli) {
1324
1388
  cli.option("d", {
1325
1389
  alias: "dry-run",
@@ -1497,6 +1561,9 @@ const RegisterReleaseCommand = new Plugin("built-in:register-release-command", {
1497
1561
  const test = new Command({
1498
1562
  command: "test",
1499
1563
  describe: "Run tests",
1564
+ meta: {
1565
+ private: true
1566
+ },
1500
1567
  async handler(argv) {
1501
1568
  const { $style } = OutputUtils;
1502
1569
  this.log($style.yellow("Command not implemented. Read the doc and build your own!"));
@@ -1520,32 +1587,15 @@ function wrapCommandBuilder(target, builder) {
1520
1587
  return _target(builder(cli));
1521
1588
  };
1522
1589
  }
1523
- function wrapCommandhandler(target, handler) {
1524
- return function(args) {
1525
- handler.call(this, args);
1526
- return target.call(this, args);
1527
- };
1528
- }
1529
1590
 
1530
- const visitor$3 = function(commandObject, cli) {
1591
+ const visitor$2 = function(commandObject, cli) {
1531
1592
  const defaultCommand = getDefaultCommand(commandObject.command);
1532
1593
  if (defaultCommand) {
1533
1594
  commandObject.builder = wrapCommandBuilder(commandObject.builder, function(_cli) {
1534
1595
  if (defaultCommand.children?.length) {
1535
1596
  for (const child of defaultCommand.children) {
1536
1597
  if (cli.hasDefaultCommand(child.fullSignature)) {
1537
- cli.command({
1538
- // @ts-ignore
1539
- aliases: child.commandObject.aliases,
1540
- command: child.commandObject.command,
1541
- describe: child.commandObject.describe,
1542
- builder: (__cli) => {
1543
- return child.commandObject.builder(__cli);
1544
- },
1545
- handler: child.commandObject.handler,
1546
- meta: child.commandObject.meta,
1547
- middlewares: child.commandObject.middlewares
1548
- });
1598
+ cli.command(child.commandObject.toObject());
1549
1599
  }
1550
1600
  }
1551
1601
  }
@@ -1554,39 +1604,11 @@ const visitor$3 = function(commandObject, cli) {
1554
1604
  }
1555
1605
  return commandObject;
1556
1606
  };
1557
- const options$3 = {};
1558
-
1559
- const DefaultCommandFallbacks = new Plugin("built-in:default-command-fallbacks", {
1560
- created({ engine, builder, factoryOptions }) {
1561
- engine.globalCommandVisitor("default-command-fallbacks-visitor", visitor$3, options$3);
1562
- }
1563
- });
1564
-
1565
- const visitor$2 = function(commandObject, cli) {
1566
- commandObject.handler = wrapCommandhandler(commandObject.handler, function(args) {
1567
- Object.defineProperty(this, "engine", {
1568
- get() {
1569
- return cli;
1570
- }
1571
- });
1572
- Object.defineProperty(this, "log", {
1573
- get() {
1574
- return (msg, options2 = {}) => {
1575
- OutputUtils.log(msg, {
1576
- ...options2,
1577
- loggerInstance: cli.getInternalMethods().getLoggerInstance()
1578
- });
1579
- };
1580
- }
1581
- });
1582
- });
1583
- return commandObject;
1584
- };
1585
1607
  const options$2 = {};
1586
1608
 
1587
- const CommandHandlerInjections = new Plugin("built-in:command-handler-injections", {
1609
+ const DefaultCommandFallbacks = new Plugin("built-in:default-command-fallbacks", {
1588
1610
  created({ engine, builder, factoryOptions }) {
1589
- engine.globalCommandVisitor("command-handler-injections-visitor", visitor$2, options$2);
1611
+ engine.globalCommandVisitor("default-command-fallbacks-visitor", visitor$2, options$2);
1590
1612
  }
1591
1613
  });
1592
1614
 
@@ -1702,8 +1724,7 @@ CLIFactory.use(RegisterLintCommands);
1702
1724
  CLIFactory.use(RegisterReleaseCommand);
1703
1725
  CLIFactory.use(RegisterTestCommand);
1704
1726
  CLIFactory.use(DefaultCommandFallbacks);
1705
- CLIFactory.use(CommandHandlerInjections);
1706
1727
  CLIFactory.use(CommandMeta);
1707
1728
  CLIFactory.use(PrivateCommands);
1708
1729
 
1709
- export { CLIFactory, Command, InterfaceUtils, OutputUtils, extractUsage };
1730
+ export { CLIFactory, Command, InterfaceUtils, OutputUtils, Plugin, extractUsage };
@@ -1,3 +1,15 @@
1
1
  import { Command } from '../../../Command';
2
- declare const _default: Command;
3
- export default _default;
2
+ import { CLIEngine, CommandHandlerArgs } from '../../../types';
3
+ export default class BumpVersionCommand extends Command {
4
+ command: string;
5
+ describe: string;
6
+ meta: {
7
+ private: boolean;
8
+ };
9
+ builder(cli: CLIEngine): CLIEngine;
10
+ handler(argv: CommandHandlerArgs<{
11
+ preid: string;
12
+ file: string;
13
+ indent: number;
14
+ }>): Promise<void>;
15
+ }
@@ -1,4 +1,4 @@
1
- import { Argv, CommandModule as YargsCommandModule, MiddlewareFunction } from 'yargs';
1
+ import { Argv, ArgumentsCamelCase, CommandModule as YargsCommandModule, MiddlewareFunction } from 'yargs';
2
2
  import { Command } from './Command';
3
3
  /**
4
4
  * An object whose all properties have the same type.
@@ -110,11 +110,15 @@ export interface CommandObject {
110
110
  /** string used as the description for the command in help text, use `false` for a hidden command */
111
111
  describe: YargsCommandModule['describe'];
112
112
  /** a function which will be passed the parsed argv. */
113
- handler: CommandHandler;
113
+ handler: YargsCommandModule['handler'];
114
114
  /** object declaring the options the command accepts, or a function accepting and returning a yargs instance */
115
115
  builder: (cli: CLIEngine) => CLIEngine | PromiseLike<CLIEngine>;
116
116
  middlewares?: MiddlewareFunction[];
117
117
  }
118
+ /**
119
+ * @group Types
120
+ */
121
+ export type CommandHandlerArgs<T = {}> = ArgumentsCamelCase<T>;
118
122
  /**
119
123
  * @group Types
120
124
  */
@@ -1,4 +1,4 @@
1
- import { CommandObject, CLIEngine, CommandHandler } from './types';
1
+ import { CommandObject, CLIEngine } from './types';
2
2
  /**
3
3
  * @ignore
4
4
  * @param target - The target builder
@@ -8,12 +8,3 @@ import { CommandObject, CLIEngine, CommandHandler } from './types';
8
8
  * that will be called before target. Target can be undefined
9
9
  */
10
10
  export declare function wrapCommandBuilder(target: CommandObject['builder'], builder: (cli: CLIEngine) => CLIEngine): (cli: CLIEngine) => CLIEngine | PromiseLike<CLIEngine>;
11
- /**
12
- * @ignore
13
- * @param target - The target handler
14
- * @param handler - The wrap
15
- * @description
16
- * Wrap command handler (target) with handler passed as second parameter
17
- * that will be called before target. Target can be undefined
18
- */
19
- export declare function wrapCommandhandler(target: CommandHandler, handler: CommandHandler): CommandHandler;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.15
2
+ * juisy v2.0.0-beta.16
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.15
2
+ * juisy v2.0.0-beta.16
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.15
2
+ * juisy v2.0.0-beta.16
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.15
2
+ * juisy v2.0.0-beta.16
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juisy",
3
- "version": "2.0.0-beta.15",
3
+ "version": "2.0.0-beta.16",
4
4
  "description": "Make you JavaScript (and/or TypeScript) project juicy!",
5
5
  "type": "module",
6
6
  "files": [
@@ -64,7 +64,7 @@
64
64
  "release": "release-it --no-increment",
65
65
  "test": "node ./bin/cli test",
66
66
  "test:dev": "npm test -- --watch",
67
- "test:ui": "npm test -- --ui"
67
+ "test:ui": "vitest --ui"
68
68
  },
69
69
  "repository": {
70
70
  "type": "git",
@@ -1,29 +0,0 @@
1
- import { CommandModule as YargsCommandModule, CommandBuilder, MiddlewareFunction } from 'yargs';
2
- declare module '../../types' {
3
- /** Shims for private yargs types */
4
- interface Positional {
5
- cmd: NotEmptyArray<string>;
6
- variadic: boolean;
7
- }
8
- /**
9
- * An array whose first element is not undefined.
10
- */
11
- type NotEmptyArray<T = any> = [T, ...T[]];
12
- interface CommandHandlerThisArg {
13
- builder: CommandBuilder;
14
- demanded: Positional[];
15
- deprecated?: boolean;
16
- description?: string | false;
17
- handler: CommandObject['handler'];
18
- middlewares: MiddlewareFunction[];
19
- optional: Positional[];
20
- original: string;
21
- engine: CLIEngine;
22
- log: (msg?: string, options?: any) => void;
23
- }
24
- /**
25
- * Type declaration to extend "this" type inside command handler method
26
- * @group Types
27
- */
28
- type CommandHandler = (this: CommandHandlerThisArg, argv: Parameters<YargsCommandModule['handler']>[0]) => ReturnType<YargsCommandModule['handler']>;
29
- }
@@ -1,10 +0,0 @@
1
- import { CommandVisitor } from '../../../types';
2
- /**
3
- * Global command visitor to auto-set command meta
4
- * @ignore
5
- * @param commandObject - The command object
6
- * @param cli - The CLIEngine instance
7
- * @returns The commandObject with wrapped handler to inject properties.
8
- */
9
- export declare const visitor: CommandVisitor;
10
- export declare const options: {};
@@ -1,3 +0,0 @@
1
- import { Plugin } from '../../Plugin';
2
- declare const _default: Plugin;
3
- export default _default;