juisy 2.0.0-beta.0

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 (71) hide show
  1. package/README.md +211 -0
  2. package/bin/cli/cli.js +23 -0
  3. package/bin/cli/cmds/changelog.js +41 -0
  4. package/bin/cli/cmds/docs/generate-api.js +22 -0
  5. package/bin/cli/cmds/docs/generate-cli.js +11 -0
  6. package/bin/cli/cmds/docs/generate-readme.js +11 -0
  7. package/bin/cli/cmds/docs/index.js +22 -0
  8. package/bin/cli/cmds/docs/lint.js +42 -0
  9. package/bin/cli/cmds/eject.js +28 -0
  10. package/bin/cli/cmds/git-hooks/index.js +20 -0
  11. package/bin/cli/cmds/git-hooks/reset.js +48 -0
  12. package/bin/cli/cmds/git-hooks/sync.js +19 -0
  13. package/bin/cli/cmds/index.js +15 -0
  14. package/bin/cli/cmds/print-globals.js +28 -0
  15. package/bin/cli/cmds/release.js +231 -0
  16. package/bin/cli/cmds/squeeze.js +269 -0
  17. package/bin/cli/cmds/test.js +33 -0
  18. package/bin/cli/index.js +9 -0
  19. package/bin/cli/lib/docs/generate-api-doc.js +78 -0
  20. package/bin/cli/lib/version/update-version.js +52 -0
  21. package/bin/scripts/commit-msg.js +32 -0
  22. package/bin/scripts/pre-commit.js +24 -0
  23. package/dist/DataExporter.d.ts +67 -0
  24. package/dist/cli/CLIFactory.d.ts +19 -0
  25. package/dist/cli/Command.d.ts +44 -0
  26. package/dist/cli/InterfaceUtils.d.ts +53 -0
  27. package/dist/cli/OutputUtils.d.ts +123 -0
  28. package/dist/cli/command-visitors/command-handler-injections.d.ts +10 -0
  29. package/dist/cli/command-visitors/get-command-meta.d.ts +10 -0
  30. package/dist/cli/command-visitors/index.d.ts +9 -0
  31. package/dist/cli/command-visitors/private-command.d.ts +16 -0
  32. package/dist/cli/create-engine.d.ts +7 -0
  33. package/dist/cli/extract-usage.d.ts +72 -0
  34. package/dist/cli/index.d.ts +20 -0
  35. package/dist/cli/index.js +559 -0
  36. package/dist/cli/types.d.ts +112 -0
  37. package/dist/cli/utils.d.ts +19 -0
  38. package/dist/eject.d.ts +22 -0
  39. package/dist/get-package-info.d.ts +6 -0
  40. package/dist/index.d.ts +11 -0
  41. package/dist/index.js +244 -0
  42. package/dist/project-globals.d.ts +63 -0
  43. package/dist/templater/Templater.d.ts +23 -0
  44. package/dist/templater/index.d.ts +6 -0
  45. package/dist/templater/index.js +330 -0
  46. package/dist/templater/markdown-templater/ReadmeTemplater.d.ts +154 -0
  47. package/dist/templater/markdown-templater/index.d.ts +25 -0
  48. package/dist/templater/types.d.ts +10 -0
  49. package/dist/utils/misc.d.ts +21 -0
  50. package/package.json +179 -0
  51. package/src/index.js +507 -0
  52. package/template/CHANGELOG.md +0 -0
  53. package/template/bin/cli/cli.js +27 -0
  54. package/template/bin/cli/cmds/changelog.js +71 -0
  55. package/template/bin/cli/cmds/docs.js +30 -0
  56. package/template/bin/cli/cmds/docs_cmds/generate-api.js +75 -0
  57. package/template/bin/cli/cmds/docs_cmds/generate-readme.js +51 -0
  58. package/template/bin/cli/cmds/git-hooks.js +30 -0
  59. package/template/bin/cli/cmds/git_hooks_cmds/reset.js +76 -0
  60. package/template/bin/cli/cmds/git_hooks_cmds/sync.js +44 -0
  61. package/template/bin/cli/cmds/release.js +219 -0
  62. package/template/bin/cli/index.js +7 -0
  63. package/template/bin/cli/lib/docs/generate-api-doc.js +33 -0
  64. package/template/bin/cli/lib/release/generate-release-note.js +3 -0
  65. package/template/bin/cli/lib/version/update-version.js +51 -0
  66. package/template/bin/scripts/commit-msg.js +42 -0
  67. package/template/bin/scripts/pre-commit.js +32 -0
  68. package/template/docs/api/docs.config.js +10 -0
  69. package/template/docs/readme/config.js +22 -0
  70. package/template/docs/readme/readme.js +70 -0
  71. package/template/docs/readme/template.md +53 -0
