@visulima/cerebro 1.1.49 → 1.1.50

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.
@@ -1,1240 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4
-
5
- const node_process = require('node:process');
6
- const boxen = require('@visulima/boxen');
7
- const colorize = require('@visulima/colorize');
8
- const processor = require('@visulima/pail/processor');
9
- const server = require('@visulima/pail/server');
10
- const commandLineArgs = require('command-line-args');
11
- const CliTable3 = require('cli-table3');
12
- const template = require('@visulima/colorize/template');
13
- const os = require('node:os');
14
- const fastestLevenshtein = require('fastest-levenshtein');
15
-
16
- const _interopDefaultCompat = e => e && typeof e === 'object' && 'default' in e ? e.default : e;
17
-
18
- const commandLineArgs__default = /*#__PURE__*/_interopDefaultCompat(commandLineArgs);
19
- const CliTable3__default = /*#__PURE__*/_interopDefaultCompat(CliTable3);
20
- const template__default = /*#__PURE__*/_interopDefaultCompat(template);
21
- const os__default = /*#__PURE__*/_interopDefaultCompat(os);
22
-
23
- var __defProp$m = Object.defineProperty;
24
- var __name$m = (target, value) => __defProp$m(target, "name", { value, configurable: true });
25
- const UPPERCASE = /[\p{Lu}]/u;
26
- const LOWERCASE = /[\p{Ll}]/u;
27
- const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
28
- const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
29
- const SEPARATORS = /[_.\- ]+/;
30
- const LEADING_SEPARATORS = new RegExp("^" + SEPARATORS.source);
31
- const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, "gu");
32
- const NUMBERS_AND_IDENTIFIER = new RegExp("\\d+" + IDENTIFIER.source, "gu");
33
- const preserveCamelCase = /* @__PURE__ */ __name$m((string, toLowerCase, toUpperCase, preserveConsecutiveUppercase2) => {
34
- let isLastCharLower = false;
35
- let isLastCharUpper = false;
36
- let isLastLastCharUpper = false;
37
- let isLastLastCharPreserved = false;
38
- for (let index = 0; index < string.length; index++) {
39
- const character = string[index];
40
- isLastLastCharPreserved = index > 2 ? string[index - 3] === "-" : true;
41
- if (isLastCharLower && UPPERCASE.test(character)) {
42
- string = string.slice(0, index) + "-" + string.slice(index);
43
- isLastCharLower = false;
44
- isLastLastCharUpper = isLastCharUpper;
45
- isLastCharUpper = true;
46
- index++;
47
- } else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character) && (!isLastLastCharPreserved || preserveConsecutiveUppercase2)) {
48
- string = string.slice(0, index - 1) + "-" + string.slice(index - 1);
49
- isLastLastCharUpper = isLastCharUpper;
50
- isLastCharUpper = false;
51
- isLastCharLower = true;
52
- } else {
53
- isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
54
- isLastLastCharUpper = isLastCharUpper;
55
- isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
56
- }
57
- }
58
- return string;
59
- }, "preserveCamelCase");
60
- const preserveConsecutiveUppercase = /* @__PURE__ */ __name$m((input, toLowerCase) => {
61
- LEADING_CAPITAL.lastIndex = 0;
62
- return input.replaceAll(LEADING_CAPITAL, (match) => toLowerCase(match));
63
- }, "preserveConsecutiveUppercase");
64
- const postProcess = /* @__PURE__ */ __name$m((input, toUpperCase) => {
65
- SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
66
- NUMBERS_AND_IDENTIFIER.lastIndex = 0;
67
- return input.replaceAll(NUMBERS_AND_IDENTIFIER, (match, pattern, offset) => ["_", "-"].includes(input.charAt(offset + match.length)) ? match : toUpperCase(match)).replaceAll(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier));
68
- }, "postProcess");
69
- function camelCase(input, options) {
70
- if (!(typeof input === "string" || Array.isArray(input))) {
71
- throw new TypeError("Expected the input to be `string | string[]`");
72
- }
73
- options = {
74
- pascalCase: false,
75
- preserveConsecutiveUppercase: false,
76
- ...options
77
- };
78
- if (Array.isArray(input)) {
79
- input = input.map((x) => x.trim()).filter((x) => x.length).join("-");
80
- } else {
81
- input = input.trim();
82
- }
83
- if (input.length === 0) {
84
- return "";
85
- }
86
- const toLowerCase = options.locale === false ? (string) => string.toLowerCase() : (string) => string.toLocaleLowerCase(options.locale);
87
- const toUpperCase = options.locale === false ? (string) => string.toUpperCase() : (string) => string.toLocaleUpperCase(options.locale);
88
- if (input.length === 1) {
89
- if (SEPARATORS.test(input)) {
90
- return "";
91
- }
92
- return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
93
- }
94
- const hasUpperCase = input !== toLowerCase(input);
95
- if (hasUpperCase) {
96
- input = preserveCamelCase(input, toLowerCase, toUpperCase, options.preserveConsecutiveUppercase);
97
- }
98
- input = input.replace(LEADING_SEPARATORS, "");
99
- input = options.preserveConsecutiveUppercase ? preserveConsecutiveUppercase(input, toLowerCase) : toLowerCase(input);
100
- if (options.pascalCase) {
101
- input = toUpperCase(input.charAt(0)) + input.slice(1);
102
- }
103
- return postProcess(input, toUpperCase);
104
- }
105
- __name$m(camelCase, "camelCase");
106
-
107
- const defaultOptions = [
108
- {
109
- description: "Turn on verbose output",
110
- group: "global",
111
- name: "verbose",
112
- type: Boolean
113
- },
114
- {
115
- description: "Turn on debugging output",
116
- group: "global",
117
- name: "debug",
118
- type: Boolean
119
- },
120
- {
121
- alias: "h",
122
- description: "Print out helpful usage information",
123
- group: "global",
124
- name: "help",
125
- type: Boolean
126
- },
127
- {
128
- alias: "q",
129
- description: "Silence output",
130
- group: "global",
131
- name: "quiet",
132
- type: Boolean
133
- },
134
- {
135
- alias: "V",
136
- description: "Print version info",
137
- group: "global",
138
- name: "version",
139
- type: Boolean
140
- },
141
- {
142
- description: "Turn off colored output",
143
- group: "global",
144
- name: "no-color",
145
- type: Boolean
146
- },
147
- {
148
- description: "Force colored output",
149
- group: "global",
150
- name: "color",
151
- type: Boolean
152
- }
153
- ];
154
-
155
- var __defProp$l = Object.defineProperty;
156
- var __name$l = (target, value) => __defProp$l(target, "name", { value, configurable: true });
157
- const templateFormat = /* @__PURE__ */ __name$l((string_) => {
158
- if (string_) {
159
- return template__default(Object.assign([], { raw: [string_.replaceAll("`", "\\`")] }));
160
- }
161
- return "";
162
- }, "templateFormat");
163
-
164
- var __defProp$k = Object.defineProperty;
165
- var __name$k = (target, value) => __defProp$k(target, "name", { value, configurable: true });
166
- class BaseSection {
167
- static {
168
- __name$k(this, "BaseSection");
169
- }
170
- lines;
171
- constructor() {
172
- this.lines = [];
173
- }
174
- add(line) {
175
- this.lines.push(line);
176
- }
177
- toString() {
178
- return this.lines.join(os__default.EOL);
179
- }
180
- header(text) {
181
- this.add(colorize.bold(text));
182
- this.lines.push("");
183
- }
184
- }
185
-
186
- var __defProp$j = Object.defineProperty;
187
- var __name$j = (target, value) => __defProp$j(target, "name", { value, configurable: true });
188
- const defaultTableOptions = {
189
- chars: {
190
- bottom: "",
191
- "bottom-left": "",
192
- "bottom-mid": "",
193
- "bottom-right": "",
194
- left: " ",
195
- "left-mid": "",
196
- mid: "",
197
- "mid-mid": "",
198
- middle: " ",
199
- right: "",
200
- "right-mid": "",
201
- top: "",
202
- "top-left": "",
203
- "top-mid": "",
204
- "top-right": ""
205
- },
206
- colWidths: [40, 60],
207
- style: { border: [], compact: true, head: [], "padding-left": 2, "padding-right": 1 },
208
- wordWrap: true
209
- };
210
- class ContentSection extends BaseSection {
211
- static {
212
- __name$j(this, "ContentSection");
213
- }
214
- // eslint-disable-next-line sonarjs/cognitive-complexity
215
- constructor(section) {
216
- super();
217
- if (section.header) {
218
- this.header(templateFormat(section.header));
219
- }
220
- if (section.content) {
221
- if (section.raw) {
222
- if (Array.isArray(section.content) && section.content.every((value) => typeof value === "string")) {
223
- section.content.forEach((row) => {
224
- if (Array.isArray(row)) {
225
- row.forEach((cell) => this.add(templateFormat(cell)));
226
- } else {
227
- this.add(templateFormat(row));
228
- }
229
- });
230
- } else if (typeof section.content === "string") {
231
- this.add(templateFormat(section.content));
232
- } else {
233
- throw new TypeError("Invalid raw content, must be a string or array of strings.");
234
- }
235
- } else {
236
- this.add(this.getContentLines(section.content));
237
- }
238
- this.add("");
239
- }
240
- }
241
- // eslint-disable-next-line sonarjs/cognitive-complexity,class-methods-use-this
242
- getContentLines(content) {
243
- if (typeof content === "string") {
244
- const table = new CliTable3__default({
245
- ...defaultTableOptions,
246
- colWidths: [80]
247
- });
248
- table.push([templateFormat(content)]);
249
- return table.toString();
250
- }
251
- if (Array.isArray(content) && // eslint-disable-next-line @typescript-eslint/no-shadow
252
- content.every((value) => typeof value === "string" || Array.isArray(value) && value.every((value2) => typeof value2 === "string"))) {
253
- const table = new CliTable3__default({
254
- ...defaultTableOptions
255
- });
256
- content.forEach((row) => {
257
- if (Array.isArray(row)) {
258
- table.push(row.map((cell) => templateFormat(cell)));
259
- } else {
260
- table.push([templateFormat(row)]);
261
- }
262
- });
263
- return table.toString();
264
- }
265
- if (typeof content === "object") {
266
- const contentObject = content;
267
- if (!contentObject.options || !contentObject.data) {
268
- throw new Error(`Must have an "options" or "data" property
269
- ${JSON.stringify(content)}`);
270
- }
271
- const table = new CliTable3__default({
272
- ...defaultTableOptions,
273
- ...contentObject.options,
274
- style: { ...defaultTableOptions.style, ...contentObject.options.style }
275
- });
276
- contentObject.data.forEach((row) => {
277
- if (Array.isArray(row)) {
278
- table.push(row.map((cell) => templateFormat(cell)));
279
- } else {
280
- table.push([templateFormat(row)]);
281
- }
282
- });
283
- return table.toString();
284
- }
285
- throw new Error(`invalid input - 'content' must be a string, array of strings or a object:
286
-
287
- ${JSON.stringify(content)}`);
288
- }
289
- }
290
-
291
- var __defProp$i = Object.defineProperty;
292
- var __name$i = (target, value) => __defProp$i(target, "name", { value, configurable: true });
293
- class OptionListSection extends BaseSection {
294
- static {
295
- __name$i(this, "OptionListSection");
296
- }
297
- // eslint-disable-next-line sonarjs/cognitive-complexity
298
- constructor(data) {
299
- super();
300
- let definitions = data.optionList ?? [];
301
- const hide = Array.isArray(data.hide) ? data.hide : [data.hide].filter(Boolean);
302
- const groups = Array.isArray(data.group) ? data.group : [data.group].filter(Boolean);
303
- if (hide.length > 0) {
304
- definitions = definitions.filter((definition) => !hide.includes(definition.name));
305
- }
306
- if (data.header) {
307
- this.header(templateFormat(data.header));
308
- }
309
- if (groups.length > 0) {
310
- definitions = definitions.filter((definition) => {
311
- const noGroupMatch = groups.includes("_none") && !definition.group;
312
- const groupMatch = this.intersect(Array.isArray(definition.group) ? definition.group : [definition.group], groups);
313
- return noGroupMatch || groupMatch ? definition : void 0;
314
- });
315
- }
316
- const table = new CliTable3__default({
317
- chars: {
318
- bottom: "",
319
- "bottom-left": "",
320
- "bottom-mid": "",
321
- "bottom-right": "",
322
- left: " ",
323
- "left-mid": "",
324
- mid: "",
325
- "mid-mid": "",
326
- middle: " ",
327
- right: "",
328
- "right-mid": "",
329
- top: "",
330
- "top-left": "",
331
- "top-mid": "",
332
- "top-right": ""
333
- },
334
- colWidths: [40, 40],
335
- style: { "padding-left": 2, "padding-right": 1 },
336
- wordWrap: true
337
- });
338
- definitions.forEach(
339
- (definition) => table.push([this.getOptionNames(definition, data.reverseNameOrder ?? false, data.isArgument ?? false), templateFormat(definition.description)])
340
- );
341
- this.add(table.toString());
342
- this.lines.push("");
343
- }
344
- // eslint-disable-next-line class-methods-use-this,sonarjs/cognitive-complexity,@typescript-eslint/no-explicit-any
345
- getOptionNames(definition, reverseNameOrder, isArgument) {
346
- if (!definition.name) {
347
- throw new TypeError("Invalid option definition, name is required.");
348
- }
349
- let type = definition.type ? definition.type.name.toLowerCase() : "string";
350
- const multiple = definition.multiple || definition.lazyMultiple ? "[]" : "";
351
- type = templateFormat(definition.typeLabel ?? `{underline ${type}${multiple}}`);
352
- let result;
353
- if (definition.alias) {
354
- if (definition.name) {
355
- const name = isArgument ? definition.name : `{yellow --${definition.name}}`;
356
- result = reverseNameOrder ? templateFormat(`{bold ${name}}, {bold -${definition.alias}} ${type}`) : templateFormat(`{bold -${definition.alias}}, {bold ${name}} ${type}`);
357
- } else if (reverseNameOrder) {
358
- result = templateFormat(`{bold -${definition.alias}} ${type}`);
359
- } else {
360
- result = templateFormat(`{bold -${definition.alias}} ${type}`);
361
- }
362
- } else {
363
- result = templateFormat(`{bold ${isArgument ? definition.name : `{yellow --${definition.name}}`}} ${type}`);
364
- }
365
- return result;
366
- }
367
- // eslint-disable-next-line class-methods-use-this
368
- intersect(array1, array2) {
369
- return array1.some((item1) => array2.includes(item1));
370
- }
371
- }
372
-
373
- var __defProp$h = Object.defineProperty;
374
- var __name$h = (target, value) => __defProp$h(target, "name", { value, configurable: true });
375
- const commandLineUsage = /* @__PURE__ */ __name$h((sections) => {
376
- const lines = Array.isArray(sections) ? sections : [sections];
377
- if (lines.length === 0) {
378
- return "";
379
- }
380
- return `
381
- ${sections.map((section) => {
382
- if (section.optionList) {
383
- return new OptionListSection(section).toString();
384
- }
385
- return new ContentSection(section).toString();
386
- }).join("\n")}`;
387
- }, "commandLineUsage");
388
-
389
- var __defProp$g = Object.defineProperty;
390
- var __name$g = (target, value) => __defProp$g(target, "name", { value, configurable: true });
391
- const EMPTY_GROUP_KEY = "__Other";
392
- const upperFirstChar = /* @__PURE__ */ __name$g((string_) => string_.charAt(0).toUpperCase() + string_.slice(1), "upperFirstChar");
393
- const printGeneralHelp = /* @__PURE__ */ __name$g((logger, runtime, commands, groupOption) => {
394
- logger.debug("no command given, printing general help...");
395
- let filteredCommands = [...new Set(commands.values())].filter((command) => !command.hidden);
396
- if (groupOption) {
397
- filteredCommands = filteredCommands.filter((command) => command.group === groupOption);
398
- }
399
- const groupedCommands = filteredCommands.reduce((accumulator, command) => {
400
- const group = command.group ?? EMPTY_GROUP_KEY;
401
- if (!accumulator[group]) {
402
- accumulator[group] = [];
403
- }
404
- accumulator[group].push(command);
405
- return accumulator;
406
- }, {});
407
- logger.raw(
408
- commandLineUsage(
409
- [
410
- {
411
- content: `{cyan ${runtime.getCliName()}} {green <command>} [positional arguments] {yellow [options]}`,
412
- header: "{inverse.cyan Usage }"
413
- },
414
- ...Object.keys(groupedCommands).map((key) => {
415
- return {
416
- // eslint-disable-next-line security/detect-object-injection
417
- content: groupedCommands[key].map((command) => {
418
- let aliases = "";
419
- if (typeof command.alias === "string") {
420
- aliases = command.alias;
421
- } else if (Array.isArray(command.alias)) {
422
- aliases = command.alias.join(", ");
423
- }
424
- if (aliases !== "") {
425
- aliases = ` [${aliases}]`;
426
- }
427
- return [`{green ${command.name}} ${aliases}`, command.description ?? ""];
428
- }),
429
- header: key === EMPTY_GROUP_KEY || groupOption ? `{inverse.green Available${groupOption ? ` ${upperFirstChar(groupOption)}` : ""} Commands }` : ` {inverse.green ${upperFirstChar(key)} }`
430
- };
431
- }),
432
- commands.has("help") ? {
433
- header: "{inverse.yellow Command Options }",
434
- optionList: commands.get("help").options?.filter((option) => !option.hidden)
435
- } : void 0,
436
- { header: "{inverse.yellow Global Options }", optionList: defaultOptions },
437
- {
438
- content: `Run "{cyan ${runtime.getCliName()}} {green help <command>}" or "{cyan ${runtime.getCliName()}} {green <command>} {yellow --help}" for help with a specific command.`,
439
- raw: true
440
- }
441
- ].filter(Boolean)
442
- )
443
- );
444
- }, "printGeneralHelp");
445
- const printCommandHelp = /* @__PURE__ */ __name$g((logger, runtime, commands, name) => {
446
- const command = commands.get(name);
447
- const usageGroups = [];
448
- usageGroups.push({
449
- content: `{cyan ${runtime.getCliName()}} {green ${command.name}}${command.argument ? " [positional arguments]" : ""}${command.options ? " [options]" : ""}`,
450
- header: "{inverse.cyan Usage }"
451
- });
452
- if (command.description) {
453
- usageGroups.push({ content: command.description, header: "{inverse.green Description }" });
454
- }
455
- if (command.argument) {
456
- usageGroups.push({ header: "Command Positional Arguments", isArgument: true, optionList: [command.argument] });
457
- }
458
- if (Array.isArray(command.options) && command.options.length > 0) {
459
- usageGroups.push({
460
- header: "{inverse.yellow Command Options }",
461
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
462
- optionList: command.options.filter((option) => !option.hidden)
463
- });
464
- }
465
- usageGroups.push({ header: "{inverse.yellow Global Options }", optionList: defaultOptions });
466
- if (command.alias !== void 0 && command.alias.length > 0) {
467
- let alias = command.alias;
468
- if (typeof command.alias === "string") {
469
- alias = [command.alias];
470
- }
471
- usageGroups.splice(1, 0, {
472
- content: alias,
473
- header: "Alias(es)"
474
- });
475
- }
476
- if (Array.isArray(command.examples) && command.examples.length > 0) {
477
- usageGroups.push({
478
- content: command.examples,
479
- header: "Examples"
480
- });
481
- }
482
- logger.raw(commandLineUsage(usageGroups));
483
- }, "printCommandHelp");
484
- class HelpCommand {
485
- static {
486
- __name$g(this, "HelpCommand");
487
- }
488
- name = "help";
489
- options = [
490
- {
491
- description: "Display only the specified group",
492
- name: "group",
493
- type: String
494
- }
495
- ];
496
- commands;
497
- constructor(commands) {
498
- this.commands = commands;
499
- }
500
- execute(toolbox) {
501
- const { commandName, logger, options, runtime } = toolbox;
502
- const { footer, header } = runtime.getCommandSection();
503
- if (header) {
504
- logger.raw(templateFormat(header));
505
- }
506
- if (commandName === "help") {
507
- printGeneralHelp(logger, runtime, this.commands, options?.group);
508
- } else {
509
- printCommandHelp(logger, runtime, this.commands, commandName);
510
- }
511
- if (footer) {
512
- logger.raw(templateFormat(footer));
513
- }
514
- }
515
- }
516
-
517
- var __defProp$f = Object.defineProperty;
518
- var __name$f = (target, value) => __defProp$f(target, "name", { value, configurable: true });
519
- const VersionCommand = {
520
- alias: ["v", "V"],
521
- description: "Output the version number",
522
- execute: /* @__PURE__ */ __name$f(({ logger, runtime }) => {
523
- const version = runtime.getPackageVersion();
524
- if (version === void 0) {
525
- logger.warn("Unknown version");
526
- logger.debug("The version number was not provided by the cli constructor.");
527
- } else {
528
- logger.info(version);
529
- }
530
- }, "execute"),
531
- name: "version",
532
- options: [],
533
- usage: []
534
- };
535
-
536
- const VERBOSITY_QUIET = 16;
537
- const VERBOSITY_NORMAL = 32;
538
- const VERBOSITY_VERBOSE = 64;
539
- const VERBOSITY_DEBUG = 128;
540
- const POSITIONALS_KEY = "positionals";
541
-
542
- var __defProp$e = Object.defineProperty;
543
- var __name$e = (target, value) => __defProp$e(target, "name", { value, configurable: true });
544
- class EmptyToolbox {
545
- static {
546
- __name$e(this, "EmptyToolbox");
547
- }
548
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
549
- result;
550
- argv;
551
- options;
552
- argument;
553
- command;
554
- commandName;
555
- runtime;
556
- logger;
557
- constructor(commandName, command) {
558
- this.commandName = commandName;
559
- this.command = command;
560
- }
561
- }
562
-
563
- var __defProp$d = Object.defineProperty;
564
- var __name$d = (target, value) => __defProp$d(target, "name", { value, configurable: true });
565
- const checkNodeVersion = /* @__PURE__ */ __name$d(() => {
566
- const minNodeVersion = process.env.CEREBRO_MIN_NODE_VERSION ? Number(process.env.CEREBRO_MIN_NODE_VERSION) : 18;
567
- const nodeVersion = process.version.replace("v", "");
568
- const major = Number(/v([^.]+)/.exec(process.version)[1]);
569
- if (major < minNodeVersion) {
570
- console.log(
571
- `cerebro supports a minimum Node version of ${minNodeVersion}. You have ${nodeVersion}. Read our version support policy: https://github.com/visulima/visulima#supported-nodejs-versions`
572
- );
573
- process.exit(1);
574
- }
575
- }, "checkNodeVersion");
576
-
577
- var __defProp$c = Object.defineProperty;
578
- var __name$c = (target, value) => __defProp$c(target, "name", { value, configurable: true });
579
- const argumentNameRegExp = /^-{1,2}(\w+)(=(\w+))?$/;
580
- const getParameterOption = /* @__PURE__ */ __name$c((argument, options) => {
581
- const regExpResult = argumentNameRegExp.exec(argument);
582
- if (regExpResult == null) {
583
- return {};
584
- }
585
- const nameOrAlias = regExpResult[1];
586
- const option = options.find((o) => o.name === nameOrAlias || o.alias === nameOrAlias);
587
- if (option !== void 0) {
588
- return { argName: option.name, argValue: regExpResult[3], option };
589
- }
590
- return {};
591
- }, "getParameterOption");
592
-
593
- var __defProp$b = Object.defineProperty;
594
- var __name$b = (target, value) => __defProp$b(target, "name", { value, configurable: true });
595
- const isBoolean = /* @__PURE__ */ __name$b((option) => option.type?.name === "Boolean", "isBoolean");
596
-
597
- var __defProp$a = Object.defineProperty;
598
- var __name$a = (target, value) => __defProp$a(target, "name", { value, configurable: true });
599
- const convertType = /* @__PURE__ */ __name$a((value, option) => {
600
- if (option.type === void 0) {
601
- return value;
602
- }
603
- if (option.type.name === "Boolean") {
604
- if (value === "true" || value === "1") {
605
- return option.type(true);
606
- }
607
- if (value === "false" || value === "0") {
608
- return option.type(false);
609
- }
610
- }
611
- return option.type(value);
612
- }, "convertType");
613
- const booleanValue$1 = /* @__PURE__ */ new Set(["1", "0", "true", "false"]);
614
- const getBooleanValues = /* @__PURE__ */ __name$a((arguments_, options) => {
615
- const getBooleanValue = /* @__PURE__ */ __name$a((argumentsAndLastOption, argument) => {
616
- const { argName, argValue, option } = getParameterOption(argument, options);
617
- const { lastOption } = argumentsAndLastOption;
618
- if (option && isBoolean(option) && argValue && argName) {
619
- argumentsAndLastOption.partial[argName] = convertType(argValue, option);
620
- } else if (argumentsAndLastOption.lastName && lastOption && isBoolean(lastOption) && booleanValue$1.has(argument)) {
621
- argumentsAndLastOption.partial[argumentsAndLastOption.lastName] = convertType(
622
- argument,
623
- lastOption
624
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
625
- );
626
- }
627
- return { lastName: argName, lastOption: option, partial: argumentsAndLastOption.partial };
628
- }, "getBooleanValue");
629
- return arguments_.reduce(getBooleanValue, { partial: {} }).partial;
630
- }, "getBooleanValues");
631
-
632
- var __defProp$9 = Object.defineProperty;
633
- var __name$9 = (target, value) => __defProp$9(target, "name", { value, configurable: true });
634
- const getTypeLabel = /* @__PURE__ */ __name$9((definition) => {
635
- let typeLabel = definition.type ? definition.type.name.toLowerCase() : "string";
636
- const multiple = definition.multiple ?? definition.lazyMultiple ? "[]" : "";
637
- if (typeLabel) {
638
- typeLabel = typeLabel === "boolean" ? "" : `{underline ${typeLabel}${multiple}}`;
639
- }
640
- return typeLabel;
641
- }, "getTypeLabel");
642
- const mapOptionTypeLabel = /* @__PURE__ */ __name$9((definition) => {
643
- if (isBoolean(definition)) {
644
- return definition;
645
- }
646
- definition.typeLabel = definition.typeLabel ?? getTypeLabel(definition);
647
- if (definition.defaultOption) {
648
- definition.typeLabel = `${definition.typeLabel} (D)`;
649
- }
650
- if (definition.required) {
651
- definition.typeLabel = `${definition.typeLabel} (R)`;
652
- }
653
- return definition;
654
- }, "mapOptionTypeLabel");
655
-
656
- var __defProp$8 = Object.defineProperty;
657
- var __name$8 = (target, value) => __defProp$8(target, "name", { value, configurable: true });
658
- const booleanValue = /* @__PURE__ */ new Set(["1", "0", "true", "false"]);
659
- const removeBooleanValues = /* @__PURE__ */ __name$8((arguments_, options) => {
660
- const removeBooleanArguments = /* @__PURE__ */ __name$8((argumentsAndLastValue, argument) => {
661
- const { argValue, option } = getParameterOption(argument, options);
662
- const { lastOption } = argumentsAndLastValue;
663
- if (lastOption && isBoolean(lastOption) && booleanValue.has(argument)) {
664
- const copiedArguments_ = [...argumentsAndLastValue.args];
665
- copiedArguments_.pop();
666
- return { args: copiedArguments_ };
667
- }
668
- if (option && isBoolean(option) && argValue) {
669
- return { args: argumentsAndLastValue.args };
670
- }
671
- return { args: [...argumentsAndLastValue.args, argument], lastOption: option };
672
- }, "removeBooleanArguments");
673
- return arguments_.reduce(removeBooleanArguments, { args: [] }).args;
674
- }, "removeBooleanValues");
675
-
676
- var __defProp$7 = Object.defineProperty;
677
- var __name$7 = (target, value) => __defProp$7(target, "name", { value, configurable: true });
678
- const isShort = new RegExp(/^-([^\d-])$/);
679
- const isLong = new RegExp(/^--(\S+)/);
680
- const isCombined = new RegExp(/^-([^\d-]{2,})$/);
681
- const isOption = /* @__PURE__ */ __name$7((argument) => isShort.test(argument) || isLong.test(argument) || isCombined.test(argument), "isOption");
682
- const commandLineCommands = /* @__PURE__ */ __name$7((commands, argv) => {
683
- const command = argv[0] && isOption(argv[0]) || argv.length === 0 ? null : argv.shift() ?? null;
684
- if (!commands.includes(command)) {
685
- const error = new Error(`Command not recognised: ${command}`);
686
- error.command = command;
687
- error.name = "INVALID_COMMAND";
688
- throw error;
689
- }
690
- return { argv, command };
691
- }, "commandLineCommands");
692
-
693
- var __defProp$6 = Object.defineProperty;
694
- var __name$6 = (target, value) => __defProp$6(target, "name", { value, configurable: true });
695
- const isSimilar = /* @__PURE__ */ __name$6((string1, string2) => fastestLevenshtein.distance(string1, string2) <= string1.length / 3 || string2.includes(string1), "isSimilar");
696
- const findAlternatives = /* @__PURE__ */ __name$6((string, array) => {
697
- const id = string.toLowerCase();
698
- return array.filter((nextId) => isSimilar(nextId.toLowerCase(), id));
699
- }, "findAlternatives");
700
-
701
- var __defProp$5 = Object.defineProperty;
702
- var __name$5 = (target, value) => __defProp$5(target, "name", { value, configurable: true });
703
- const listMissingArguments = /* @__PURE__ */ __name$5((commandLineConfig, parsedArguments) => commandLineConfig.filter((config) => config.required && parsedArguments[config.name] == null).filter((config) => {
704
- if (config.type?.name === "Boolean") {
705
- parsedArguments[config.name] = false;
706
- return false;
707
- }
708
- return true;
709
- }), "listMissingArguments");
710
-
711
- var __defProp$4 = Object.defineProperty;
712
- var __name$4 = (target, value) => __defProp$4(target, "name", { value, configurable: true });
713
- const mergeArguments = /* @__PURE__ */ __name$4((argumentLists) => {
714
- const argumentsByName = /* @__PURE__ */ new Map();
715
- argumentLists.forEach((argument) => {
716
- argumentsByName.set(argument.name, { ...argumentsByName.get(argument.name), ...argument });
717
- });
718
- return [...argumentsByName.values()];
719
- }, "mergeArguments");
720
-
721
- var __defProp$3 = Object.defineProperty;
722
- var __name$3 = (target, value) => __defProp$3(target, "name", { value, configurable: true });
723
- const isElectronApp = /* @__PURE__ */ __name$3(() => !!process.versions.electron, "isElectronApp");
724
- const isBundledElectronApp = /* @__PURE__ */ __name$3(() => isElectronApp() && !process.defaultApp, "isBundledElectronApp");
725
- const getProcessArgvBinIndex = /* @__PURE__ */ __name$3(() => {
726
- if (isBundledElectronApp()) {
727
- return 0;
728
- }
729
- return 1;
730
- }, "getProcessArgvBinIndex");
731
- const hideBin = /* @__PURE__ */ __name$3((argv) => argv.slice(getProcessArgvBinIndex() + 1), "hideBin");
732
-
733
- var __defProp$2 = Object.defineProperty;
734
- var __name$2 = (target, value) => __defProp$2(target, "name", { value, configurable: true });
735
- const COMMAND_DELIMITER = " ";
736
- const equals = /* @__PURE__ */ __name$2((a, b) => a.length === b.length && a.every((v, index) => v === b[index]), "equals");
737
- const parseRawCommand = /* @__PURE__ */ __name$2((commandArray) => {
738
- if (typeof commandArray === "string") {
739
- return commandArray.split(COMMAND_DELIMITER);
740
- }
741
- if (equals(commandArray, process.argv)) {
742
- return hideBin(commandArray);
743
- }
744
- return commandArray;
745
- }, "parseRawCommand");
746
-
747
- var __defProp$1 = Object.defineProperty;
748
- var __name$1 = (target, value) => __defProp$1(target, "name", { value, configurable: true });
749
- const registerExceptionHandler = /* @__PURE__ */ __name$1((logger) => {
750
- process.on("uncaughtException", (error) => {
751
- logger.error(`Uncaught exception: ${error}`);
752
- if (error?.stack) {
753
- logger.error(error.stack);
754
- }
755
- process.exit(1);
756
- });
757
- process.on("unhandledRejection", (error) => {
758
- logger.error(`Promise rejection: ${error}`);
759
- if (error?.stack) {
760
- logger.error(error.stack);
761
- }
762
- process.exit(1);
763
- });
764
- }, "registerExceptionHandler");
765
-
766
- var __defProp = Object.defineProperty;
767
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
768
- const isCI = "CI" in node_process.env && ("GITHUB_ACTIONS" in node_process.env || "GITLAB_CI" in node_process.env || "CIRCLECI" in node_process.env);
769
- const lowerFirstChar = /* @__PURE__ */ __name((string_) => string_.charAt(0).toLowerCase() + string_.slice(1), "lowerFirstChar");
770
- class Cli {
771
- static {
772
- __name(this, "Cli");
773
- }
774
- logger;
775
- argv;
776
- cwd;
777
- cliName;
778
- packageVersion;
779
- packageName;
780
- extensions = [];
781
- commands;
782
- defaultCommand;
783
- updateNotifierOptions;
784
- commandSection;
785
- /**
786
- * @param cliName The cli cliName.
787
- * @param options The options for the CLI.
788
- * - argv This should be in the base case process.argv
789
- * - cwd The path of main folder.
790
- * - logger The logger options.
791
- * - packageName The packageJson name.
792
- * - packageVersion The packageJson version.
793
- */
794
- constructor(cliName, options = {}) {
795
- const { argv, cwd, packageName, packageVersion } = {
796
- argv: node_process.argv,
797
- cwd: node_process.cwd(),
798
- ...options
799
- };
800
- this.argv = parseRawCommand(argv);
801
- if (this.argv.includes("--quiet") || this.argv.includes("-q")) {
802
- node_process.env.CEREBRO_OUTPUT_LEVEL = String(VERBOSITY_QUIET);
803
- } else if (this.argv.includes("--verbose") || this.argv.includes("-v")) {
804
- node_process.env.CEREBRO_OUTPUT_LEVEL = String(VERBOSITY_VERBOSE);
805
- } else if (this.argv.includes("--debug") || this.argv.includes("-vvv") || "DEBUG" in node_process.env) {
806
- node_process.env.CEREBRO_OUTPUT_LEVEL = String(VERBOSITY_DEBUG);
807
- } else {
808
- node_process.env.CEREBRO_OUTPUT_LEVEL = String(VERBOSITY_NORMAL);
809
- }
810
- const cerebroLevelToPailLevel = {
811
- "32": "informational",
812
- "64": "trace",
813
- "128": "debug"
814
- };
815
- const processors = [new processor.MessageFormatterProcessor()];
816
- if (node_process.env.CEREBRO_OUTPUT_LEVEL === String(VERBOSITY_DEBUG)) {
817
- processors.push(new processor.CallerProcessor());
818
- }
819
- this.logger = server.createPail({
820
- logLevel: node_process.env.CEREBRO_OUTPUT_LEVEL ? cerebroLevelToPailLevel[node_process.env.CEREBRO_OUTPUT_LEVEL] ?? "informational" : "informational",
821
- processors,
822
- ...options.logger
823
- });
824
- if (node_process.env.CEREBRO_OUTPUT_LEVEL === String(VERBOSITY_QUIET)) {
825
- this.logger.disable();
826
- }
827
- checkNodeVersion();
828
- registerExceptionHandler(this.logger);
829
- this.cliName = cliName;
830
- this.packageVersion = packageVersion;
831
- this.packageName = packageName;
832
- this.cwd = cwd;
833
- this.defaultCommand = "help";
834
- this.commandSection = {
835
- header: `${this.cliName}${this.packageVersion ? ` v${this.packageVersion}` : ""}`
836
- };
837
- this.commands = /* @__PURE__ */ new Map();
838
- this.addCoreExtensions();
839
- this.addCommand(VersionCommand);
840
- this.addCommand(new HelpCommand(this.commands));
841
- }
842
- setCommandSection(commandSection) {
843
- this.commandSection = commandSection;
844
- return this;
845
- }
846
- getCommandSection() {
847
- return this.commandSection;
848
- }
849
- /**
850
- * Set a default command, to display a different command if cli is call without command.
851
- */
852
- setDefaultCommand(commandName) {
853
- this.defaultCommand = commandName;
854
- return this;
855
- }
856
- /**
857
- * Add an arbitrary command to the CLI.
858
- */
859
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
860
- addCommand(command) {
861
- if (this.commands.has(command.name)) {
862
- throw new Error(`Ignored command with name "${command.name}", it was found in the command list.`);
863
- } else {
864
- command.options?.map((option) => mapOptionTypeLabel(option));
865
- this.validateDoubleOptions(command);
866
- this.addNegatableOption(command);
867
- command.options?.forEach((option) => {
868
- option.__camelCaseName__ = camelCase(option.name);
869
- });
870
- this.commands.set(command.name, command);
871
- if (command.alias !== void 0) {
872
- let aliases = command.alias;
873
- if (typeof command.alias === "string") {
874
- aliases = [command.alias];
875
- }
876
- aliases.forEach((alias) => {
877
- this.logger.debug("adding alias", alias);
878
- if (this.commands.has(alias)) {
879
- throw new Error(`Ignoring command alias "${alias}, command with the same name was found."`);
880
- } else {
881
- this.commands.set(alias, command);
882
- }
883
- });
884
- }
885
- }
886
- return this;
887
- }
888
- /**
889
- * Adds an extension so it is available when commands execute. They usually live
890
- * the given name on the toolbox object passed to commands, but are able
891
- * to manipulate the toolbox object however they want.
892
- */
893
- addExtension(extension) {
894
- this.extensions.push(extension);
895
- return this;
896
- }
897
- /**
898
- * Enable the update notifier functionality with the given options.
899
- *
900
- * @param options - The options for enabling the update notifier.
901
- * options.alwaysRun - Determines whether the update check should always run. Defaults to false.
902
- * options.distributionTag - The distribution tag to use for checking updates. Defaults to "latest".
903
- * options.updateCheckInterval - The interval in milliseconds between each update check. Defaults to 24 hours.
904
- *
905
- * @example
906
- * enableUpdateNotifier({
907
- * alwaysRun: true,
908
- * debug: false,
909
- * distributionTag: "stable",
910
- * pkg: {
911
- * name: "my-package",
912
- * version: "1.0.0"
913
- * },
914
- * updateCheckInterval: 1000 * 60 * 60
915
- * });
916
- */
917
- enableUpdateNotifier(options = {}) {
918
- if (!this.packageName || !this.packageVersion) {
919
- throw new Error("Cannot enable update notifier without package name and version.");
920
- }
921
- const configKeys = Object.keys(options);
922
- if (configKeys.length > 0 && !configKeys.includes("alwaysRun") && !configKeys.includes("distTag") && !configKeys.includes("updateCheckInterval")) {
923
- throw new Error("Invalid update notifier options, please check the documentation.");
924
- }
925
- this.updateNotifierOptions = {
926
- alwaysRun: false,
927
- debug: node_process.env.CEREBRO_OUTPUT_LEVEL === String(VERBOSITY_DEBUG),
928
- distTag: "latest",
929
- pkg: {
930
- name: this.packageName,
931
- version: this.packageVersion
932
- },
933
- updateCheckInterval: 1e3 * 60 * 60 * 24,
934
- ...options
935
- };
936
- return this;
937
- }
938
- getCliName() {
939
- return this.cliName;
940
- }
941
- getPackageVersion() {
942
- return this.packageVersion;
943
- }
944
- getPackageName() {
945
- return this.packageName;
946
- }
947
- getCommands() {
948
- return this.commands;
949
- }
950
- getCwd() {
951
- return this.cwd;
952
- }
953
- // eslint-disable-next-line sonarjs/cognitive-complexity
954
- async run(extraOptions = {}) {
955
- const { shouldExitProcess = true, ...otherExtraOptions } = extraOptions;
956
- const commandNames = [...this.commands.keys()];
957
- let parsedArguments;
958
- this.logger.debug(`process.execPath: ${node_process.execPath}`);
959
- this.logger.debug(`process.execArgv: ${node_process.execArgv.join(" ")}`);
960
- this.logger.debug(`process.argv: ${node_process.argv.join(" ")}`);
961
- try {
962
- parsedArguments = commandLineCommands([null, ...commandNames], this.argv);
963
- } catch (error) {
964
- if (error.name === "INVALID_COMMAND" && error.command) {
965
- let alternatives = "";
966
- const foundAlternatives = findAlternatives(error.command, [...this.commands.keys()]);
967
- if (foundAlternatives.length > 0) {
968
- alternatives = ` Did you mean: \r
969
- - ${foundAlternatives.join(" \r\n- ")}`;
970
- }
971
- this.logger.error(`"${error.command}" is not an available command.${alternatives}`);
972
- } else {
973
- this.logger.error(error);
974
- }
975
- return shouldExitProcess ? node_process.exit(1) : void 0;
976
- }
977
- const commandName = parsedArguments.command ?? this.defaultCommand;
978
- const command = this.commands.get(commandName);
979
- if (typeof command.execute !== "function") {
980
- this.logger.error(`Command "${command.name}" has no function to execute.`);
981
- return shouldExitProcess ? node_process.exit(1) : void 0;
982
- }
983
- const commandArguments = parsedArguments.argv;
984
- this.logger.debug(`command '${commandName}' found, parsing command args: ${commandArguments.join(", ")}`);
985
- let arguments_ = mergeArguments([...command.options ?? [], ...defaultOptions]);
986
- arguments_.forEach((argument) => {
987
- if (argument.multiple && argument.lazyMultiple) {
988
- throw new Error(`Argument "${argument.name}" cannot have both multiple and lazyMultiple options, please choose one.`);
989
- }
990
- });
991
- if (command.argument) {
992
- this.logger.debug("command has positional argument, parsing them...");
993
- arguments_ = [
994
- {
995
- defaultOption: true,
996
- description: command.argument?.description,
997
- group: "positionals",
998
- multiple: true,
999
- name: POSITIONALS_KEY,
1000
- type: command.argument?.type,
1001
- typeLabel: command.argument?.typeLabel
1002
- },
1003
- ...arguments_
1004
- ];
1005
- }
1006
- const parsedArgs = commandLineArgs__default(arguments_, {
1007
- argv: removeBooleanValues(commandArguments, command.options ?? []),
1008
- camelCase: true,
1009
- partial: true,
1010
- stopAtFirstUnknown: true
1011
- });
1012
- const booleanValues = getBooleanValues(commandArguments, command.options ?? []);
1013
- const commandArgs = { ...parsedArgs, _all: { ...parsedArgs._all, ...booleanValues } };
1014
- this.validateCommandOptions(arguments_, commandArgs, command);
1015
- const toolbox = new EmptyToolbox(command.name, command);
1016
- toolbox.runtime = this;
1017
- await this.registerExtensions(toolbox);
1018
- await this.updateNotifier(toolbox);
1019
- const { _all, positionals } = commandArgs;
1020
- if (_all[POSITIONALS_KEY]) {
1021
- delete _all[POSITIONALS_KEY];
1022
- }
1023
- toolbox.argument = positionals?.[POSITIONALS_KEY] ?? [];
1024
- toolbox.argv = this.argv;
1025
- toolbox.options = { ..._all, ...otherExtraOptions };
1026
- this.mapNegatableOptions(toolbox, command);
1027
- this.mapImpliesOptions(toolbox, command);
1028
- this.validateCommandArgsForConflicts(arguments_, toolbox.options, command);
1029
- this.logger.debug("command options parsed from options:");
1030
- this.logger.debug(JSON.stringify(toolbox.options, null, 2));
1031
- this.logger.debug("command argument parsed from argument:");
1032
- this.logger.debug(JSON.stringify(toolbox.argument, null, 2));
1033
- await this.prepareToolboxResult(commandArgs, toolbox, command);
1034
- return shouldExitProcess ? node_process.exit(0) : void 0;
1035
- }
1036
- // eslint-disable-next-line class-methods-use-this,@typescript-eslint/no-explicit-any
1037
- validateDoubleOptions(command) {
1038
- if (Array.isArray(command.options)) {
1039
- const groupedDuplicatedOption = command.options.reduce((accumulator, object) => {
1040
- const key = `${object.name}-${object.alias}`;
1041
- if (!accumulator[key]) {
1042
- accumulator[key] = [];
1043
- }
1044
- accumulator[key].push(object);
1045
- return accumulator;
1046
- }, {});
1047
- const duplicatedOptions = Object.values(groupedDuplicatedOption).filter((object) => object.length > 1);
1048
- let errorMessages = "";
1049
- duplicatedOptions.forEach((options) => {
1050
- const matchingOption = options[0];
1051
- const duplicate = options[1];
1052
- let flag = "alias";
1053
- if (matchingOption.name === duplicate.name) {
1054
- flag = "name";
1055
- if (matchingOption.alias === duplicate.alias) {
1056
- flag += " and alias";
1057
- }
1058
- }
1059
- errorMessages += `Cannot add option ${flag} "${JSON.stringify(duplicate)}" to command "${command.name}" due to conflicting option ${JSON.stringify(matchingOption)}
1060
- `;
1061
- });
1062
- if (errorMessages.length > 0) {
1063
- throw new Error(errorMessages);
1064
- }
1065
- }
1066
- }
1067
- /**
1068
- * Adds the core extensions. These provide the basic features
1069
- * available in cerebro.
1070
- */
1071
- addCoreExtensions() {
1072
- this.addExtension({
1073
- execute: /* @__PURE__ */ __name((toolbox) => {
1074
- toolbox.logger = this.logger;
1075
- }, "execute"),
1076
- name: "logger"
1077
- });
1078
- }
1079
- // eslint-disable-next-line unicorn/prevent-abbreviations,@typescript-eslint/no-explicit-any
1080
- async prepareToolboxResult(commandArgs, toolbox, command) {
1081
- if (commandArgs.global?.help) {
1082
- this.logger.debug("'--help' option found, running 'help' for given command...");
1083
- const helpCommand = this.commands.get("help");
1084
- if (!helpCommand) {
1085
- throw new Error("Help command not found.");
1086
- }
1087
- await helpCommand.execute(toolbox);
1088
- return;
1089
- }
1090
- if (commandArgs.global?.version || commandArgs.global?.V) {
1091
- this.logger.debug("'--version' option found, running 'version' for given command...");
1092
- const helpCommand = this.commands.get("version");
1093
- if (!helpCommand) {
1094
- throw new Error("Version command not found.");
1095
- }
1096
- await helpCommand.execute(toolbox);
1097
- return;
1098
- }
1099
- await command.execute(toolbox);
1100
- }
1101
- async updateNotifier({ logger }) {
1102
- if (this.updateNotifierOptions?.alwaysRun || !(node_process.env.NO_UPDATE_NOTIFIER || node_process.env.NODE_ENV === "test" || this.argv.includes("--no-update-notifier") || isCI) && this.updateNotifierOptions) {
1103
- logger.raw("Checking for updates...");
1104
- const hasNewVersion = await import('../packem_chunks/has-new-version.cjs').then((m) => m.default);
1105
- const updateAvailable = await hasNewVersion(this.updateNotifierOptions);
1106
- if (updateAvailable) {
1107
- const template = "Update available " + colorize.dim(this.packageVersion + "") + colorize.reset(" → ") + colorize.green(updateAvailable);
1108
- this.logger.error(
1109
- boxen.boxen(template, {
1110
- borderColor: /* @__PURE__ */ __name((border) => colorize.yellow(border), "borderColor"),
1111
- borderStyle: "round",
1112
- margin: 1,
1113
- padding: 1,
1114
- textAlignment: "center"
1115
- })
1116
- );
1117
- }
1118
- }
1119
- }
1120
- // eslint-disable-next-line sonarjs/cognitive-complexity,class-methods-use-this,@typescript-eslint/no-explicit-any
1121
- validateCommandOptions(arguments_, commandArguments, command) {
1122
- const missingOptions = listMissingArguments(arguments_, commandArguments);
1123
- if (missingOptions.length > 0) {
1124
- throw new Error(
1125
- `You called the command "${command.name}" without the required options: ${missingOptions.map((argument) => argument.name).join(", ")}`
1126
- );
1127
- }
1128
- if (commandArguments._unknown && commandArguments._unknown.length > 0) {
1129
- const errors = [];
1130
- commandArguments._unknown.forEach((unknownOption) => {
1131
- const isOption = unknownOption.startsWith("--");
1132
- let error = `Found unknown ${isOption ? "option" : "argument"} "${unknownOption}"`;
1133
- if (isOption) {
1134
- const foundAlternatives = findAlternatives(unknownOption.replace("--", ""), [
1135
- ...(command.options ?? []).map((option) => option.name),
1136
- ...defaultOptions.map((option) => option.name)
1137
- ]);
1138
- if (foundAlternatives.length > 0) {
1139
- const [first, ...rest] = foundAlternatives.map((alternative) => `--${alternative}`);
1140
- error += rest.length > 0 ? `, did you mean ${first} or ${rest.join(", ")}?` : `, did you mean ${first}?`;
1141
- }
1142
- }
1143
- errors.push(error);
1144
- });
1145
- if (errors.length > 0) {
1146
- throw new Error(errors.join("\n"));
1147
- }
1148
- }
1149
- }
1150
- // eslint-disable-next-line class-methods-use-this,@typescript-eslint/no-explicit-any
1151
- validateCommandArgsForConflicts(arguments_, commandArguments, command) {
1152
- const conflicts = arguments_.filter((argument) => argument.conflicts !== void 0);
1153
- if (conflicts.length > 0) {
1154
- const conflict = conflicts.find((argument) => {
1155
- if (Array.isArray(argument.conflicts)) {
1156
- return argument.conflicts.some((c) => commandArguments[c] !== void 0) && commandArguments[argument.name] !== void 0;
1157
- }
1158
- return commandArguments[argument.conflicts] !== void 0 && commandArguments[argument.name] !== void 0;
1159
- });
1160
- if (conflict) {
1161
- throw new Error(
1162
- `You called the command "${command.name}" with conflicting options: ${conflict.name} and ${typeof conflict.conflicts === "string" ? conflict.conflicts : conflict.conflicts?.join(", ")}`
1163
- );
1164
- }
1165
- }
1166
- }
1167
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1168
- addNegatableOption(command) {
1169
- if (Array.isArray(command.options)) {
1170
- command.options.forEach((option) => {
1171
- if (option.name.startsWith("no-") && !command.options.some((o) => o.name === option.name.replace("no-", ""))) {
1172
- if (option.type !== Boolean) {
1173
- this.logger.debug(`Cannot add negated option "${option.name}" to command "${command.name}" because it is not a boolean.`);
1174
- return;
1175
- }
1176
- const negatedOption = {
1177
- ...option,
1178
- defaultValue: option.defaultValue === void 0 ? true : !option.defaultValue,
1179
- name: `${option.name.replace("no-", "")}`
1180
- };
1181
- command.options.push(negatedOption);
1182
- }
1183
- });
1184
- }
1185
- }
1186
- async registerExtensions(toolbox) {
1187
- const callback = /* @__PURE__ */ __name(async (extension) => {
1188
- if (typeof extension.execute !== "function") {
1189
- this.logger.warn(`Skipped ${extension.name} because execute is not a function.`);
1190
- return null;
1191
- }
1192
- await extension.execute(toolbox);
1193
- return null;
1194
- }, "callback");
1195
- for (const extension of this.extensions) {
1196
- await callback(extension);
1197
- }
1198
- }
1199
- // combining negatable options with their non-negated counterparts
1200
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1201
- mapNegatableOptions(toolbox, command) {
1202
- Object.entries(toolbox.options).forEach(([key, value]) => {
1203
- if (/^no\w+/.test(key)) {
1204
- const nonNegatedKey = lowerFirstChar(key.replace("no", ""));
1205
- this.logger.debug(`mapping negated option "${key}" to "${nonNegatedKey}"`);
1206
- toolbox.options[nonNegatedKey] = !value;
1207
- command.options?.forEach((option) => {
1208
- if (option.name === nonNegatedKey) {
1209
- option.__negated__ = true;
1210
- }
1211
- });
1212
- }
1213
- });
1214
- }
1215
- // Apply any implied option values, if option is undefined or default value.
1216
- // eslint-disable-next-line class-methods-use-this,@typescript-eslint/no-explicit-any
1217
- mapImpliesOptions(toolbox, command) {
1218
- Object.keys(toolbox.options).forEach((optionKey) => {
1219
- const option = command.options?.find(
1220
- // eslint-disable-next-line no-underscore-dangle
1221
- (o) => o.__camelCaseName__ === optionKey && o.__negated__ === void 0 && o.implies !== void 0
1222
- );
1223
- if (option?.implies) {
1224
- const implies = option.implies;
1225
- Object.entries(implies).forEach(([key, value]) => {
1226
- if (toolbox.options[key] === void 0) {
1227
- toolbox.options[key] = value;
1228
- } else {
1229
- const impliedOption = command.options?.find((cOption) => cOption.name === key);
1230
- if (impliedOption?.defaultValue === void 0 || toolbox.options[key] === impliedOption.defaultValue) {
1231
- toolbox.options[key] = value;
1232
- }
1233
- }
1234
- });
1235
- }
1236
- });
1237
- }
1238
- }
1239
-
1240
- exports.Cli = Cli;