@@ -0,0 +1,559 @@
1
+ /*!
2
+ * juisy v1.4.0
3
+ * Copyright © 2022-Present Hervé Perchec
4
+ */
5
+
6
+ import { hideBin } from 'yargs/helpers';
7
+ import execa from 'execa';
8
+ import _prompts from 'prompts';
9
+ import chalk from 'chalk';
10
+ import indent from 'indent-string';
11
+ import _stripAnsi from 'strip-ansi';
12
+ import Yargs from 'yargs/yargs';
13
+ import deepmerge from 'deepmerge';
14
+
15
+ class Command {
16
+ /**
17
+ * Creates a Command instance from object (CommandModule)
18
+ * @param {CommandModule} commandObject - The command definition object
19
+ */
20
+ constructor(commandObject) {
21
+ this.command = commandObject.command;
22
+ this.aliases = commandObject.aliases;
23
+ this.describe = commandObject.describe;
24
+ this.deprecated = commandObject.deprecated;
25
+ this.meta = commandObject.meta;
26
+ this.builder = commandObject.builder || ((cli) => cli);
27
+ this.handler = commandObject.handler;
28
+ }
29
+ /**
30
+ * The command
31
+ */
32
+ command;
33
+ /**
34
+ * The aliases
35
+ */
36
+ aliases;
37
+ /**
38
+ * Command description
39
+ */
40
+ describe;
41
+ /**
42
+ * Is deprecated?
43
+ */
44
+ deprecated;
45
+ /**
46
+ * Command meta
47
+ */
48
+ meta;
49
+ /**
50
+ * Command builder
51
+ */
52
+ builder;
53
+ /**
54
+ * Command handler
55
+ */
56
+ handler;
57
+ }
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 {Error} [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 = void 0) {
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
+ const { log, $style } = OutputUtils;
232
+ class InterfaceUtils {
233
+ /**
234
+ * Get root directory path
235
+ * @example
236
+ * import { CLIUtils: { rootDir } } from '@hperchec/juisy'
237
+ * console.log(rootDir) // => 'path/to/your/root/dir'
238
+ */
239
+ static rootDir = process.cwd();
240
+ /**
241
+ * @param {string} bin - Command
242
+ * @param {string[]} args - Same as execa second arg
243
+ * @param {object} [opts] - Options
244
+ * @returns {Promise<object>} The `execa` Promise
245
+ * @description
246
+ * Run command (child_process). See also `execa` package documentation
247
+ * @example
248
+ * const { run } = require('@hperchec/juisy').utils
249
+ * await run('npm', [ 'run', 'test' ], { stdio: 'inherit' })
250
+ */
251
+ static run(bin, args, opts = {}) {
252
+ return execa(bin, args, { stdio: "inherit", cwd: InterfaceUtils.rootDir, ...opts });
253
+ }
254
+ /**
255
+ * @alias utils.abort
256
+ * @param {number} [code] - Code for process.exit() (default: 0)
257
+ * @returns {void}
258
+ * @description
259
+ * Exit process
260
+ * @example
261
+ * const { abort } = require('@hperchec/juisy').utils
262
+ * abort() // => exit process with code 0
263
+ * abort(1) // => error code
264
+ */
265
+ static abort(code = 0) {
266
+ log($style.yellow("Aborted..."));
267
+ process.exit(code);
268
+ }
269
+ /**
270
+ * @alias utils.confirm
271
+ * @param {prompts.PromptObject} question - A prompt question object (see https://gitlab.com/hperchec/juisy/-/blob/main/documentation/utils.md#utilspromptsargs-object)
272
+ * @returns {Promise<boolean>} - True if confirmed
273
+ * @description
274
+ * Demand confirmation with prompts native util. If not confirmed, it will automatically abort the script.
275
+ * @example
276
+ * confirm({ message: 'Confirm to continue' }) // Deny it will abort the script
277
+ */
278
+ static async confirm(question) {
279
+ if (!question) {
280
+ question = {
281
+ type: "confirm",
282
+ name: "yes"
283
+ };
284
+ }
285
+ const { yes } = await InterfaceUtils.prompts([
286
+ {
287
+ message: "Confirm?",
288
+ initial: true,
289
+ ...question,
290
+ type: "confirm",
291
+ name: "yes"
292
+ }
293
+ ]);
294
+ if (!yes) {
295
+ InterfaceUtils.abort();
296
+ } else {
297
+ return true;
298
+ }
299
+ }
300
+ /**
301
+ * See `prompts` package documentation
302
+ * @example
303
+ * const { prompts } = InterfaceUtils
304
+ * // See prompts documentation
305
+ * @see https://www.npmjs.com/package/prompts
306
+ */
307
+ static prompts = _prompts;
308
+ }
309
+
310
+ function wrapCommandBuilder(target, builder) {
311
+ const _target = target || ((cli) => cli);
312
+ return (cli) => {
313
+ return _target(builder(cli));
314
+ };
315
+ }
316
+ function wrapCommandhandler(target, handler) {
317
+ return function(args) {
318
+ handler.call(this, args);
319
+ return target.call(this, args);
320
+ };
321
+ }
322
+
323
+ const visitor$2 = function(commandObject, cli) {
324
+ commandObject.handler = wrapCommandhandler(commandObject.handler, function(args) {
325
+ Object.defineProperty(this, "engine", {
326
+ get() {
327
+ return cli;
328
+ }
329
+ });
330
+ Object.defineProperty(this, "log", {
331
+ get() {
332
+ return (msg, options2 = {}) => {
333
+ OutputUtils.log(msg, {
334
+ ...options2,
335
+ loggerInstance: cli.getInternalMethods().getLoggerInstance()
336
+ });
337
+ };
338
+ }
339
+ });
340
+ });
341
+ return commandObject;
342
+ };
343
+ const options$2 = {};
344
+
345
+ const commandHandlerInjections = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
346
+ __proto__: null,
347
+ options: options$2,
348
+ visitor: visitor$2
349
+ }, Symbol.toStringTag, { value: 'Module' }));
350
+
351
+ const visitor$1 = function(commandObject, cli) {
352
+ if (commandObject.meta) {
353
+ const commandMeta = commandObject.meta;
354
+ commandObject.builder = wrapCommandBuilder(commandObject.builder, function(_cli) {
355
+ _cli._meta = deepmerge(_cli._meta, commandMeta);
356
+ return _cli;
357
+ });
358
+ }
359
+ return commandObject;
360
+ };
361
+ const options$1 = {};
362
+
363
+ const getCommandMeta = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
364
+ __proto__: null,
365
+ options: options$1,
366
+ visitor: visitor$1
367
+ }, Symbol.toStringTag, { value: 'Module' }));
368
+
369
+ const visitor = function(commandObject, engine, options2) {
370
+ const { metaProp, envKey } = options2;
371
+ if (commandObject.meta?.[metaProp]) {
372
+ if (process.env[envKey] === "private") {
373
+ commandObject.builder = wrapCommandBuilder(commandObject.builder, function(cli) {
374
+ cli._isPrivate = true;
375
+ return cli;
376
+ });
377
+ } else {
378
+ return false;
379
+ }
380
+ }
381
+ return commandObject;
382
+ };
383
+ const options = {
384
+ metaProp: "private",
385
+ envKey: "CLI_ENV"
386
+ };
387
+
388
+ const privateCommand = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
389
+ __proto__: null,
390
+ options,
391
+ visitor
392
+ }, Symbol.toStringTag, { value: 'Module' }));
393
+
394
+ const commandVisitors = {
395
+ commandHandlerInjections,
396
+ getCommandMeta,
397
+ privateCommand
398
+ };
399
+
400
+ function createEngine(yargs) {
401
+ const xargs = yargs;
402
+ xargs._isPrivate = false;
403
+ xargs._globalCommandVisitors = {};
404
+ xargs._globalCommandVisitorsEnabled = /* @__PURE__ */ new Set([]);
405
+ xargs._meta = {
406
+ private: false
407
+ };
408
+ const originalCommandMethod = xargs.command;
409
+ xargs.originalCommand = originalCommandMethod;
410
+ xargs.command = command;
411
+ xargs.globalCommandVisitor = globalCommandVisitor;
412
+ xargs.globalCommandVisitorOptions = globalCommandVisitorOptions;
413
+ xargs.hasGlobalCommandVisitor = hasGlobalCommandVisitor;
414
+ xargs.disableGlobalCommandVisitors = disableGlobalCommandVisitors;
415
+ xargs.enableGlobalCommandVisitors = enableGlobalCommandVisitors;
416
+ xargs.isPrivate = isPrivate;
417
+ xargs.getMeta = getMeta;
418
+ return xargs.globalCommandVisitor("command-handler-injections-visitor", commandVisitors.commandHandlerInjections.visitor, commandVisitors.commandHandlerInjections.options).globalCommandVisitor("get-meta-command-visitor", commandVisitors.getCommandMeta.visitor, commandVisitors.getCommandMeta.options).globalCommandVisitor("private-command-visitor", commandVisitors.privateCommand.visitor, commandVisitors.privateCommand.options).strict().help();
419
+ }
420
+ function command(...args) {
421
+ const self = this;
422
+ if (args.length === 1) {
423
+ const visit = (cmdModule) => {
424
+ const cmdObj = {
425
+ ...cmdModule
426
+ };
427
+ let failOnFalsyReturn;
428
+ for (const name of self._globalCommandVisitorsEnabled) {
429
+ const globalVisitor = self._globalCommandVisitors[name];
430
+ if (!globalVisitor(cmdObj, self, globalVisitor.options)) {
431
+ failOnFalsyReturn = true;
432
+ }
433
+ }
434
+ return failOnFalsyReturn ? false : cmdObj;
435
+ };
436
+ if (args[0] instanceof Array) {
437
+ const cmdsArray = [];
438
+ for (const commandModule of args[0]) {
439
+ const visited = visit(commandModule);
440
+ if (visited)
441
+ cmdsArray.push(visited);
442
+ }
443
+ return self.originalCommand(cmdsArray);
444
+ } else {
445
+ const visited = visit(args[0]);
446
+ return visited ? self.originalCommand(visited) : self;
447
+ }
448
+ } else {
449
+ return self.originalCommand(...args);
450
+ }
451
+ }
452
+ function globalCommandVisitor(name, visitor, defaultOptions = {}) {
453
+ this._globalCommandVisitors[name] = visitor;
454
+ return this.enableGlobalCommandVisitors([name]).globalCommandVisitorOptions(name, defaultOptions);
455
+ }
456
+ function globalCommandVisitorOptions(name, options) {
457
+ this._globalCommandVisitors[name].options = {
458
+ ...this._globalCommandVisitors[name].options,
459
+ ...options
460
+ };
461
+ return this;
462
+ }
463
+ function hasGlobalCommandVisitor(name) {
464
+ return Object.keys(this._globalCommandVisitors).includes(name);
465
+ }
466
+ function disableGlobalCommandVisitors(visitors = []) {
467
+ for (const name of visitors) {
468
+ if (this.hasGlobalCommandVisitor(name)) {
469
+ this._globalCommandVisitorsEnabled.delete(name);
470
+ } else {
471
+ throw new Error('Global command visitor: "' + name + '" not defined.');
472
+ }
473
+ }
474
+ return this;
475
+ }
476
+ function enableGlobalCommandVisitors(visitors = []) {
477
+ for (const name of visitors) {
478
+ if (this.hasGlobalCommandVisitor(name)) {
479
+ this._globalCommandVisitorsEnabled.add(name);
480
+ } else {
481
+ throw new Error('Global command visitor: "' + name + '" not defined.');
482
+ }
483
+ }
484
+ return this;
485
+ }
486
+ function isPrivate() {
487
+ return this._isPrivate;
488
+ }
489
+ function getMeta() {
490
+ return this._meta;
491
+ }
492
+
493
+ function CLIFactory(builder) {
494
+ const cli = function(argv) {
495
+ const engine = createEngine(Yargs(argv));
496
+ return builder(engine);
497
+ };
498
+ return cli;
499
+ }
500
+
501
+ async function extractUsage(factory, recursive = false, args = [""], locale = "en") {
502
+ const innerYargs = factory([""]);
503
+ innerYargs.locale(locale);
504
+ const doclet = {
505
+ command: void 0,
506
+ args: void 0,
507
+ aliases: void 0,
508
+ deprecated: false,
509
+ extractedUsage: void 0,
510
+ rawUsage: void 0,
511
+ children: recursive ? {} : void 0
512
+ };
513
+ const parseCallback = function(err, argv, output) {
514
+ if (err)
515
+ throw err;
516
+ const self = this;
517
+ doclet.args = argv._;
518
+ doclet.command = argv._[argv._.length - 1];
519
+ doclet.rawUsage = output;
520
+ const extractedUsage = doclet.extractedUsage = {};
521
+ extractedUsage.demandedCommands = self.getDemandedCommands();
522
+ extractedUsage.demandedOptions = self.getDemandedOptions();
523
+ extractedUsage.deprecatedOptions = self.getDeprecatedOptions();
524
+ extractedUsage.groups = self.getGroups();
525
+ extractedUsage.options = self.getOptions();
526
+ const internalMethods = self.getInternalMethods();
527
+ const usageInstance = internalMethods.getUsageInstance();
528
+ extractedUsage.usages = usageInstance.getUsage();
529
+ const commandInstance = internalMethods.getCommandInstance();
530
+ doclet.aliases = commandInstance.aliasMap;
531
+ const childCommandsFromHandlers = commandInstance.handlers;
532
+ const childCommandsFromUsage = usageInstance.getCommands();
533
+ extractedUsage.commands = Object.keys(childCommandsFromHandlers).reduce((accumulator, handlerKey) => {
534
+ const [cmd, description, isDefault, aliases, deprecated] = childCommandsFromUsage.find((command) => {
535
+ return command[0] === childCommandsFromHandlers[handlerKey].original;
536
+ });
537
+ accumulator[handlerKey] = { cmd, description, isDefault, aliases, deprecated };
538
+ return accumulator;
539
+ }, {});
540
+ };
541
+ await innerYargs.parseAsync(args, { help: true }, parseCallback);
542
+ if (recursive) {
543
+ for (const childCommand in doclet.extractedUsage.commands) {
544
+ doclet.children[childCommand] = await extractUsage(factory, true, [...args.filter((a) => a !== ""), childCommand], locale);
545
+ }
546
+ }
547
+ return doclet;
548
+ }
549
+
550
+ globalThis.CLI = {
551
+ helpers: {
552
+ hideBin
553
+ },
554
+ Command,
555
+ InterfaceUtils,
556
+ OutputUtils
557
+ };
558
+
559
+ export { CLIFactory, Command, InterfaceUtils, OutputUtils, extractUsage };
@@ -0,0 +1,112 @@
1
+ import { Argv, CommandModule as YargsCommandModule, CommandBuilder, MiddlewareFunction } from 'yargs';
2
+ /**
3
+ * An object whose all properties have the same type.
4
+ */
5
+ type Dictionary<T = any> = {
6
+ [key: string]: T;
7
+ };
8
+ /**
9
+ * An array whose first element is not undefined.
10
+ */
11
+ type NotEmptyArray<T = any> = [T, ...T[]];
12
+ /** Shims for private yargs types */
13
+ interface Positional {
14
+ cmd: NotEmptyArray<string>;
15
+ variadic: boolean;
16
+ }
17
+ export interface YargsCommandHandler {
18
+ builder: CommandBuilder;
19
+ demanded: Positional[];
20
+ deprecated?: boolean;
21
+ description?: string | false;
22
+ handler: CommandModule['handler'];
23
+ middlewares: MiddlewareFunction[];
24
+ optional: Positional[];
25
+ original: string;
26
+ }
27
+ /** ---------------------------- */
28
+ /**
29
+ * Our custon extended Yargs type
30
+ */
31
+ export interface CLIEngine extends Argv {
32
+ _isPrivate: boolean;
33
+ _globalCommandVisitors: Record<string, CommandVisitor>;
34
+ _globalCommandVisitorsEnabled: Set<string>;
35
+ _meta: Record<string, any> & {
36
+ private: boolean;
37
+ };
38
+ originalCommand: Argv['command'];
39
+ globalCommandVisitor: (name: string, visitor: CommandVisitor, defaultOptions: any) => this;
40
+ globalCommandVisitorOptions: (name: string, options: Record<any, any>) => this;
41
+ hasGlobalCommandVisitor: (name: string) => boolean;
42
+ disableGlobalCommandVisitors: (visitors: string[]) => this;
43
+ enableGlobalCommandVisitors: (visitors: string[]) => this;
44
+ isPrivate: () => this['_isPrivate'];
45
+ getMeta: () => this['_meta'];
46
+ getDemandedCommands: () => Dictionary<{
47
+ min: number;
48
+ max: number;
49
+ minMsg?: string | null;
50
+ maxMsg?: string | null;
51
+ }>;
52
+ getDemandedOptions: () => Dictionary<string | undefined>;
53
+ getDeprecatedOptions: () => Dictionary<string | boolean | undefined>;
54
+ getGroups: () => Dictionary<string[]>;
55
+ getOptions: () => Record<string, any>;
56
+ getInternalMethods: () => {
57
+ getCommandInstance(): any;
58
+ getContext(): any;
59
+ getHasOutput(): boolean;
60
+ getLoggerInstance(): any;
61
+ getParseContext(): any;
62
+ getParserConfiguration(): any;
63
+ getUsageConfiguration(): any;
64
+ getUsageInstance(): any;
65
+ getValidationInstance(): any;
66
+ hasParseCallback(): any;
67
+ isGlobalContext(): any;
68
+ postProcess(argv: any | Promise<any>, populateDoubleDash: boolean, calledFromCommand: boolean, runGlobalMiddleware: boolean): any;
69
+ reset(aliases?: any): any;
70
+ runValidation(aliases: Dictionary<string[]>, positionalMap: Dictionary<string[]>, parseErrors: Error | null, isDefaultCommand?: boolean): (argv: any) => void;
71
+ runYargsParserAndExecuteCommands(args: string | string[] | null, shortCircuit?: boolean | null, calledFromCommand?: boolean, commandIndex?: number, helpOnly?: boolean): any | Promise<any>;
72
+ setHasOutput(): void;
73
+ };
74
+ }
75
+ export type CommandModule = {
76
+ /** array of strings (or a single string) representing aliases of `exports.command`, positional args defined in an alias are ignored */
77
+ aliases: YargsCommandModule['aliases'];
78
+ /** string (or array of strings) that executes this command when given on the command line, first string may contain positional args */
79
+ command: YargsCommandModule['command'];
80
+ /** boolean (or string) to show deprecation notice */
81
+ deprecated: YargsCommandModule['deprecated'];
82
+ /** string used as the description for the command in help text, use `false` for a hidden command */
83
+ describe: YargsCommandModule['describe'];
84
+ /** a function which will be passed the parsed argv. */
85
+ handler: (this: YargsCommandHandler & {
86
+ engine?: CLIEngine;
87
+ log?: (msg?: string, options?: any) => void;
88
+ }, argv: Parameters<YargsCommandModule['handler']>[0]) => ReturnType<YargsCommandModule['handler']>;
89
+ /** object declaring the options the command accepts, or a function accepting and returning a yargs instance */
90
+ builder: (cli: CLIEngine) => CLIEngine | PromiseLike<CLIEngine>;
91
+ meta: Record<string, any>;
92
+ };
93
+ export type CLIBuilder = (cli: CLIEngine) => CLIEngine;
94
+ /**
95
+ * Custom global command visitor callback.
96
+ */
97
+ export type CommandVisitor = {
98
+ options?: Record<any, any>;
99
+ } & ((
100
+ /**
101
+ * The exported command object
102
+ */
103
+ commandObject: CommandModule,
104
+ /**
105
+ * The current CLI instance
106
+ */
107
+ engine: CLIEngine,
108
+ /**
109
+ * The default options to set
110
+ */
111
+ options: any) => false | CommandModule);
112
+ export {};
@@ -0,0 +1,19 @@
1
+ import { CommandModule, CLIEngine } from './types';
2
+ /**
3
+ * @ignore
4
+ * @param target - The target builder
5
+ * @param builder - The wrap
6
+ * @description
7
+ * Wrap command builder (target) with builder passed as second parameter
8
+ * that will be called before target. Target can be undefined
9
+ */
10
+ export declare function wrapCommandBuilder(target: CommandModule['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: CommandModule['handler'], handler: CommandModule['handler']): CommandModule["handler"];