@axiomify/cli 4.0.0 → 5.0.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 (4) hide show
  1. package/README.md +56 -52
  2. package/dist/index.js +3199 -59
  3. package/dist/index.mjs +3198 -59
  4. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -1,12 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- var commander = require('commander');
5
4
  var esbuild = require('esbuild');
6
5
  var path4 = require('path');
7
6
  var fs = require('fs');
8
7
  var child_process = require('child_process');
8
+ var enquirer = require('enquirer');
9
+ var execa = require('execa');
9
10
  var fs2 = require('fs/promises');
11
+ var pc = require('picocolors');
10
12
 
11
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
14
 
@@ -32,28 +34,2914 @@ var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
32
34
  var path4__default = /*#__PURE__*/_interopDefault(path4);
33
35
  var fs__default = /*#__PURE__*/_interopDefault(fs);
34
36
  var fs2__default = /*#__PURE__*/_interopDefault(fs2);
37
+ var pc__default = /*#__PURE__*/_interopDefault(pc);
35
38
 
39
+ var __create = Object.create;
40
+ var __defProp = Object.defineProperty;
41
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
42
+ var __getOwnPropNames = Object.getOwnPropertyNames;
43
+ var __getProtoOf = Object.getPrototypeOf;
44
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
36
45
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
37
46
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
38
47
  }) : x)(function(x) {
39
48
  if (typeof require !== "undefined") return require.apply(this, arguments);
40
49
  throw Error('Dynamic require of "' + x + '" is not supported');
41
50
  });
51
+ var __commonJS = (cb, mod) => function __require2() {
52
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
53
+ };
54
+ var __copyProps = (to, from, except, desc) => {
55
+ if (from && typeof from === "object" || typeof from === "function") {
56
+ for (let key of __getOwnPropNames(from))
57
+ if (!__hasOwnProp.call(to, key) && key !== except)
58
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
59
+ }
60
+ return to;
61
+ };
62
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
63
+ // If the importer is in node compatibility mode or this is not an ESM
64
+ // file that has been converted to a CommonJS file using a Babel-
65
+ // compatible transform (i.e. "__esModule" has not been set), then set
66
+ // "default" to the CommonJS "module.exports" for node compatibility.
67
+ __defProp(target, "default", { value: mod, enumerable: true }) ,
68
+ mod
69
+ ));
70
+
71
+ // node_modules/commander/lib/error.js
72
+ var require_error = __commonJS({
73
+ "node_modules/commander/lib/error.js"(exports) {
74
+ var CommanderError2 = class extends Error {
75
+ /**
76
+ * Constructs the CommanderError class
77
+ * @param {number} exitCode suggested exit code which could be used with process.exit
78
+ * @param {string} code an id string representing the error
79
+ * @param {string} message human-readable description of the error
80
+ * @constructor
81
+ */
82
+ constructor(exitCode, code, message) {
83
+ super(message);
84
+ Error.captureStackTrace(this, this.constructor);
85
+ this.name = this.constructor.name;
86
+ this.code = code;
87
+ this.exitCode = exitCode;
88
+ this.nestedError = void 0;
89
+ }
90
+ };
91
+ var InvalidArgumentError2 = class extends CommanderError2 {
92
+ /**
93
+ * Constructs the InvalidArgumentError class
94
+ * @param {string} [message] explanation of why argument is invalid
95
+ * @constructor
96
+ */
97
+ constructor(message) {
98
+ super(1, "commander.invalidArgument", message);
99
+ Error.captureStackTrace(this, this.constructor);
100
+ this.name = this.constructor.name;
101
+ }
102
+ };
103
+ exports.CommanderError = CommanderError2;
104
+ exports.InvalidArgumentError = InvalidArgumentError2;
105
+ }
106
+ });
107
+
108
+ // node_modules/commander/lib/argument.js
109
+ var require_argument = __commonJS({
110
+ "node_modules/commander/lib/argument.js"(exports) {
111
+ var { InvalidArgumentError: InvalidArgumentError2 } = require_error();
112
+ var Argument2 = class {
113
+ /**
114
+ * Initialize a new command argument with the given name and description.
115
+ * The default is that the argument is required, and you can explicitly
116
+ * indicate this with <> around the name. Put [] around the name for an optional argument.
117
+ *
118
+ * @param {string} name
119
+ * @param {string} [description]
120
+ */
121
+ constructor(name, description) {
122
+ this.description = description || "";
123
+ this.variadic = false;
124
+ this.parseArg = void 0;
125
+ this.defaultValue = void 0;
126
+ this.defaultValueDescription = void 0;
127
+ this.argChoices = void 0;
128
+ switch (name[0]) {
129
+ case "<":
130
+ this.required = true;
131
+ this._name = name.slice(1, -1);
132
+ break;
133
+ case "[":
134
+ this.required = false;
135
+ this._name = name.slice(1, -1);
136
+ break;
137
+ default:
138
+ this.required = true;
139
+ this._name = name;
140
+ break;
141
+ }
142
+ if (this._name.length > 3 && this._name.slice(-3) === "...") {
143
+ this.variadic = true;
144
+ this._name = this._name.slice(0, -3);
145
+ }
146
+ }
147
+ /**
148
+ * Return argument name.
149
+ *
150
+ * @return {string}
151
+ */
152
+ name() {
153
+ return this._name;
154
+ }
155
+ /**
156
+ * @package internal use only
157
+ */
158
+ _concatValue(value, previous) {
159
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
160
+ return [value];
161
+ }
162
+ return previous.concat(value);
163
+ }
164
+ /**
165
+ * Set the default value, and optionally supply the description to be displayed in the help.
166
+ *
167
+ * @param {*} value
168
+ * @param {string} [description]
169
+ * @return {Argument}
170
+ */
171
+ default(value, description) {
172
+ this.defaultValue = value;
173
+ this.defaultValueDescription = description;
174
+ return this;
175
+ }
176
+ /**
177
+ * Set the custom handler for processing CLI command arguments into argument values.
178
+ *
179
+ * @param {Function} [fn]
180
+ * @return {Argument}
181
+ */
182
+ argParser(fn) {
183
+ this.parseArg = fn;
184
+ return this;
185
+ }
186
+ /**
187
+ * Only allow argument value to be one of choices.
188
+ *
189
+ * @param {string[]} values
190
+ * @return {Argument}
191
+ */
192
+ choices(values) {
193
+ this.argChoices = values.slice();
194
+ this.parseArg = (arg, previous) => {
195
+ if (!this.argChoices.includes(arg)) {
196
+ throw new InvalidArgumentError2(`Allowed choices are ${this.argChoices.join(", ")}.`);
197
+ }
198
+ if (this.variadic) {
199
+ return this._concatValue(arg, previous);
200
+ }
201
+ return arg;
202
+ };
203
+ return this;
204
+ }
205
+ /**
206
+ * Make argument required.
207
+ */
208
+ argRequired() {
209
+ this.required = true;
210
+ return this;
211
+ }
212
+ /**
213
+ * Make argument optional.
214
+ */
215
+ argOptional() {
216
+ this.required = false;
217
+ return this;
218
+ }
219
+ };
220
+ function humanReadableArgName(arg) {
221
+ const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
222
+ return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
223
+ }
224
+ exports.Argument = Argument2;
225
+ exports.humanReadableArgName = humanReadableArgName;
226
+ }
227
+ });
228
+
229
+ // node_modules/commander/lib/help.js
230
+ var require_help = __commonJS({
231
+ "node_modules/commander/lib/help.js"(exports) {
232
+ var { humanReadableArgName } = require_argument();
233
+ var Help2 = class {
234
+ constructor() {
235
+ this.helpWidth = void 0;
236
+ this.sortSubcommands = false;
237
+ this.sortOptions = false;
238
+ this.showGlobalOptions = false;
239
+ }
240
+ /**
241
+ * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
242
+ *
243
+ * @param {Command} cmd
244
+ * @returns {Command[]}
245
+ */
246
+ visibleCommands(cmd) {
247
+ const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
248
+ const helpCommand = cmd._getHelpCommand();
249
+ if (helpCommand && !helpCommand._hidden) {
250
+ visibleCommands.push(helpCommand);
251
+ }
252
+ if (this.sortSubcommands) {
253
+ visibleCommands.sort((a, b) => {
254
+ return a.name().localeCompare(b.name());
255
+ });
256
+ }
257
+ return visibleCommands;
258
+ }
259
+ /**
260
+ * Compare options for sort.
261
+ *
262
+ * @param {Option} a
263
+ * @param {Option} b
264
+ * @returns number
265
+ */
266
+ compareOptions(a, b) {
267
+ const getSortKey = (option) => {
268
+ return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
269
+ };
270
+ return getSortKey(a).localeCompare(getSortKey(b));
271
+ }
272
+ /**
273
+ * Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.
274
+ *
275
+ * @param {Command} cmd
276
+ * @returns {Option[]}
277
+ */
278
+ visibleOptions(cmd) {
279
+ const visibleOptions = cmd.options.filter((option) => !option.hidden);
280
+ const helpOption = cmd._getHelpOption();
281
+ if (helpOption && !helpOption.hidden) {
282
+ const removeShort = helpOption.short && cmd._findOption(helpOption.short);
283
+ const removeLong = helpOption.long && cmd._findOption(helpOption.long);
284
+ if (!removeShort && !removeLong) {
285
+ visibleOptions.push(helpOption);
286
+ } else if (helpOption.long && !removeLong) {
287
+ visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
288
+ } else if (helpOption.short && !removeShort) {
289
+ visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
290
+ }
291
+ }
292
+ if (this.sortOptions) {
293
+ visibleOptions.sort(this.compareOptions);
294
+ }
295
+ return visibleOptions;
296
+ }
297
+ /**
298
+ * Get an array of the visible global options. (Not including help.)
299
+ *
300
+ * @param {Command} cmd
301
+ * @returns {Option[]}
302
+ */
303
+ visibleGlobalOptions(cmd) {
304
+ if (!this.showGlobalOptions) return [];
305
+ const globalOptions = [];
306
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
307
+ const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
308
+ globalOptions.push(...visibleOptions);
309
+ }
310
+ if (this.sortOptions) {
311
+ globalOptions.sort(this.compareOptions);
312
+ }
313
+ return globalOptions;
314
+ }
315
+ /**
316
+ * Get an array of the arguments if any have a description.
317
+ *
318
+ * @param {Command} cmd
319
+ * @returns {Argument[]}
320
+ */
321
+ visibleArguments(cmd) {
322
+ if (cmd._argsDescription) {
323
+ cmd.registeredArguments.forEach((argument) => {
324
+ argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
325
+ });
326
+ }
327
+ if (cmd.registeredArguments.find((argument) => argument.description)) {
328
+ return cmd.registeredArguments;
329
+ }
330
+ return [];
331
+ }
332
+ /**
333
+ * Get the command term to show in the list of subcommands.
334
+ *
335
+ * @param {Command} cmd
336
+ * @returns {string}
337
+ */
338
+ subcommandTerm(cmd) {
339
+ const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
340
+ return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + // simplistic check for non-help option
341
+ (args ? " " + args : "");
342
+ }
343
+ /**
344
+ * Get the option term to show in the list of options.
345
+ *
346
+ * @param {Option} option
347
+ * @returns {string}
348
+ */
349
+ optionTerm(option) {
350
+ return option.flags;
351
+ }
352
+ /**
353
+ * Get the argument term to show in the list of arguments.
354
+ *
355
+ * @param {Argument} argument
356
+ * @returns {string}
357
+ */
358
+ argumentTerm(argument) {
359
+ return argument.name();
360
+ }
361
+ /**
362
+ * Get the longest command term length.
363
+ *
364
+ * @param {Command} cmd
365
+ * @param {Help} helper
366
+ * @returns {number}
367
+ */
368
+ longestSubcommandTermLength(cmd, helper) {
369
+ return helper.visibleCommands(cmd).reduce((max, command) => {
370
+ return Math.max(max, helper.subcommandTerm(command).length);
371
+ }, 0);
372
+ }
373
+ /**
374
+ * Get the longest option term length.
375
+ *
376
+ * @param {Command} cmd
377
+ * @param {Help} helper
378
+ * @returns {number}
379
+ */
380
+ longestOptionTermLength(cmd, helper) {
381
+ return helper.visibleOptions(cmd).reduce((max, option) => {
382
+ return Math.max(max, helper.optionTerm(option).length);
383
+ }, 0);
384
+ }
385
+ /**
386
+ * Get the longest global option term length.
387
+ *
388
+ * @param {Command} cmd
389
+ * @param {Help} helper
390
+ * @returns {number}
391
+ */
392
+ longestGlobalOptionTermLength(cmd, helper) {
393
+ return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
394
+ return Math.max(max, helper.optionTerm(option).length);
395
+ }, 0);
396
+ }
397
+ /**
398
+ * Get the longest argument term length.
399
+ *
400
+ * @param {Command} cmd
401
+ * @param {Help} helper
402
+ * @returns {number}
403
+ */
404
+ longestArgumentTermLength(cmd, helper) {
405
+ return helper.visibleArguments(cmd).reduce((max, argument) => {
406
+ return Math.max(max, helper.argumentTerm(argument).length);
407
+ }, 0);
408
+ }
409
+ /**
410
+ * Get the command usage to be displayed at the top of the built-in help.
411
+ *
412
+ * @param {Command} cmd
413
+ * @returns {string}
414
+ */
415
+ commandUsage(cmd) {
416
+ let cmdName = cmd._name;
417
+ if (cmd._aliases[0]) {
418
+ cmdName = cmdName + "|" + cmd._aliases[0];
419
+ }
420
+ let ancestorCmdNames = "";
421
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
422
+ ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
423
+ }
424
+ return ancestorCmdNames + cmdName + " " + cmd.usage();
425
+ }
426
+ /**
427
+ * Get the description for the command.
428
+ *
429
+ * @param {Command} cmd
430
+ * @returns {string}
431
+ */
432
+ commandDescription(cmd) {
433
+ return cmd.description();
434
+ }
435
+ /**
436
+ * Get the subcommand summary to show in the list of subcommands.
437
+ * (Fallback to description for backwards compatibility.)
438
+ *
439
+ * @param {Command} cmd
440
+ * @returns {string}
441
+ */
442
+ subcommandDescription(cmd) {
443
+ return cmd.summary() || cmd.description();
444
+ }
445
+ /**
446
+ * Get the option description to show in the list of options.
447
+ *
448
+ * @param {Option} option
449
+ * @return {string}
450
+ */
451
+ optionDescription(option) {
452
+ const extraInfo = [];
453
+ if (option.argChoices) {
454
+ extraInfo.push(
455
+ // use stringify to match the display of the default value
456
+ `choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`
457
+ );
458
+ }
459
+ if (option.defaultValue !== void 0) {
460
+ const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean";
461
+ if (showDefault) {
462
+ extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
463
+ }
464
+ }
465
+ if (option.presetArg !== void 0 && option.optional) {
466
+ extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
467
+ }
468
+ if (option.envVar !== void 0) {
469
+ extraInfo.push(`env: ${option.envVar}`);
470
+ }
471
+ if (extraInfo.length > 0) {
472
+ return `${option.description} (${extraInfo.join(", ")})`;
473
+ }
474
+ return option.description;
475
+ }
476
+ /**
477
+ * Get the argument description to show in the list of arguments.
478
+ *
479
+ * @param {Argument} argument
480
+ * @return {string}
481
+ */
482
+ argumentDescription(argument) {
483
+ const extraInfo = [];
484
+ if (argument.argChoices) {
485
+ extraInfo.push(
486
+ // use stringify to match the display of the default value
487
+ `choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`
488
+ );
489
+ }
490
+ if (argument.defaultValue !== void 0) {
491
+ extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
492
+ }
493
+ if (extraInfo.length > 0) {
494
+ const extraDescripton = `(${extraInfo.join(", ")})`;
495
+ if (argument.description) {
496
+ return `${argument.description} ${extraDescripton}`;
497
+ }
498
+ return extraDescripton;
499
+ }
500
+ return argument.description;
501
+ }
502
+ /**
503
+ * Generate the built-in help text.
504
+ *
505
+ * @param {Command} cmd
506
+ * @param {Help} helper
507
+ * @returns {string}
508
+ */
509
+ formatHelp(cmd, helper) {
510
+ const termWidth = helper.padWidth(cmd, helper);
511
+ const helpWidth = helper.helpWidth || 80;
512
+ const itemIndentWidth = 2;
513
+ const itemSeparatorWidth = 2;
514
+ function formatItem(term, description) {
515
+ if (description) {
516
+ const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
517
+ return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
518
+ }
519
+ return term;
520
+ }
521
+ function formatList(textArray) {
522
+ return textArray.join("\n").replace(/^/gm, " ".repeat(itemIndentWidth));
523
+ }
524
+ let output = [`Usage: ${helper.commandUsage(cmd)}`, ""];
525
+ const commandDescription = helper.commandDescription(cmd);
526
+ if (commandDescription.length > 0) {
527
+ output = output.concat([helper.wrap(commandDescription, helpWidth, 0), ""]);
528
+ }
529
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
530
+ return formatItem(helper.argumentTerm(argument), helper.argumentDescription(argument));
531
+ });
532
+ if (argumentList.length > 0) {
533
+ output = output.concat(["Arguments:", formatList(argumentList), ""]);
534
+ }
535
+ const optionList = helper.visibleOptions(cmd).map((option) => {
536
+ return formatItem(helper.optionTerm(option), helper.optionDescription(option));
537
+ });
538
+ if (optionList.length > 0) {
539
+ output = output.concat(["Options:", formatList(optionList), ""]);
540
+ }
541
+ if (this.showGlobalOptions) {
542
+ const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
543
+ return formatItem(helper.optionTerm(option), helper.optionDescription(option));
544
+ });
545
+ if (globalOptionList.length > 0) {
546
+ output = output.concat(["Global Options:", formatList(globalOptionList), ""]);
547
+ }
548
+ }
549
+ const commandList = helper.visibleCommands(cmd).map((cmd2) => {
550
+ return formatItem(helper.subcommandTerm(cmd2), helper.subcommandDescription(cmd2));
551
+ });
552
+ if (commandList.length > 0) {
553
+ output = output.concat(["Commands:", formatList(commandList), ""]);
554
+ }
555
+ return output.join("\n");
556
+ }
557
+ /**
558
+ * Calculate the pad width from the maximum term length.
559
+ *
560
+ * @param {Command} cmd
561
+ * @param {Help} helper
562
+ * @returns {number}
563
+ */
564
+ padWidth(cmd, helper) {
565
+ return Math.max(
566
+ helper.longestOptionTermLength(cmd, helper),
567
+ helper.longestGlobalOptionTermLength(cmd, helper),
568
+ helper.longestSubcommandTermLength(cmd, helper),
569
+ helper.longestArgumentTermLength(cmd, helper)
570
+ );
571
+ }
572
+ /**
573
+ * Wrap the given string to width characters per line, with lines after the first indented.
574
+ * Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
575
+ *
576
+ * @param {string} str
577
+ * @param {number} width
578
+ * @param {number} indent
579
+ * @param {number} [minColumnWidth=40]
580
+ * @return {string}
581
+ *
582
+ */
583
+ wrap(str, width, indent, minColumnWidth = 40) {
584
+ const indents = " \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF";
585
+ const manualIndent = new RegExp(`[\\n][${indents}]+`);
586
+ if (str.match(manualIndent)) return str;
587
+ const columnWidth = width - indent;
588
+ if (columnWidth < minColumnWidth) return str;
589
+ const leadingStr = str.slice(0, indent);
590
+ const columnText = str.slice(indent).replace("\r\n", "\n");
591
+ const indentString = " ".repeat(indent);
592
+ const zeroWidthSpace = "\u200B";
593
+ const breaks = `\\s${zeroWidthSpace}`;
594
+ const regex = new RegExp(`
595
+ |.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, "g");
596
+ const lines = columnText.match(regex) || [];
597
+ return leadingStr + lines.map((line, i) => {
598
+ if (line === "\n") return "";
599
+ return (i > 0 ? indentString : "") + line.trimEnd();
600
+ }).join("\n");
601
+ }
602
+ };
603
+ exports.Help = Help2;
604
+ }
605
+ });
606
+
607
+ // node_modules/commander/lib/option.js
608
+ var require_option = __commonJS({
609
+ "node_modules/commander/lib/option.js"(exports) {
610
+ var { InvalidArgumentError: InvalidArgumentError2 } = require_error();
611
+ var Option2 = class {
612
+ /**
613
+ * Initialize a new `Option` with the given `flags` and `description`.
614
+ *
615
+ * @param {string} flags
616
+ * @param {string} [description]
617
+ */
618
+ constructor(flags, description) {
619
+ this.flags = flags;
620
+ this.description = description || "";
621
+ this.required = flags.includes("<");
622
+ this.optional = flags.includes("[");
623
+ this.variadic = /\w\.\.\.[>\]]$/.test(flags);
624
+ this.mandatory = false;
625
+ const optionFlags = splitOptionFlags(flags);
626
+ this.short = optionFlags.shortFlag;
627
+ this.long = optionFlags.longFlag;
628
+ this.negate = false;
629
+ if (this.long) {
630
+ this.negate = this.long.startsWith("--no-");
631
+ }
632
+ this.defaultValue = void 0;
633
+ this.defaultValueDescription = void 0;
634
+ this.presetArg = void 0;
635
+ this.envVar = void 0;
636
+ this.parseArg = void 0;
637
+ this.hidden = false;
638
+ this.argChoices = void 0;
639
+ this.conflictsWith = [];
640
+ this.implied = void 0;
641
+ }
642
+ /**
643
+ * Set the default value, and optionally supply the description to be displayed in the help.
644
+ *
645
+ * @param {*} value
646
+ * @param {string} [description]
647
+ * @return {Option}
648
+ */
649
+ default(value, description) {
650
+ this.defaultValue = value;
651
+ this.defaultValueDescription = description;
652
+ return this;
653
+ }
654
+ /**
655
+ * Preset to use when option used without option-argument, especially optional but also boolean and negated.
656
+ * The custom processing (parseArg) is called.
657
+ *
658
+ * @example
659
+ * new Option('--color').default('GREYSCALE').preset('RGB');
660
+ * new Option('--donate [amount]').preset('20').argParser(parseFloat);
661
+ *
662
+ * @param {*} arg
663
+ * @return {Option}
664
+ */
665
+ preset(arg) {
666
+ this.presetArg = arg;
667
+ return this;
668
+ }
669
+ /**
670
+ * Add option name(s) that conflict with this option.
671
+ * An error will be displayed if conflicting options are found during parsing.
672
+ *
673
+ * @example
674
+ * new Option('--rgb').conflicts('cmyk');
675
+ * new Option('--js').conflicts(['ts', 'jsx']);
676
+ *
677
+ * @param {(string | string[])} names
678
+ * @return {Option}
679
+ */
680
+ conflicts(names) {
681
+ this.conflictsWith = this.conflictsWith.concat(names);
682
+ return this;
683
+ }
684
+ /**
685
+ * Specify implied option values for when this option is set and the implied options are not.
686
+ *
687
+ * The custom processing (parseArg) is not called on the implied values.
688
+ *
689
+ * @example
690
+ * program
691
+ * .addOption(new Option('--log', 'write logging information to file'))
692
+ * .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
693
+ *
694
+ * @param {Object} impliedOptionValues
695
+ * @return {Option}
696
+ */
697
+ implies(impliedOptionValues) {
698
+ let newImplied = impliedOptionValues;
699
+ if (typeof impliedOptionValues === "string") {
700
+ newImplied = { [impliedOptionValues]: true };
701
+ }
702
+ this.implied = Object.assign(this.implied || {}, newImplied);
703
+ return this;
704
+ }
705
+ /**
706
+ * Set environment variable to check for option value.
707
+ *
708
+ * An environment variable is only used if when processed the current option value is
709
+ * undefined, or the source of the current value is 'default' or 'config' or 'env'.
710
+ *
711
+ * @param {string} name
712
+ * @return {Option}
713
+ */
714
+ env(name) {
715
+ this.envVar = name;
716
+ return this;
717
+ }
718
+ /**
719
+ * Set the custom handler for processing CLI option arguments into option values.
720
+ *
721
+ * @param {Function} [fn]
722
+ * @return {Option}
723
+ */
724
+ argParser(fn) {
725
+ this.parseArg = fn;
726
+ return this;
727
+ }
728
+ /**
729
+ * Whether the option is mandatory and must have a value after parsing.
730
+ *
731
+ * @param {boolean} [mandatory=true]
732
+ * @return {Option}
733
+ */
734
+ makeOptionMandatory(mandatory = true) {
735
+ this.mandatory = !!mandatory;
736
+ return this;
737
+ }
738
+ /**
739
+ * Hide option in help.
740
+ *
741
+ * @param {boolean} [hide=true]
742
+ * @return {Option}
743
+ */
744
+ hideHelp(hide = true) {
745
+ this.hidden = !!hide;
746
+ return this;
747
+ }
748
+ /**
749
+ * @package internal use only
750
+ */
751
+ _concatValue(value, previous) {
752
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
753
+ return [value];
754
+ }
755
+ return previous.concat(value);
756
+ }
757
+ /**
758
+ * Only allow option value to be one of choices.
759
+ *
760
+ * @param {string[]} values
761
+ * @return {Option}
762
+ */
763
+ choices(values) {
764
+ this.argChoices = values.slice();
765
+ this.parseArg = (arg, previous) => {
766
+ if (!this.argChoices.includes(arg)) {
767
+ throw new InvalidArgumentError2(`Allowed choices are ${this.argChoices.join(", ")}.`);
768
+ }
769
+ if (this.variadic) {
770
+ return this._concatValue(arg, previous);
771
+ }
772
+ return arg;
773
+ };
774
+ return this;
775
+ }
776
+ /**
777
+ * Return option name.
778
+ *
779
+ * @return {string}
780
+ */
781
+ name() {
782
+ if (this.long) {
783
+ return this.long.replace(/^--/, "");
784
+ }
785
+ return this.short.replace(/^-/, "");
786
+ }
787
+ /**
788
+ * Return option name, in a camelcase format that can be used
789
+ * as a object attribute key.
790
+ *
791
+ * @return {string}
792
+ */
793
+ attributeName() {
794
+ return camelcase(this.name().replace(/^no-/, ""));
795
+ }
796
+ /**
797
+ * Check if `arg` matches the short or long flag.
798
+ *
799
+ * @param {string} arg
800
+ * @return {boolean}
801
+ * @package internal use only
802
+ */
803
+ is(arg) {
804
+ return this.short === arg || this.long === arg;
805
+ }
806
+ /**
807
+ * Return whether a boolean option.
808
+ *
809
+ * Options are one of boolean, negated, required argument, or optional argument.
810
+ *
811
+ * @return {boolean}
812
+ * @package internal use only
813
+ */
814
+ isBoolean() {
815
+ return !this.required && !this.optional && !this.negate;
816
+ }
817
+ };
818
+ var DualOptions = class {
819
+ /**
820
+ * @param {Option[]} options
821
+ */
822
+ constructor(options) {
823
+ this.positiveOptions = /* @__PURE__ */ new Map();
824
+ this.negativeOptions = /* @__PURE__ */ new Map();
825
+ this.dualOptions = /* @__PURE__ */ new Set();
826
+ options.forEach((option) => {
827
+ if (option.negate) {
828
+ this.negativeOptions.set(option.attributeName(), option);
829
+ } else {
830
+ this.positiveOptions.set(option.attributeName(), option);
831
+ }
832
+ });
833
+ this.negativeOptions.forEach((value, key) => {
834
+ if (this.positiveOptions.has(key)) {
835
+ this.dualOptions.add(key);
836
+ }
837
+ });
838
+ }
839
+ /**
840
+ * Did the value come from the option, and not from possible matching dual option?
841
+ *
842
+ * @param {*} value
843
+ * @param {Option} option
844
+ * @returns {boolean}
845
+ */
846
+ valueFromOption(value, option) {
847
+ const optionKey = option.attributeName();
848
+ if (!this.dualOptions.has(optionKey)) return true;
849
+ const preset = this.negativeOptions.get(optionKey).presetArg;
850
+ const negativeValue = preset !== void 0 ? preset : false;
851
+ return option.negate === (negativeValue === value);
852
+ }
853
+ };
854
+ function camelcase(str) {
855
+ return str.split("-").reduce((str2, word) => {
856
+ return str2 + word[0].toUpperCase() + word.slice(1);
857
+ });
858
+ }
859
+ function splitOptionFlags(flags) {
860
+ let shortFlag;
861
+ let longFlag;
862
+ const flagParts = flags.split(/[ |,]+/);
863
+ if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1])) shortFlag = flagParts.shift();
864
+ longFlag = flagParts.shift();
865
+ if (!shortFlag && /^-[^-]$/.test(longFlag)) {
866
+ shortFlag = longFlag;
867
+ longFlag = void 0;
868
+ }
869
+ return { shortFlag, longFlag };
870
+ }
871
+ exports.Option = Option2;
872
+ exports.DualOptions = DualOptions;
873
+ }
874
+ });
875
+
876
+ // node_modules/commander/lib/suggestSimilar.js
877
+ var require_suggestSimilar = __commonJS({
878
+ "node_modules/commander/lib/suggestSimilar.js"(exports) {
879
+ var maxDistance = 3;
880
+ function editDistance(a, b) {
881
+ if (Math.abs(a.length - b.length) > maxDistance) return Math.max(a.length, b.length);
882
+ const d = [];
883
+ for (let i = 0; i <= a.length; i++) {
884
+ d[i] = [i];
885
+ }
886
+ for (let j = 0; j <= b.length; j++) {
887
+ d[0][j] = j;
888
+ }
889
+ for (let j = 1; j <= b.length; j++) {
890
+ for (let i = 1; i <= a.length; i++) {
891
+ let cost = 1;
892
+ if (a[i - 1] === b[j - 1]) {
893
+ cost = 0;
894
+ } else {
895
+ cost = 1;
896
+ }
897
+ d[i][j] = Math.min(
898
+ d[i - 1][j] + 1,
899
+ // deletion
900
+ d[i][j - 1] + 1,
901
+ // insertion
902
+ d[i - 1][j - 1] + cost
903
+ // substitution
904
+ );
905
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
906
+ d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
907
+ }
908
+ }
909
+ }
910
+ return d[a.length][b.length];
911
+ }
912
+ function suggestSimilar(word, candidates) {
913
+ if (!candidates || candidates.length === 0) return "";
914
+ candidates = Array.from(new Set(candidates));
915
+ const searchingOptions = word.startsWith("--");
916
+ if (searchingOptions) {
917
+ word = word.slice(2);
918
+ candidates = candidates.map((candidate) => candidate.slice(2));
919
+ }
920
+ let similar = [];
921
+ let bestDistance = maxDistance;
922
+ const minSimilarity = 0.4;
923
+ candidates.forEach((candidate) => {
924
+ if (candidate.length <= 1) return;
925
+ const distance = editDistance(word, candidate);
926
+ const length = Math.max(word.length, candidate.length);
927
+ const similarity = (length - distance) / length;
928
+ if (similarity > minSimilarity) {
929
+ if (distance < bestDistance) {
930
+ bestDistance = distance;
931
+ similar = [candidate];
932
+ } else if (distance === bestDistance) {
933
+ similar.push(candidate);
934
+ }
935
+ }
936
+ });
937
+ similar.sort((a, b) => a.localeCompare(b));
938
+ if (searchingOptions) {
939
+ similar = similar.map((candidate) => `--${candidate}`);
940
+ }
941
+ if (similar.length > 1) {
942
+ return `
943
+ (Did you mean one of ${similar.join(", ")}?)`;
944
+ }
945
+ if (similar.length === 1) {
946
+ return `
947
+ (Did you mean ${similar[0]}?)`;
948
+ }
949
+ return "";
950
+ }
951
+ exports.suggestSimilar = suggestSimilar;
952
+ }
953
+ });
954
+
955
+ // node_modules/commander/lib/command.js
956
+ var require_command = __commonJS({
957
+ "node_modules/commander/lib/command.js"(exports) {
958
+ var EventEmitter = __require("events").EventEmitter;
959
+ var childProcess = __require("child_process");
960
+ var path6 = __require("path");
961
+ var fs4 = __require("fs");
962
+ var process2 = __require("process");
963
+ var { Argument: Argument2, humanReadableArgName } = require_argument();
964
+ var { CommanderError: CommanderError2 } = require_error();
965
+ var { Help: Help2 } = require_help();
966
+ var { Option: Option2, DualOptions } = require_option();
967
+ var { suggestSimilar } = require_suggestSimilar();
968
+ var Command2 = class _Command extends EventEmitter {
969
+ /**
970
+ * Initialize a new `Command`.
971
+ *
972
+ * @param {string} [name]
973
+ */
974
+ constructor(name) {
975
+ super();
976
+ this.commands = [];
977
+ this.options = [];
978
+ this.parent = null;
979
+ this._allowUnknownOption = false;
980
+ this._allowExcessArguments = true;
981
+ this.registeredArguments = [];
982
+ this._args = this.registeredArguments;
983
+ this.args = [];
984
+ this.rawArgs = [];
985
+ this.processedArgs = [];
986
+ this._scriptPath = null;
987
+ this._name = name || "";
988
+ this._optionValues = {};
989
+ this._optionValueSources = {};
990
+ this._storeOptionsAsProperties = false;
991
+ this._actionHandler = null;
992
+ this._executableHandler = false;
993
+ this._executableFile = null;
994
+ this._executableDir = null;
995
+ this._defaultCommandName = null;
996
+ this._exitCallback = null;
997
+ this._aliases = [];
998
+ this._combineFlagAndOptionalValue = true;
999
+ this._description = "";
1000
+ this._summary = "";
1001
+ this._argsDescription = void 0;
1002
+ this._enablePositionalOptions = false;
1003
+ this._passThroughOptions = false;
1004
+ this._lifeCycleHooks = {};
1005
+ this._showHelpAfterError = false;
1006
+ this._showSuggestionAfterError = true;
1007
+ this._outputConfiguration = {
1008
+ writeOut: (str) => process2.stdout.write(str),
1009
+ writeErr: (str) => process2.stderr.write(str),
1010
+ getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
1011
+ getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
1012
+ outputError: (str, write) => write(str)
1013
+ };
1014
+ this._hidden = false;
1015
+ this._helpOption = void 0;
1016
+ this._addImplicitHelpCommand = void 0;
1017
+ this._helpCommand = void 0;
1018
+ this._helpConfiguration = {};
1019
+ }
1020
+ /**
1021
+ * Copy settings that are useful to have in common across root command and subcommands.
1022
+ *
1023
+ * (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)
1024
+ *
1025
+ * @param {Command} sourceCommand
1026
+ * @return {Command} `this` command for chaining
1027
+ */
1028
+ copyInheritedSettings(sourceCommand) {
1029
+ this._outputConfiguration = sourceCommand._outputConfiguration;
1030
+ this._helpOption = sourceCommand._helpOption;
1031
+ this._helpCommand = sourceCommand._helpCommand;
1032
+ this._helpConfiguration = sourceCommand._helpConfiguration;
1033
+ this._exitCallback = sourceCommand._exitCallback;
1034
+ this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
1035
+ this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
1036
+ this._allowExcessArguments = sourceCommand._allowExcessArguments;
1037
+ this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
1038
+ this._showHelpAfterError = sourceCommand._showHelpAfterError;
1039
+ this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
1040
+ return this;
1041
+ }
1042
+ /**
1043
+ * @returns {Command[]}
1044
+ * @private
1045
+ */
1046
+ _getCommandAndAncestors() {
1047
+ const result = [];
1048
+ for (let command = this; command; command = command.parent) {
1049
+ result.push(command);
1050
+ }
1051
+ return result;
1052
+ }
1053
+ /**
1054
+ * Define a command.
1055
+ *
1056
+ * There are two styles of command: pay attention to where to put the description.
1057
+ *
1058
+ * @example
1059
+ * // Command implemented using action handler (description is supplied separately to `.command`)
1060
+ * program
1061
+ * .command('clone <source> [destination]')
1062
+ * .description('clone a repository into a newly created directory')
1063
+ * .action((source, destination) => {
1064
+ * console.log('clone command called');
1065
+ * });
1066
+ *
1067
+ * // Command implemented using separate executable file (description is second parameter to `.command`)
1068
+ * program
1069
+ * .command('start <service>', 'start named service')
1070
+ * .command('stop [service]', 'stop named service, or all if no name supplied');
1071
+ *
1072
+ * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
1073
+ * @param {(Object|string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
1074
+ * @param {Object} [execOpts] - configuration options (for executable)
1075
+ * @return {Command} returns new command for action handler, or `this` for executable command
1076
+ */
1077
+ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
1078
+ let desc = actionOptsOrExecDesc;
1079
+ let opts = execOpts;
1080
+ if (typeof desc === "object" && desc !== null) {
1081
+ opts = desc;
1082
+ desc = null;
1083
+ }
1084
+ opts = opts || {};
1085
+ const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
1086
+ const cmd = this.createCommand(name);
1087
+ if (desc) {
1088
+ cmd.description(desc);
1089
+ cmd._executableHandler = true;
1090
+ }
1091
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
1092
+ cmd._hidden = !!(opts.noHelp || opts.hidden);
1093
+ cmd._executableFile = opts.executableFile || null;
1094
+ if (args) cmd.arguments(args);
1095
+ this._registerCommand(cmd);
1096
+ cmd.parent = this;
1097
+ cmd.copyInheritedSettings(this);
1098
+ if (desc) return this;
1099
+ return cmd;
1100
+ }
1101
+ /**
1102
+ * Factory routine to create a new unattached command.
1103
+ *
1104
+ * See .command() for creating an attached subcommand, which uses this routine to
1105
+ * create the command. You can override createCommand to customise subcommands.
1106
+ *
1107
+ * @param {string} [name]
1108
+ * @return {Command} new command
1109
+ */
1110
+ createCommand(name) {
1111
+ return new _Command(name);
1112
+ }
1113
+ /**
1114
+ * You can customise the help with a subclass of Help by overriding createHelp,
1115
+ * or by overriding Help properties using configureHelp().
1116
+ *
1117
+ * @return {Help}
1118
+ */
1119
+ createHelp() {
1120
+ return Object.assign(new Help2(), this.configureHelp());
1121
+ }
1122
+ /**
1123
+ * You can customise the help by overriding Help properties using configureHelp(),
1124
+ * or with a subclass of Help by overriding createHelp().
1125
+ *
1126
+ * @param {Object} [configuration] - configuration options
1127
+ * @return {(Command|Object)} `this` command for chaining, or stored configuration
1128
+ */
1129
+ configureHelp(configuration) {
1130
+ if (configuration === void 0) return this._helpConfiguration;
1131
+ this._helpConfiguration = configuration;
1132
+ return this;
1133
+ }
1134
+ /**
1135
+ * The default output goes to stdout and stderr. You can customise this for special
1136
+ * applications. You can also customise the display of errors by overriding outputError.
1137
+ *
1138
+ * The configuration properties are all functions:
1139
+ *
1140
+ * // functions to change where being written, stdout and stderr
1141
+ * writeOut(str)
1142
+ * writeErr(str)
1143
+ * // matching functions to specify width for wrapping help
1144
+ * getOutHelpWidth()
1145
+ * getErrHelpWidth()
1146
+ * // functions based on what is being written out
1147
+ * outputError(str, write) // used for displaying errors, and not used for displaying help
1148
+ *
1149
+ * @param {Object} [configuration] - configuration options
1150
+ * @return {(Command|Object)} `this` command for chaining, or stored configuration
1151
+ */
1152
+ configureOutput(configuration) {
1153
+ if (configuration === void 0) return this._outputConfiguration;
1154
+ Object.assign(this._outputConfiguration, configuration);
1155
+ return this;
1156
+ }
1157
+ /**
1158
+ * Display the help or a custom message after an error occurs.
1159
+ *
1160
+ * @param {(boolean|string)} [displayHelp]
1161
+ * @return {Command} `this` command for chaining
1162
+ */
1163
+ showHelpAfterError(displayHelp = true) {
1164
+ if (typeof displayHelp !== "string") displayHelp = !!displayHelp;
1165
+ this._showHelpAfterError = displayHelp;
1166
+ return this;
1167
+ }
1168
+ /**
1169
+ * Display suggestion of similar commands for unknown commands, or options for unknown options.
1170
+ *
1171
+ * @param {boolean} [displaySuggestion]
1172
+ * @return {Command} `this` command for chaining
1173
+ */
1174
+ showSuggestionAfterError(displaySuggestion = true) {
1175
+ this._showSuggestionAfterError = !!displaySuggestion;
1176
+ return this;
1177
+ }
1178
+ /**
1179
+ * Add a prepared subcommand.
1180
+ *
1181
+ * See .command() for creating an attached subcommand which inherits settings from its parent.
1182
+ *
1183
+ * @param {Command} cmd - new subcommand
1184
+ * @param {Object} [opts] - configuration options
1185
+ * @return {Command} `this` command for chaining
1186
+ */
1187
+ addCommand(cmd, opts) {
1188
+ if (!cmd._name) {
1189
+ throw new Error(`Command passed to .addCommand() must have a name
1190
+ - specify the name in Command constructor or using .name()`);
1191
+ }
1192
+ opts = opts || {};
1193
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
1194
+ if (opts.noHelp || opts.hidden) cmd._hidden = true;
1195
+ this._registerCommand(cmd);
1196
+ cmd.parent = this;
1197
+ cmd._checkForBrokenPassThrough();
1198
+ return this;
1199
+ }
1200
+ /**
1201
+ * Factory routine to create a new unattached argument.
1202
+ *
1203
+ * See .argument() for creating an attached argument, which uses this routine to
1204
+ * create the argument. You can override createArgument to return a custom argument.
1205
+ *
1206
+ * @param {string} name
1207
+ * @param {string} [description]
1208
+ * @return {Argument} new argument
1209
+ */
1210
+ createArgument(name, description) {
1211
+ return new Argument2(name, description);
1212
+ }
1213
+ /**
1214
+ * Define argument syntax for command.
1215
+ *
1216
+ * The default is that the argument is required, and you can explicitly
1217
+ * indicate this with <> around the name. Put [] around the name for an optional argument.
1218
+ *
1219
+ * @example
1220
+ * program.argument('<input-file>');
1221
+ * program.argument('[output-file]');
1222
+ *
1223
+ * @param {string} name
1224
+ * @param {string} [description]
1225
+ * @param {(Function|*)} [fn] - custom argument processing function
1226
+ * @param {*} [defaultValue]
1227
+ * @return {Command} `this` command for chaining
1228
+ */
1229
+ argument(name, description, fn, defaultValue) {
1230
+ const argument = this.createArgument(name, description);
1231
+ if (typeof fn === "function") {
1232
+ argument.default(defaultValue).argParser(fn);
1233
+ } else {
1234
+ argument.default(fn);
1235
+ }
1236
+ this.addArgument(argument);
1237
+ return this;
1238
+ }
1239
+ /**
1240
+ * Define argument syntax for command, adding multiple at once (without descriptions).
1241
+ *
1242
+ * See also .argument().
1243
+ *
1244
+ * @example
1245
+ * program.arguments('<cmd> [env]');
1246
+ *
1247
+ * @param {string} names
1248
+ * @return {Command} `this` command for chaining
1249
+ */
1250
+ arguments(names) {
1251
+ names.trim().split(/ +/).forEach((detail) => {
1252
+ this.argument(detail);
1253
+ });
1254
+ return this;
1255
+ }
1256
+ /**
1257
+ * Define argument syntax for command, adding a prepared argument.
1258
+ *
1259
+ * @param {Argument} argument
1260
+ * @return {Command} `this` command for chaining
1261
+ */
1262
+ addArgument(argument) {
1263
+ const previousArgument = this.registeredArguments.slice(-1)[0];
1264
+ if (previousArgument && previousArgument.variadic) {
1265
+ throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
1266
+ }
1267
+ if (argument.required && argument.defaultValue !== void 0 && argument.parseArg === void 0) {
1268
+ throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
1269
+ }
1270
+ this.registeredArguments.push(argument);
1271
+ return this;
1272
+ }
1273
+ /**
1274
+ * Customise or override default help command. By default a help command is automatically added if your command has subcommands.
1275
+ *
1276
+ * program.helpCommand('help [cmd]');
1277
+ * program.helpCommand('help [cmd]', 'show help');
1278
+ * program.helpCommand(false); // suppress default help command
1279
+ * program.helpCommand(true); // add help command even if no subcommands
1280
+ *
1281
+ * @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
1282
+ * @param {string} [description] - custom description
1283
+ * @return {Command} `this` command for chaining
1284
+ */
1285
+ helpCommand(enableOrNameAndArgs, description) {
1286
+ if (typeof enableOrNameAndArgs === "boolean") {
1287
+ this._addImplicitHelpCommand = enableOrNameAndArgs;
1288
+ return this;
1289
+ }
1290
+ enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
1291
+ const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
1292
+ const helpDescription = description ?? "display help for command";
1293
+ const helpCommand = this.createCommand(helpName);
1294
+ helpCommand.helpOption(false);
1295
+ if (helpArgs) helpCommand.arguments(helpArgs);
1296
+ if (helpDescription) helpCommand.description(helpDescription);
1297
+ this._addImplicitHelpCommand = true;
1298
+ this._helpCommand = helpCommand;
1299
+ return this;
1300
+ }
1301
+ /**
1302
+ * Add prepared custom help command.
1303
+ *
1304
+ * @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
1305
+ * @param {string} [deprecatedDescription] - deprecated custom description used with custom name only
1306
+ * @return {Command} `this` command for chaining
1307
+ */
1308
+ addHelpCommand(helpCommand, deprecatedDescription) {
1309
+ if (typeof helpCommand !== "object") {
1310
+ this.helpCommand(helpCommand, deprecatedDescription);
1311
+ return this;
1312
+ }
1313
+ this._addImplicitHelpCommand = true;
1314
+ this._helpCommand = helpCommand;
1315
+ return this;
1316
+ }
1317
+ /**
1318
+ * Lazy create help command.
1319
+ *
1320
+ * @return {(Command|null)}
1321
+ * @package
1322
+ */
1323
+ _getHelpCommand() {
1324
+ const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
1325
+ if (hasImplicitHelpCommand) {
1326
+ if (this._helpCommand === void 0) {
1327
+ this.helpCommand(void 0, void 0);
1328
+ }
1329
+ return this._helpCommand;
1330
+ }
1331
+ return null;
1332
+ }
1333
+ /**
1334
+ * Add hook for life cycle event.
1335
+ *
1336
+ * @param {string} event
1337
+ * @param {Function} listener
1338
+ * @return {Command} `this` command for chaining
1339
+ */
1340
+ hook(event, listener) {
1341
+ const allowedValues = ["preSubcommand", "preAction", "postAction"];
1342
+ if (!allowedValues.includes(event)) {
1343
+ throw new Error(`Unexpected value for event passed to hook : '${event}'.
1344
+ Expecting one of '${allowedValues.join("', '")}'`);
1345
+ }
1346
+ if (this._lifeCycleHooks[event]) {
1347
+ this._lifeCycleHooks[event].push(listener);
1348
+ } else {
1349
+ this._lifeCycleHooks[event] = [listener];
1350
+ }
1351
+ return this;
1352
+ }
1353
+ /**
1354
+ * Register callback to use as replacement for calling process.exit.
1355
+ *
1356
+ * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing
1357
+ * @return {Command} `this` command for chaining
1358
+ */
1359
+ exitOverride(fn) {
1360
+ if (fn) {
1361
+ this._exitCallback = fn;
1362
+ } else {
1363
+ this._exitCallback = (err) => {
1364
+ if (err.code !== "commander.executeSubCommandAsync") {
1365
+ throw err;
1366
+ }
1367
+ };
1368
+ }
1369
+ return this;
1370
+ }
1371
+ /**
1372
+ * Call process.exit, and _exitCallback if defined.
1373
+ *
1374
+ * @param {number} exitCode exit code for using with process.exit
1375
+ * @param {string} code an id string representing the error
1376
+ * @param {string} message human-readable description of the error
1377
+ * @return never
1378
+ * @private
1379
+ */
1380
+ _exit(exitCode, code, message) {
1381
+ if (this._exitCallback) {
1382
+ this._exitCallback(new CommanderError2(exitCode, code, message));
1383
+ }
1384
+ process2.exit(exitCode);
1385
+ }
1386
+ /**
1387
+ * Register callback `fn` for the command.
1388
+ *
1389
+ * @example
1390
+ * program
1391
+ * .command('serve')
1392
+ * .description('start service')
1393
+ * .action(function() {
1394
+ * // do work here
1395
+ * });
1396
+ *
1397
+ * @param {Function} fn
1398
+ * @return {Command} `this` command for chaining
1399
+ */
1400
+ action(fn) {
1401
+ const listener = (args) => {
1402
+ const expectedArgsCount = this.registeredArguments.length;
1403
+ const actionArgs = args.slice(0, expectedArgsCount);
1404
+ if (this._storeOptionsAsProperties) {
1405
+ actionArgs[expectedArgsCount] = this;
1406
+ } else {
1407
+ actionArgs[expectedArgsCount] = this.opts();
1408
+ }
1409
+ actionArgs.push(this);
1410
+ return fn.apply(this, actionArgs);
1411
+ };
1412
+ this._actionHandler = listener;
1413
+ return this;
1414
+ }
1415
+ /**
1416
+ * Factory routine to create a new unattached option.
1417
+ *
1418
+ * See .option() for creating an attached option, which uses this routine to
1419
+ * create the option. You can override createOption to return a custom option.
1420
+ *
1421
+ * @param {string} flags
1422
+ * @param {string} [description]
1423
+ * @return {Option} new option
1424
+ */
1425
+ createOption(flags, description) {
1426
+ return new Option2(flags, description);
1427
+ }
1428
+ /**
1429
+ * Wrap parseArgs to catch 'commander.invalidArgument'.
1430
+ *
1431
+ * @param {(Option | Argument)} target
1432
+ * @param {string} value
1433
+ * @param {*} previous
1434
+ * @param {string} invalidArgumentMessage
1435
+ * @private
1436
+ */
1437
+ _callParseArg(target, value, previous, invalidArgumentMessage) {
1438
+ try {
1439
+ return target.parseArg(value, previous);
1440
+ } catch (err) {
1441
+ if (err.code === "commander.invalidArgument") {
1442
+ const message = `${invalidArgumentMessage} ${err.message}`;
1443
+ this.error(message, { exitCode: err.exitCode, code: err.code });
1444
+ }
1445
+ throw err;
1446
+ }
1447
+ }
1448
+ /**
1449
+ * Check for option flag conflicts.
1450
+ * Register option if no conflicts found, or throw on conflict.
1451
+ *
1452
+ * @param {Option} option
1453
+ * @api private
1454
+ */
1455
+ _registerOption(option) {
1456
+ const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
1457
+ if (matchingOption) {
1458
+ const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
1459
+ throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
1460
+ - already used by option '${matchingOption.flags}'`);
1461
+ }
1462
+ this.options.push(option);
1463
+ }
1464
+ /**
1465
+ * Check for command name and alias conflicts with existing commands.
1466
+ * Register command if no conflicts found, or throw on conflict.
1467
+ *
1468
+ * @param {Command} command
1469
+ * @api private
1470
+ */
1471
+ _registerCommand(command) {
1472
+ const knownBy = (cmd) => {
1473
+ return [cmd.name()].concat(cmd.aliases());
1474
+ };
1475
+ const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
1476
+ if (alreadyUsed) {
1477
+ const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
1478
+ const newCmd = knownBy(command).join("|");
1479
+ throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
1480
+ }
1481
+ this.commands.push(command);
1482
+ }
1483
+ /**
1484
+ * Add an option.
1485
+ *
1486
+ * @param {Option} option
1487
+ * @return {Command} `this` command for chaining
1488
+ */
1489
+ addOption(option) {
1490
+ this._registerOption(option);
1491
+ const oname = option.name();
1492
+ const name = option.attributeName();
1493
+ if (option.negate) {
1494
+ const positiveLongFlag = option.long.replace(/^--no-/, "--");
1495
+ if (!this._findOption(positiveLongFlag)) {
1496
+ this.setOptionValueWithSource(name, option.defaultValue === void 0 ? true : option.defaultValue, "default");
1497
+ }
1498
+ } else if (option.defaultValue !== void 0) {
1499
+ this.setOptionValueWithSource(name, option.defaultValue, "default");
1500
+ }
1501
+ const handleOptionValue = (val, invalidValueMessage, valueSource) => {
1502
+ if (val == null && option.presetArg !== void 0) {
1503
+ val = option.presetArg;
1504
+ }
1505
+ const oldValue = this.getOptionValue(name);
1506
+ if (val !== null && option.parseArg) {
1507
+ val = this._callParseArg(option, val, oldValue, invalidValueMessage);
1508
+ } else if (val !== null && option.variadic) {
1509
+ val = option._concatValue(val, oldValue);
1510
+ }
1511
+ if (val == null) {
1512
+ if (option.negate) {
1513
+ val = false;
1514
+ } else if (option.isBoolean() || option.optional) {
1515
+ val = true;
1516
+ } else {
1517
+ val = "";
1518
+ }
1519
+ }
1520
+ this.setOptionValueWithSource(name, val, valueSource);
1521
+ };
1522
+ this.on("option:" + oname, (val) => {
1523
+ const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
1524
+ handleOptionValue(val, invalidValueMessage, "cli");
1525
+ });
1526
+ if (option.envVar) {
1527
+ this.on("optionEnv:" + oname, (val) => {
1528
+ const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
1529
+ handleOptionValue(val, invalidValueMessage, "env");
1530
+ });
1531
+ }
1532
+ return this;
1533
+ }
1534
+ /**
1535
+ * Internal implementation shared by .option() and .requiredOption()
1536
+ *
1537
+ * @private
1538
+ */
1539
+ _optionEx(config, flags, description, fn, defaultValue) {
1540
+ if (typeof flags === "object" && flags instanceof Option2) {
1541
+ throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
1542
+ }
1543
+ const option = this.createOption(flags, description);
1544
+ option.makeOptionMandatory(!!config.mandatory);
1545
+ if (typeof fn === "function") {
1546
+ option.default(defaultValue).argParser(fn);
1547
+ } else if (fn instanceof RegExp) {
1548
+ const regex = fn;
1549
+ fn = (val, def) => {
1550
+ const m = regex.exec(val);
1551
+ return m ? m[0] : def;
1552
+ };
1553
+ option.default(defaultValue).argParser(fn);
1554
+ } else {
1555
+ option.default(fn);
1556
+ }
1557
+ return this.addOption(option);
1558
+ }
1559
+ /**
1560
+ * Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
1561
+ *
1562
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
1563
+ * option-argument is indicated by `<>` and an optional option-argument by `[]`.
1564
+ *
1565
+ * See the README for more details, and see also addOption() and requiredOption().
1566
+ *
1567
+ * @example
1568
+ * program
1569
+ * .option('-p, --pepper', 'add pepper')
1570
+ * .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
1571
+ * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
1572
+ * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
1573
+ *
1574
+ * @param {string} flags
1575
+ * @param {string} [description]
1576
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
1577
+ * @param {*} [defaultValue]
1578
+ * @return {Command} `this` command for chaining
1579
+ */
1580
+ option(flags, description, parseArg, defaultValue) {
1581
+ return this._optionEx({}, flags, description, parseArg, defaultValue);
1582
+ }
1583
+ /**
1584
+ * Add a required option which must have a value after parsing. This usually means
1585
+ * the option must be specified on the command line. (Otherwise the same as .option().)
1586
+ *
1587
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
1588
+ *
1589
+ * @param {string} flags
1590
+ * @param {string} [description]
1591
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
1592
+ * @param {*} [defaultValue]
1593
+ * @return {Command} `this` command for chaining
1594
+ */
1595
+ requiredOption(flags, description, parseArg, defaultValue) {
1596
+ return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
1597
+ }
1598
+ /**
1599
+ * Alter parsing of short flags with optional values.
1600
+ *
1601
+ * @example
1602
+ * // for `.option('-f,--flag [value]'):
1603
+ * program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
1604
+ * program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
1605
+ *
1606
+ * @param {boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
1607
+ */
1608
+ combineFlagAndOptionalValue(combine = true) {
1609
+ this._combineFlagAndOptionalValue = !!combine;
1610
+ return this;
1611
+ }
1612
+ /**
1613
+ * Allow unknown options on the command line.
1614
+ *
1615
+ * @param {boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
1616
+ * for unknown options.
1617
+ */
1618
+ allowUnknownOption(allowUnknown = true) {
1619
+ this._allowUnknownOption = !!allowUnknown;
1620
+ return this;
1621
+ }
1622
+ /**
1623
+ * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
1624
+ *
1625
+ * @param {boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
1626
+ * for excess arguments.
1627
+ */
1628
+ allowExcessArguments(allowExcess = true) {
1629
+ this._allowExcessArguments = !!allowExcess;
1630
+ return this;
1631
+ }
1632
+ /**
1633
+ * Enable positional options. Positional means global options are specified before subcommands which lets
1634
+ * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
1635
+ * The default behaviour is non-positional and global options may appear anywhere on the command line.
1636
+ *
1637
+ * @param {boolean} [positional=true]
1638
+ */
1639
+ enablePositionalOptions(positional = true) {
1640
+ this._enablePositionalOptions = !!positional;
1641
+ return this;
1642
+ }
1643
+ /**
1644
+ * Pass through options that come after command-arguments rather than treat them as command-options,
1645
+ * so actual command-options come before command-arguments. Turning this on for a subcommand requires
1646
+ * positional options to have been enabled on the program (parent commands).
1647
+ * The default behaviour is non-positional and options may appear before or after command-arguments.
1648
+ *
1649
+ * @param {boolean} [passThrough=true]
1650
+ * for unknown options.
1651
+ */
1652
+ passThroughOptions(passThrough = true) {
1653
+ this._passThroughOptions = !!passThrough;
1654
+ this._checkForBrokenPassThrough();
1655
+ return this;
1656
+ }
1657
+ /**
1658
+ * @private
1659
+ */
1660
+ _checkForBrokenPassThrough() {
1661
+ if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
1662
+ throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
1663
+ }
1664
+ }
1665
+ /**
1666
+ * Whether to store option values as properties on command object,
1667
+ * or store separately (specify false). In both cases the option values can be accessed using .opts().
1668
+ *
1669
+ * @param {boolean} [storeAsProperties=true]
1670
+ * @return {Command} `this` command for chaining
1671
+ */
1672
+ storeOptionsAsProperties(storeAsProperties = true) {
1673
+ if (this.options.length) {
1674
+ throw new Error("call .storeOptionsAsProperties() before adding options");
1675
+ }
1676
+ if (Object.keys(this._optionValues).length) {
1677
+ throw new Error("call .storeOptionsAsProperties() before setting option values");
1678
+ }
1679
+ this._storeOptionsAsProperties = !!storeAsProperties;
1680
+ return this;
1681
+ }
1682
+ /**
1683
+ * Retrieve option value.
1684
+ *
1685
+ * @param {string} key
1686
+ * @return {Object} value
1687
+ */
1688
+ getOptionValue(key) {
1689
+ if (this._storeOptionsAsProperties) {
1690
+ return this[key];
1691
+ }
1692
+ return this._optionValues[key];
1693
+ }
1694
+ /**
1695
+ * Store option value.
1696
+ *
1697
+ * @param {string} key
1698
+ * @param {Object} value
1699
+ * @return {Command} `this` command for chaining
1700
+ */
1701
+ setOptionValue(key, value) {
1702
+ return this.setOptionValueWithSource(key, value, void 0);
1703
+ }
1704
+ /**
1705
+ * Store option value and where the value came from.
1706
+ *
1707
+ * @param {string} key
1708
+ * @param {Object} value
1709
+ * @param {string} source - expected values are default/config/env/cli/implied
1710
+ * @return {Command} `this` command for chaining
1711
+ */
1712
+ setOptionValueWithSource(key, value, source) {
1713
+ if (this._storeOptionsAsProperties) {
1714
+ this[key] = value;
1715
+ } else {
1716
+ this._optionValues[key] = value;
1717
+ }
1718
+ this._optionValueSources[key] = source;
1719
+ return this;
1720
+ }
1721
+ /**
1722
+ * Get source of option value.
1723
+ * Expected values are default | config | env | cli | implied
1724
+ *
1725
+ * @param {string} key
1726
+ * @return {string}
1727
+ */
1728
+ getOptionValueSource(key) {
1729
+ return this._optionValueSources[key];
1730
+ }
1731
+ /**
1732
+ * Get source of option value. See also .optsWithGlobals().
1733
+ * Expected values are default | config | env | cli | implied
1734
+ *
1735
+ * @param {string} key
1736
+ * @return {string}
1737
+ */
1738
+ getOptionValueSourceWithGlobals(key) {
1739
+ let source;
1740
+ this._getCommandAndAncestors().forEach((cmd) => {
1741
+ if (cmd.getOptionValueSource(key) !== void 0) {
1742
+ source = cmd.getOptionValueSource(key);
1743
+ }
1744
+ });
1745
+ return source;
1746
+ }
1747
+ /**
1748
+ * Get user arguments from implied or explicit arguments.
1749
+ * Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
1750
+ *
1751
+ * @private
1752
+ */
1753
+ _prepareUserArgs(argv, parseOptions) {
1754
+ if (argv !== void 0 && !Array.isArray(argv)) {
1755
+ throw new Error("first parameter to parse must be array or undefined");
1756
+ }
1757
+ parseOptions = parseOptions || {};
1758
+ if (argv === void 0) {
1759
+ argv = process2.argv;
1760
+ if (process2.versions && process2.versions.electron) {
1761
+ parseOptions.from = "electron";
1762
+ }
1763
+ }
1764
+ this.rawArgs = argv.slice();
1765
+ let userArgs;
1766
+ switch (parseOptions.from) {
1767
+ case void 0:
1768
+ case "node":
1769
+ this._scriptPath = argv[1];
1770
+ userArgs = argv.slice(2);
1771
+ break;
1772
+ case "electron":
1773
+ if (process2.defaultApp) {
1774
+ this._scriptPath = argv[1];
1775
+ userArgs = argv.slice(2);
1776
+ } else {
1777
+ userArgs = argv.slice(1);
1778
+ }
1779
+ break;
1780
+ case "user":
1781
+ userArgs = argv.slice(0);
1782
+ break;
1783
+ default:
1784
+ throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
1785
+ }
1786
+ if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath);
1787
+ this._name = this._name || "program";
1788
+ return userArgs;
1789
+ }
1790
+ /**
1791
+ * Parse `argv`, setting options and invoking commands when defined.
1792
+ *
1793
+ * The default expectation is that the arguments are from node and have the application as argv[0]
1794
+ * and the script being run in argv[1], with user parameters after that.
1795
+ *
1796
+ * @example
1797
+ * program.parse(process.argv);
1798
+ * program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
1799
+ * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
1800
+ *
1801
+ * @param {string[]} [argv] - optional, defaults to process.argv
1802
+ * @param {Object} [parseOptions] - optionally specify style of options with from: node/user/electron
1803
+ * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
1804
+ * @return {Command} `this` command for chaining
1805
+ */
1806
+ parse(argv, parseOptions) {
1807
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
1808
+ this._parseCommand([], userArgs);
1809
+ return this;
1810
+ }
1811
+ /**
1812
+ * Parse `argv`, setting options and invoking commands when defined.
1813
+ *
1814
+ * Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
1815
+ *
1816
+ * The default expectation is that the arguments are from node and have the application as argv[0]
1817
+ * and the script being run in argv[1], with user parameters after that.
1818
+ *
1819
+ * @example
1820
+ * await program.parseAsync(process.argv);
1821
+ * await program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
1822
+ * await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
1823
+ *
1824
+ * @param {string[]} [argv]
1825
+ * @param {Object} [parseOptions]
1826
+ * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
1827
+ * @return {Promise}
1828
+ */
1829
+ async parseAsync(argv, parseOptions) {
1830
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
1831
+ await this._parseCommand([], userArgs);
1832
+ return this;
1833
+ }
1834
+ /**
1835
+ * Execute a sub-command executable.
1836
+ *
1837
+ * @private
1838
+ */
1839
+ _executeSubCommand(subcommand, args) {
1840
+ args = args.slice();
1841
+ let launchWithNode = false;
1842
+ const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1843
+ function findFile(baseDir, baseName) {
1844
+ const localBin = path6.resolve(baseDir, baseName);
1845
+ if (fs4.existsSync(localBin)) return localBin;
1846
+ if (sourceExt.includes(path6.extname(baseName))) return void 0;
1847
+ const foundExt = sourceExt.find((ext) => fs4.existsSync(`${localBin}${ext}`));
1848
+ if (foundExt) return `${localBin}${foundExt}`;
1849
+ return void 0;
1850
+ }
1851
+ this._checkForMissingMandatoryOptions();
1852
+ this._checkForConflictingOptions();
1853
+ let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
1854
+ let executableDir = this._executableDir || "";
1855
+ if (this._scriptPath) {
1856
+ let resolvedScriptPath;
1857
+ try {
1858
+ resolvedScriptPath = fs4.realpathSync(this._scriptPath);
1859
+ } catch (err) {
1860
+ resolvedScriptPath = this._scriptPath;
1861
+ }
1862
+ executableDir = path6.resolve(path6.dirname(resolvedScriptPath), executableDir);
1863
+ }
1864
+ if (executableDir) {
1865
+ let localFile = findFile(executableDir, executableFile);
1866
+ if (!localFile && !subcommand._executableFile && this._scriptPath) {
1867
+ const legacyName = path6.basename(this._scriptPath, path6.extname(this._scriptPath));
1868
+ if (legacyName !== this._name) {
1869
+ localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
1870
+ }
1871
+ }
1872
+ executableFile = localFile || executableFile;
1873
+ }
1874
+ launchWithNode = sourceExt.includes(path6.extname(executableFile));
1875
+ let proc;
1876
+ if (process2.platform !== "win32") {
1877
+ if (launchWithNode) {
1878
+ args.unshift(executableFile);
1879
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1880
+ proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
1881
+ } else {
1882
+ proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1883
+ }
1884
+ } else {
1885
+ args.unshift(executableFile);
1886
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1887
+ proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
1888
+ }
1889
+ if (!proc.killed) {
1890
+ const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
1891
+ signals.forEach((signal) => {
1892
+ process2.on(signal, () => {
1893
+ if (proc.killed === false && proc.exitCode === null) {
1894
+ proc.kill(signal);
1895
+ }
1896
+ });
1897
+ });
1898
+ }
1899
+ const exitCallback = this._exitCallback;
1900
+ proc.on("close", (code, _signal) => {
1901
+ code = code ?? 1;
1902
+ if (!exitCallback) {
1903
+ process2.exit(code);
1904
+ } else {
1905
+ exitCallback(new CommanderError2(code, "commander.executeSubCommandAsync", "(close)"));
1906
+ }
1907
+ });
1908
+ proc.on("error", (err) => {
1909
+ if (err.code === "ENOENT") {
1910
+ const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
1911
+ const executableMissing = `'${executableFile}' does not exist
1912
+ - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1913
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1914
+ - ${executableDirMessage}`;
1915
+ throw new Error(executableMissing);
1916
+ } else if (err.code === "EACCES") {
1917
+ throw new Error(`'${executableFile}' not executable`);
1918
+ }
1919
+ if (!exitCallback) {
1920
+ process2.exit(1);
1921
+ } else {
1922
+ const wrappedError = new CommanderError2(1, "commander.executeSubCommandAsync", "(error)");
1923
+ wrappedError.nestedError = err;
1924
+ exitCallback(wrappedError);
1925
+ }
1926
+ });
1927
+ this.runningCommand = proc;
1928
+ }
1929
+ /**
1930
+ * @private
1931
+ */
1932
+ _dispatchSubcommand(commandName, operands, unknown) {
1933
+ const subCommand = this._findCommand(commandName);
1934
+ if (!subCommand) this.help({ error: true });
1935
+ let promiseChain;
1936
+ promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
1937
+ promiseChain = this._chainOrCall(promiseChain, () => {
1938
+ if (subCommand._executableHandler) {
1939
+ this._executeSubCommand(subCommand, operands.concat(unknown));
1940
+ } else {
1941
+ return subCommand._parseCommand(operands, unknown);
1942
+ }
1943
+ });
1944
+ return promiseChain;
1945
+ }
1946
+ /**
1947
+ * Invoke help directly if possible, or dispatch if necessary.
1948
+ * e.g. help foo
1949
+ *
1950
+ * @private
1951
+ */
1952
+ _dispatchHelpCommand(subcommandName) {
1953
+ if (!subcommandName) {
1954
+ this.help();
1955
+ }
1956
+ const subCommand = this._findCommand(subcommandName);
1957
+ if (subCommand && !subCommand._executableHandler) {
1958
+ subCommand.help();
1959
+ }
1960
+ return this._dispatchSubcommand(subcommandName, [], [
1961
+ this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"
1962
+ ]);
1963
+ }
1964
+ /**
1965
+ * Check this.args against expected this.registeredArguments.
1966
+ *
1967
+ * @private
1968
+ */
1969
+ _checkNumberOfArguments() {
1970
+ this.registeredArguments.forEach((arg, i) => {
1971
+ if (arg.required && this.args[i] == null) {
1972
+ this.missingArgument(arg.name());
1973
+ }
1974
+ });
1975
+ if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
1976
+ return;
1977
+ }
1978
+ if (this.args.length > this.registeredArguments.length) {
1979
+ this._excessArguments(this.args);
1980
+ }
1981
+ }
1982
+ /**
1983
+ * Process this.args using this.registeredArguments and save as this.processedArgs!
1984
+ *
1985
+ * @private
1986
+ */
1987
+ _processArguments() {
1988
+ const myParseArg = (argument, value, previous) => {
1989
+ let parsedValue = value;
1990
+ if (value !== null && argument.parseArg) {
1991
+ const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
1992
+ parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
1993
+ }
1994
+ return parsedValue;
1995
+ };
1996
+ this._checkNumberOfArguments();
1997
+ const processedArgs = [];
1998
+ this.registeredArguments.forEach((declaredArg, index) => {
1999
+ let value = declaredArg.defaultValue;
2000
+ if (declaredArg.variadic) {
2001
+ if (index < this.args.length) {
2002
+ value = this.args.slice(index);
2003
+ if (declaredArg.parseArg) {
2004
+ value = value.reduce((processed, v) => {
2005
+ return myParseArg(declaredArg, v, processed);
2006
+ }, declaredArg.defaultValue);
2007
+ }
2008
+ } else if (value === void 0) {
2009
+ value = [];
2010
+ }
2011
+ } else if (index < this.args.length) {
2012
+ value = this.args[index];
2013
+ if (declaredArg.parseArg) {
2014
+ value = myParseArg(declaredArg, value, declaredArg.defaultValue);
2015
+ }
2016
+ }
2017
+ processedArgs[index] = value;
2018
+ });
2019
+ this.processedArgs = processedArgs;
2020
+ }
2021
+ /**
2022
+ * Once we have a promise we chain, but call synchronously until then.
2023
+ *
2024
+ * @param {(Promise|undefined)} promise
2025
+ * @param {Function} fn
2026
+ * @return {(Promise|undefined)}
2027
+ * @private
2028
+ */
2029
+ _chainOrCall(promise, fn) {
2030
+ if (promise && promise.then && typeof promise.then === "function") {
2031
+ return promise.then(() => fn());
2032
+ }
2033
+ return fn();
2034
+ }
2035
+ /**
2036
+ *
2037
+ * @param {(Promise|undefined)} promise
2038
+ * @param {string} event
2039
+ * @return {(Promise|undefined)}
2040
+ * @private
2041
+ */
2042
+ _chainOrCallHooks(promise, event) {
2043
+ let result = promise;
2044
+ const hooks = [];
2045
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== void 0).forEach((hookedCommand) => {
2046
+ hookedCommand._lifeCycleHooks[event].forEach((callback) => {
2047
+ hooks.push({ hookedCommand, callback });
2048
+ });
2049
+ });
2050
+ if (event === "postAction") {
2051
+ hooks.reverse();
2052
+ }
2053
+ hooks.forEach((hookDetail) => {
2054
+ result = this._chainOrCall(result, () => {
2055
+ return hookDetail.callback(hookDetail.hookedCommand, this);
2056
+ });
2057
+ });
2058
+ return result;
2059
+ }
2060
+ /**
2061
+ *
2062
+ * @param {(Promise|undefined)} promise
2063
+ * @param {Command} subCommand
2064
+ * @param {string} event
2065
+ * @return {(Promise|undefined)}
2066
+ * @private
2067
+ */
2068
+ _chainOrCallSubCommandHook(promise, subCommand, event) {
2069
+ let result = promise;
2070
+ if (this._lifeCycleHooks[event] !== void 0) {
2071
+ this._lifeCycleHooks[event].forEach((hook) => {
2072
+ result = this._chainOrCall(result, () => {
2073
+ return hook(this, subCommand);
2074
+ });
2075
+ });
2076
+ }
2077
+ return result;
2078
+ }
2079
+ /**
2080
+ * Process arguments in context of this command.
2081
+ * Returns action result, in case it is a promise.
2082
+ *
2083
+ * @private
2084
+ */
2085
+ _parseCommand(operands, unknown) {
2086
+ const parsed = this.parseOptions(unknown);
2087
+ this._parseOptionsEnv();
2088
+ this._parseOptionsImplied();
2089
+ operands = operands.concat(parsed.operands);
2090
+ unknown = parsed.unknown;
2091
+ this.args = operands.concat(unknown);
2092
+ if (operands && this._findCommand(operands[0])) {
2093
+ return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
2094
+ }
2095
+ if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
2096
+ return this._dispatchHelpCommand(operands[1]);
2097
+ }
2098
+ if (this._defaultCommandName) {
2099
+ this._outputHelpIfRequested(unknown);
2100
+ return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
2101
+ }
2102
+ if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
2103
+ this.help({ error: true });
2104
+ }
2105
+ this._outputHelpIfRequested(parsed.unknown);
2106
+ this._checkForMissingMandatoryOptions();
2107
+ this._checkForConflictingOptions();
2108
+ const checkForUnknownOptions = () => {
2109
+ if (parsed.unknown.length > 0) {
2110
+ this.unknownOption(parsed.unknown[0]);
2111
+ }
2112
+ };
2113
+ const commandEvent = `command:${this.name()}`;
2114
+ if (this._actionHandler) {
2115
+ checkForUnknownOptions();
2116
+ this._processArguments();
2117
+ let promiseChain;
2118
+ promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
2119
+ promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
2120
+ if (this.parent) {
2121
+ promiseChain = this._chainOrCall(promiseChain, () => {
2122
+ this.parent.emit(commandEvent, operands, unknown);
2123
+ });
2124
+ }
2125
+ promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
2126
+ return promiseChain;
2127
+ }
2128
+ if (this.parent && this.parent.listenerCount(commandEvent)) {
2129
+ checkForUnknownOptions();
2130
+ this._processArguments();
2131
+ this.parent.emit(commandEvent, operands, unknown);
2132
+ } else if (operands.length) {
2133
+ if (this._findCommand("*")) {
2134
+ return this._dispatchSubcommand("*", operands, unknown);
2135
+ }
2136
+ if (this.listenerCount("command:*")) {
2137
+ this.emit("command:*", operands, unknown);
2138
+ } else if (this.commands.length) {
2139
+ this.unknownCommand();
2140
+ } else {
2141
+ checkForUnknownOptions();
2142
+ this._processArguments();
2143
+ }
2144
+ } else if (this.commands.length) {
2145
+ checkForUnknownOptions();
2146
+ this.help({ error: true });
2147
+ } else {
2148
+ checkForUnknownOptions();
2149
+ this._processArguments();
2150
+ }
2151
+ }
2152
+ /**
2153
+ * Find matching command.
2154
+ *
2155
+ * @private
2156
+ */
2157
+ _findCommand(name) {
2158
+ if (!name) return void 0;
2159
+ return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
2160
+ }
2161
+ /**
2162
+ * Return an option matching `arg` if any.
2163
+ *
2164
+ * @param {string} arg
2165
+ * @return {Option}
2166
+ * @package internal use only
2167
+ */
2168
+ _findOption(arg) {
2169
+ return this.options.find((option) => option.is(arg));
2170
+ }
2171
+ /**
2172
+ * Display an error message if a mandatory option does not have a value.
2173
+ * Called after checking for help flags in leaf subcommand.
2174
+ *
2175
+ * @private
2176
+ */
2177
+ _checkForMissingMandatoryOptions() {
2178
+ this._getCommandAndAncestors().forEach((cmd) => {
2179
+ cmd.options.forEach((anOption) => {
2180
+ if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === void 0) {
2181
+ cmd.missingMandatoryOptionValue(anOption);
2182
+ }
2183
+ });
2184
+ });
2185
+ }
2186
+ /**
2187
+ * Display an error message if conflicting options are used together in this.
2188
+ *
2189
+ * @private
2190
+ */
2191
+ _checkForConflictingLocalOptions() {
2192
+ const definedNonDefaultOptions = this.options.filter(
2193
+ (option) => {
2194
+ const optionKey = option.attributeName();
2195
+ if (this.getOptionValue(optionKey) === void 0) {
2196
+ return false;
2197
+ }
2198
+ return this.getOptionValueSource(optionKey) !== "default";
2199
+ }
2200
+ );
2201
+ const optionsWithConflicting = definedNonDefaultOptions.filter(
2202
+ (option) => option.conflictsWith.length > 0
2203
+ );
2204
+ optionsWithConflicting.forEach((option) => {
2205
+ const conflictingAndDefined = definedNonDefaultOptions.find(
2206
+ (defined) => option.conflictsWith.includes(defined.attributeName())
2207
+ );
2208
+ if (conflictingAndDefined) {
2209
+ this._conflictingOption(option, conflictingAndDefined);
2210
+ }
2211
+ });
2212
+ }
2213
+ /**
2214
+ * Display an error message if conflicting options are used together.
2215
+ * Called after checking for help flags in leaf subcommand.
2216
+ *
2217
+ * @private
2218
+ */
2219
+ _checkForConflictingOptions() {
2220
+ this._getCommandAndAncestors().forEach((cmd) => {
2221
+ cmd._checkForConflictingLocalOptions();
2222
+ });
2223
+ }
2224
+ /**
2225
+ * Parse options from `argv` removing known options,
2226
+ * and return argv split into operands and unknown arguments.
2227
+ *
2228
+ * Examples:
2229
+ *
2230
+ * argv => operands, unknown
2231
+ * --known kkk op => [op], []
2232
+ * op --known kkk => [op], []
2233
+ * sub --unknown uuu op => [sub], [--unknown uuu op]
2234
+ * sub -- --unknown uuu op => [sub --unknown uuu op], []
2235
+ *
2236
+ * @param {string[]} argv
2237
+ * @return {{operands: string[], unknown: string[]}}
2238
+ */
2239
+ parseOptions(argv) {
2240
+ const operands = [];
2241
+ const unknown = [];
2242
+ let dest = operands;
2243
+ const args = argv.slice();
2244
+ function maybeOption(arg) {
2245
+ return arg.length > 1 && arg[0] === "-";
2246
+ }
2247
+ let activeVariadicOption = null;
2248
+ while (args.length) {
2249
+ const arg = args.shift();
2250
+ if (arg === "--") {
2251
+ if (dest === unknown) dest.push(arg);
2252
+ dest.push(...args);
2253
+ break;
2254
+ }
2255
+ if (activeVariadicOption && !maybeOption(arg)) {
2256
+ this.emit(`option:${activeVariadicOption.name()}`, arg);
2257
+ continue;
2258
+ }
2259
+ activeVariadicOption = null;
2260
+ if (maybeOption(arg)) {
2261
+ const option = this._findOption(arg);
2262
+ if (option) {
2263
+ if (option.required) {
2264
+ const value = args.shift();
2265
+ if (value === void 0) this.optionMissingArgument(option);
2266
+ this.emit(`option:${option.name()}`, value);
2267
+ } else if (option.optional) {
2268
+ let value = null;
2269
+ if (args.length > 0 && !maybeOption(args[0])) {
2270
+ value = args.shift();
2271
+ }
2272
+ this.emit(`option:${option.name()}`, value);
2273
+ } else {
2274
+ this.emit(`option:${option.name()}`);
2275
+ }
2276
+ activeVariadicOption = option.variadic ? option : null;
2277
+ continue;
2278
+ }
2279
+ }
2280
+ if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
2281
+ const option = this._findOption(`-${arg[1]}`);
2282
+ if (option) {
2283
+ if (option.required || option.optional && this._combineFlagAndOptionalValue) {
2284
+ this.emit(`option:${option.name()}`, arg.slice(2));
2285
+ } else {
2286
+ this.emit(`option:${option.name()}`);
2287
+ args.unshift(`-${arg.slice(2)}`);
2288
+ }
2289
+ continue;
2290
+ }
2291
+ }
2292
+ if (/^--[^=]+=/.test(arg)) {
2293
+ const index = arg.indexOf("=");
2294
+ const option = this._findOption(arg.slice(0, index));
2295
+ if (option && (option.required || option.optional)) {
2296
+ this.emit(`option:${option.name()}`, arg.slice(index + 1));
2297
+ continue;
2298
+ }
2299
+ }
2300
+ if (maybeOption(arg)) {
2301
+ dest = unknown;
2302
+ }
2303
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
2304
+ if (this._findCommand(arg)) {
2305
+ operands.push(arg);
2306
+ if (args.length > 0) unknown.push(...args);
2307
+ break;
2308
+ } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
2309
+ operands.push(arg);
2310
+ if (args.length > 0) operands.push(...args);
2311
+ break;
2312
+ } else if (this._defaultCommandName) {
2313
+ unknown.push(arg);
2314
+ if (args.length > 0) unknown.push(...args);
2315
+ break;
2316
+ }
2317
+ }
2318
+ if (this._passThroughOptions) {
2319
+ dest.push(arg);
2320
+ if (args.length > 0) dest.push(...args);
2321
+ break;
2322
+ }
2323
+ dest.push(arg);
2324
+ }
2325
+ return { operands, unknown };
2326
+ }
2327
+ /**
2328
+ * Return an object containing local option values as key-value pairs.
2329
+ *
2330
+ * @return {Object}
2331
+ */
2332
+ opts() {
2333
+ if (this._storeOptionsAsProperties) {
2334
+ const result = {};
2335
+ const len = this.options.length;
2336
+ for (let i = 0; i < len; i++) {
2337
+ const key = this.options[i].attributeName();
2338
+ result[key] = key === this._versionOptionName ? this._version : this[key];
2339
+ }
2340
+ return result;
2341
+ }
2342
+ return this._optionValues;
2343
+ }
2344
+ /**
2345
+ * Return an object containing merged local and global option values as key-value pairs.
2346
+ *
2347
+ * @return {Object}
2348
+ */
2349
+ optsWithGlobals() {
2350
+ return this._getCommandAndAncestors().reduce(
2351
+ (combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()),
2352
+ {}
2353
+ );
2354
+ }
2355
+ /**
2356
+ * Display error message and exit (or call exitOverride).
2357
+ *
2358
+ * @param {string} message
2359
+ * @param {Object} [errorOptions]
2360
+ * @param {string} [errorOptions.code] - an id string representing the error
2361
+ * @param {number} [errorOptions.exitCode] - used with process.exit
2362
+ */
2363
+ error(message, errorOptions) {
2364
+ this._outputConfiguration.outputError(`${message}
2365
+ `, this._outputConfiguration.writeErr);
2366
+ if (typeof this._showHelpAfterError === "string") {
2367
+ this._outputConfiguration.writeErr(`${this._showHelpAfterError}
2368
+ `);
2369
+ } else if (this._showHelpAfterError) {
2370
+ this._outputConfiguration.writeErr("\n");
2371
+ this.outputHelp({ error: true });
2372
+ }
2373
+ const config = errorOptions || {};
2374
+ const exitCode = config.exitCode || 1;
2375
+ const code = config.code || "commander.error";
2376
+ this._exit(exitCode, code, message);
2377
+ }
2378
+ /**
2379
+ * Apply any option related environment variables, if option does
2380
+ * not have a value from cli or client code.
2381
+ *
2382
+ * @private
2383
+ */
2384
+ _parseOptionsEnv() {
2385
+ this.options.forEach((option) => {
2386
+ if (option.envVar && option.envVar in process2.env) {
2387
+ const optionKey = option.attributeName();
2388
+ if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
2389
+ if (option.required || option.optional) {
2390
+ this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
2391
+ } else {
2392
+ this.emit(`optionEnv:${option.name()}`);
2393
+ }
2394
+ }
2395
+ }
2396
+ });
2397
+ }
2398
+ /**
2399
+ * Apply any implied option values, if option is undefined or default value.
2400
+ *
2401
+ * @private
2402
+ */
2403
+ _parseOptionsImplied() {
2404
+ const dualHelper = new DualOptions(this.options);
2405
+ const hasCustomOptionValue = (optionKey) => {
2406
+ return this.getOptionValue(optionKey) !== void 0 && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
2407
+ };
2408
+ this.options.filter((option) => option.implied !== void 0 && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
2409
+ Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
2410
+ this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
2411
+ });
2412
+ });
2413
+ }
2414
+ /**
2415
+ * Argument `name` is missing.
2416
+ *
2417
+ * @param {string} name
2418
+ * @private
2419
+ */
2420
+ missingArgument(name) {
2421
+ const message = `error: missing required argument '${name}'`;
2422
+ this.error(message, { code: "commander.missingArgument" });
2423
+ }
2424
+ /**
2425
+ * `Option` is missing an argument.
2426
+ *
2427
+ * @param {Option} option
2428
+ * @private
2429
+ */
2430
+ optionMissingArgument(option) {
2431
+ const message = `error: option '${option.flags}' argument missing`;
2432
+ this.error(message, { code: "commander.optionMissingArgument" });
2433
+ }
2434
+ /**
2435
+ * `Option` does not have a value, and is a mandatory option.
2436
+ *
2437
+ * @param {Option} option
2438
+ * @private
2439
+ */
2440
+ missingMandatoryOptionValue(option) {
2441
+ const message = `error: required option '${option.flags}' not specified`;
2442
+ this.error(message, { code: "commander.missingMandatoryOptionValue" });
2443
+ }
2444
+ /**
2445
+ * `Option` conflicts with another option.
2446
+ *
2447
+ * @param {Option} option
2448
+ * @param {Option} conflictingOption
2449
+ * @private
2450
+ */
2451
+ _conflictingOption(option, conflictingOption) {
2452
+ const findBestOptionFromValue = (option2) => {
2453
+ const optionKey = option2.attributeName();
2454
+ const optionValue = this.getOptionValue(optionKey);
2455
+ const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
2456
+ const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
2457
+ if (negativeOption && (negativeOption.presetArg === void 0 && optionValue === false || negativeOption.presetArg !== void 0 && optionValue === negativeOption.presetArg)) {
2458
+ return negativeOption;
2459
+ }
2460
+ return positiveOption || option2;
2461
+ };
2462
+ const getErrorMessage = (option2) => {
2463
+ const bestOption = findBestOptionFromValue(option2);
2464
+ const optionKey = bestOption.attributeName();
2465
+ const source = this.getOptionValueSource(optionKey);
2466
+ if (source === "env") {
2467
+ return `environment variable '${bestOption.envVar}'`;
2468
+ }
2469
+ return `option '${bestOption.flags}'`;
2470
+ };
2471
+ const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
2472
+ this.error(message, { code: "commander.conflictingOption" });
2473
+ }
2474
+ /**
2475
+ * Unknown option `flag`.
2476
+ *
2477
+ * @param {string} flag
2478
+ * @private
2479
+ */
2480
+ unknownOption(flag) {
2481
+ if (this._allowUnknownOption) return;
2482
+ let suggestion = "";
2483
+ if (flag.startsWith("--") && this._showSuggestionAfterError) {
2484
+ let candidateFlags = [];
2485
+ let command = this;
2486
+ do {
2487
+ const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
2488
+ candidateFlags = candidateFlags.concat(moreFlags);
2489
+ command = command.parent;
2490
+ } while (command && !command._enablePositionalOptions);
2491
+ suggestion = suggestSimilar(flag, candidateFlags);
2492
+ }
2493
+ const message = `error: unknown option '${flag}'${suggestion}`;
2494
+ this.error(message, { code: "commander.unknownOption" });
2495
+ }
2496
+ /**
2497
+ * Excess arguments, more than expected.
2498
+ *
2499
+ * @param {string[]} receivedArgs
2500
+ * @private
2501
+ */
2502
+ _excessArguments(receivedArgs) {
2503
+ if (this._allowExcessArguments) return;
2504
+ const expected = this.registeredArguments.length;
2505
+ const s = expected === 1 ? "" : "s";
2506
+ const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
2507
+ const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
2508
+ this.error(message, { code: "commander.excessArguments" });
2509
+ }
2510
+ /**
2511
+ * Unknown command.
2512
+ *
2513
+ * @private
2514
+ */
2515
+ unknownCommand() {
2516
+ const unknownName = this.args[0];
2517
+ let suggestion = "";
2518
+ if (this._showSuggestionAfterError) {
2519
+ const candidateNames = [];
2520
+ this.createHelp().visibleCommands(this).forEach((command) => {
2521
+ candidateNames.push(command.name());
2522
+ if (command.alias()) candidateNames.push(command.alias());
2523
+ });
2524
+ suggestion = suggestSimilar(unknownName, candidateNames);
2525
+ }
2526
+ const message = `error: unknown command '${unknownName}'${suggestion}`;
2527
+ this.error(message, { code: "commander.unknownCommand" });
2528
+ }
2529
+ /**
2530
+ * Get or set the program version.
2531
+ *
2532
+ * This method auto-registers the "-V, --version" option which will print the version number.
2533
+ *
2534
+ * You can optionally supply the flags and description to override the defaults.
2535
+ *
2536
+ * @param {string} [str]
2537
+ * @param {string} [flags]
2538
+ * @param {string} [description]
2539
+ * @return {(this | string | undefined)} `this` command for chaining, or version string if no arguments
2540
+ */
2541
+ version(str, flags, description) {
2542
+ if (str === void 0) return this._version;
2543
+ this._version = str;
2544
+ flags = flags || "-V, --version";
2545
+ description = description || "output the version number";
2546
+ const versionOption = this.createOption(flags, description);
2547
+ this._versionOptionName = versionOption.attributeName();
2548
+ this._registerOption(versionOption);
2549
+ this.on("option:" + versionOption.name(), () => {
2550
+ this._outputConfiguration.writeOut(`${str}
2551
+ `);
2552
+ this._exit(0, "commander.version", str);
2553
+ });
2554
+ return this;
2555
+ }
2556
+ /**
2557
+ * Set the description.
2558
+ *
2559
+ * @param {string} [str]
2560
+ * @param {Object} [argsDescription]
2561
+ * @return {(string|Command)}
2562
+ */
2563
+ description(str, argsDescription) {
2564
+ if (str === void 0 && argsDescription === void 0) return this._description;
2565
+ this._description = str;
2566
+ if (argsDescription) {
2567
+ this._argsDescription = argsDescription;
2568
+ }
2569
+ return this;
2570
+ }
2571
+ /**
2572
+ * Set the summary. Used when listed as subcommand of parent.
2573
+ *
2574
+ * @param {string} [str]
2575
+ * @return {(string|Command)}
2576
+ */
2577
+ summary(str) {
2578
+ if (str === void 0) return this._summary;
2579
+ this._summary = str;
2580
+ return this;
2581
+ }
2582
+ /**
2583
+ * Set an alias for the command.
2584
+ *
2585
+ * You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
2586
+ *
2587
+ * @param {string} [alias]
2588
+ * @return {(string|Command)}
2589
+ */
2590
+ alias(alias) {
2591
+ if (alias === void 0) return this._aliases[0];
2592
+ let command = this;
2593
+ if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
2594
+ command = this.commands[this.commands.length - 1];
2595
+ }
2596
+ if (alias === command._name) throw new Error("Command alias can't be the same as its name");
2597
+ const matchingCommand = this.parent?._findCommand(alias);
2598
+ if (matchingCommand) {
2599
+ const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
2600
+ throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
2601
+ }
2602
+ command._aliases.push(alias);
2603
+ return this;
2604
+ }
2605
+ /**
2606
+ * Set aliases for the command.
2607
+ *
2608
+ * Only the first alias is shown in the auto-generated help.
2609
+ *
2610
+ * @param {string[]} [aliases]
2611
+ * @return {(string[]|Command)}
2612
+ */
2613
+ aliases(aliases) {
2614
+ if (aliases === void 0) return this._aliases;
2615
+ aliases.forEach((alias) => this.alias(alias));
2616
+ return this;
2617
+ }
2618
+ /**
2619
+ * Set / get the command usage `str`.
2620
+ *
2621
+ * @param {string} [str]
2622
+ * @return {(string|Command)}
2623
+ */
2624
+ usage(str) {
2625
+ if (str === void 0) {
2626
+ if (this._usage) return this._usage;
2627
+ const args = this.registeredArguments.map((arg) => {
2628
+ return humanReadableArgName(arg);
2629
+ });
2630
+ return [].concat(
2631
+ this.options.length || this._helpOption !== null ? "[options]" : [],
2632
+ this.commands.length ? "[command]" : [],
2633
+ this.registeredArguments.length ? args : []
2634
+ ).join(" ");
2635
+ }
2636
+ this._usage = str;
2637
+ return this;
2638
+ }
2639
+ /**
2640
+ * Get or set the name of the command.
2641
+ *
2642
+ * @param {string} [str]
2643
+ * @return {(string|Command)}
2644
+ */
2645
+ name(str) {
2646
+ if (str === void 0) return this._name;
2647
+ this._name = str;
2648
+ return this;
2649
+ }
2650
+ /**
2651
+ * Set the name of the command from script filename, such as process.argv[1],
2652
+ * or require.main.filename, or __filename.
2653
+ *
2654
+ * (Used internally and public although not documented in README.)
2655
+ *
2656
+ * @example
2657
+ * program.nameFromFilename(require.main.filename);
2658
+ *
2659
+ * @param {string} filename
2660
+ * @return {Command}
2661
+ */
2662
+ nameFromFilename(filename) {
2663
+ this._name = path6.basename(filename, path6.extname(filename));
2664
+ return this;
2665
+ }
2666
+ /**
2667
+ * Get or set the directory for searching for executable subcommands of this command.
2668
+ *
2669
+ * @example
2670
+ * program.executableDir(__dirname);
2671
+ * // or
2672
+ * program.executableDir('subcommands');
2673
+ *
2674
+ * @param {string} [path]
2675
+ * @return {(string|null|Command)}
2676
+ */
2677
+ executableDir(path7) {
2678
+ if (path7 === void 0) return this._executableDir;
2679
+ this._executableDir = path7;
2680
+ return this;
2681
+ }
2682
+ /**
2683
+ * Return program help documentation.
2684
+ *
2685
+ * @param {{ error: boolean }} [contextOptions] - pass {error:true} to wrap for stderr instead of stdout
2686
+ * @return {string}
2687
+ */
2688
+ helpInformation(contextOptions) {
2689
+ const helper = this.createHelp();
2690
+ if (helper.helpWidth === void 0) {
2691
+ helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
2692
+ }
2693
+ return helper.formatHelp(this, helper);
2694
+ }
2695
+ /**
2696
+ * @private
2697
+ */
2698
+ _getHelpContext(contextOptions) {
2699
+ contextOptions = contextOptions || {};
2700
+ const context2 = { error: !!contextOptions.error };
2701
+ let write;
2702
+ if (context2.error) {
2703
+ write = (arg) => this._outputConfiguration.writeErr(arg);
2704
+ } else {
2705
+ write = (arg) => this._outputConfiguration.writeOut(arg);
2706
+ }
2707
+ context2.write = contextOptions.write || write;
2708
+ context2.command = this;
2709
+ return context2;
2710
+ }
2711
+ /**
2712
+ * Output help information for this command.
2713
+ *
2714
+ * Outputs built-in help, and custom text added using `.addHelpText()`.
2715
+ *
2716
+ * @param {{ error: boolean } | Function} [contextOptions] - pass {error:true} to write to stderr instead of stdout
2717
+ */
2718
+ outputHelp(contextOptions) {
2719
+ let deprecatedCallback;
2720
+ if (typeof contextOptions === "function") {
2721
+ deprecatedCallback = contextOptions;
2722
+ contextOptions = void 0;
2723
+ }
2724
+ const context2 = this._getHelpContext(contextOptions);
2725
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", context2));
2726
+ this.emit("beforeHelp", context2);
2727
+ let helpInformation = this.helpInformation(context2);
2728
+ if (deprecatedCallback) {
2729
+ helpInformation = deprecatedCallback(helpInformation);
2730
+ if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
2731
+ throw new Error("outputHelp callback must return a string or a Buffer");
2732
+ }
2733
+ }
2734
+ context2.write(helpInformation);
2735
+ if (this._getHelpOption()?.long) {
2736
+ this.emit(this._getHelpOption().long);
2737
+ }
2738
+ this.emit("afterHelp", context2);
2739
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", context2));
2740
+ }
2741
+ /**
2742
+ * You can pass in flags and a description to customise the built-in help option.
2743
+ * Pass in false to disable the built-in help option.
2744
+ *
2745
+ * @example
2746
+ * program.helpOption('-?, --help' 'show help'); // customise
2747
+ * program.helpOption(false); // disable
2748
+ *
2749
+ * @param {(string | boolean)} flags
2750
+ * @param {string} [description]
2751
+ * @return {Command} `this` command for chaining
2752
+ */
2753
+ helpOption(flags, description) {
2754
+ if (typeof flags === "boolean") {
2755
+ if (flags) {
2756
+ this._helpOption = this._helpOption ?? void 0;
2757
+ } else {
2758
+ this._helpOption = null;
2759
+ }
2760
+ return this;
2761
+ }
2762
+ flags = flags ?? "-h, --help";
2763
+ description = description ?? "display help for command";
2764
+ this._helpOption = this.createOption(flags, description);
2765
+ return this;
2766
+ }
2767
+ /**
2768
+ * Lazy create help option.
2769
+ * Returns null if has been disabled with .helpOption(false).
2770
+ *
2771
+ * @returns {(Option | null)} the help option
2772
+ * @package internal use only
2773
+ */
2774
+ _getHelpOption() {
2775
+ if (this._helpOption === void 0) {
2776
+ this.helpOption(void 0, void 0);
2777
+ }
2778
+ return this._helpOption;
2779
+ }
2780
+ /**
2781
+ * Supply your own option to use for the built-in help option.
2782
+ * This is an alternative to using helpOption() to customise the flags and description etc.
2783
+ *
2784
+ * @param {Option} option
2785
+ * @return {Command} `this` command for chaining
2786
+ */
2787
+ addHelpOption(option) {
2788
+ this._helpOption = option;
2789
+ return this;
2790
+ }
2791
+ /**
2792
+ * Output help information and exit.
2793
+ *
2794
+ * Outputs built-in help, and custom text added using `.addHelpText()`.
2795
+ *
2796
+ * @param {{ error: boolean }} [contextOptions] - pass {error:true} to write to stderr instead of stdout
2797
+ */
2798
+ help(contextOptions) {
2799
+ this.outputHelp(contextOptions);
2800
+ let exitCode = process2.exitCode || 0;
2801
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
2802
+ exitCode = 1;
2803
+ }
2804
+ this._exit(exitCode, "commander.help", "(outputHelp)");
2805
+ }
2806
+ /**
2807
+ * Add additional text to be displayed with the built-in help.
2808
+ *
2809
+ * Position is 'before' or 'after' to affect just this command,
2810
+ * and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
2811
+ *
2812
+ * @param {string} position - before or after built-in help
2813
+ * @param {(string | Function)} text - string to add, or a function returning a string
2814
+ * @return {Command} `this` command for chaining
2815
+ */
2816
+ addHelpText(position, text) {
2817
+ const allowedValues = ["beforeAll", "before", "after", "afterAll"];
2818
+ if (!allowedValues.includes(position)) {
2819
+ throw new Error(`Unexpected value for position to addHelpText.
2820
+ Expecting one of '${allowedValues.join("', '")}'`);
2821
+ }
2822
+ const helpEvent = `${position}Help`;
2823
+ this.on(helpEvent, (context2) => {
2824
+ let helpStr;
2825
+ if (typeof text === "function") {
2826
+ helpStr = text({ error: context2.error, command: context2.command });
2827
+ } else {
2828
+ helpStr = text;
2829
+ }
2830
+ if (helpStr) {
2831
+ context2.write(`${helpStr}
2832
+ `);
2833
+ }
2834
+ });
2835
+ return this;
2836
+ }
2837
+ /**
2838
+ * Output help information if help flags specified
2839
+ *
2840
+ * @param {Array} args - array of options to search for help flags
2841
+ * @private
2842
+ */
2843
+ _outputHelpIfRequested(args) {
2844
+ const helpOption = this._getHelpOption();
2845
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
2846
+ if (helpRequested) {
2847
+ this.outputHelp();
2848
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
2849
+ }
2850
+ }
2851
+ };
2852
+ function incrementNodeInspectorPort(args) {
2853
+ return args.map((arg) => {
2854
+ if (!arg.startsWith("--inspect")) {
2855
+ return arg;
2856
+ }
2857
+ let debugOption;
2858
+ let debugHost = "127.0.0.1";
2859
+ let debugPort = "9229";
2860
+ let match;
2861
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
2862
+ debugOption = match[1];
2863
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
2864
+ debugOption = match[1];
2865
+ if (/^\d+$/.test(match[3])) {
2866
+ debugPort = match[3];
2867
+ } else {
2868
+ debugHost = match[3];
2869
+ }
2870
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
2871
+ debugOption = match[1];
2872
+ debugHost = match[3];
2873
+ debugPort = match[4];
2874
+ }
2875
+ if (debugOption && debugPort !== "0") {
2876
+ return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
2877
+ }
2878
+ return arg;
2879
+ });
2880
+ }
2881
+ exports.Command = Command2;
2882
+ }
2883
+ });
2884
+
2885
+ // node_modules/commander/index.js
2886
+ var require_commander = __commonJS({
2887
+ "node_modules/commander/index.js"(exports) {
2888
+ var { Argument: Argument2 } = require_argument();
2889
+ var { Command: Command2 } = require_command();
2890
+ var { CommanderError: CommanderError2, InvalidArgumentError: InvalidArgumentError2 } = require_error();
2891
+ var { Help: Help2 } = require_help();
2892
+ var { Option: Option2 } = require_option();
2893
+ exports.program = new Command2();
2894
+ exports.createCommand = (name) => new Command2(name);
2895
+ exports.createOption = (flags, description) => new Option2(flags, description);
2896
+ exports.createArgument = (name, description) => new Argument2(name, description);
2897
+ exports.Command = Command2;
2898
+ exports.Option = Option2;
2899
+ exports.Argument = Argument2;
2900
+ exports.Help = Help2;
2901
+ exports.CommanderError = CommanderError2;
2902
+ exports.InvalidArgumentError = InvalidArgumentError2;
2903
+ exports.InvalidOptionArgumentError = InvalidArgumentError2;
2904
+ }
2905
+ });
2906
+
2907
+ // node_modules/commander/esm.mjs
2908
+ var import_index = __toESM(require_commander());
2909
+ var {
2910
+ program,
2911
+ createCommand,
2912
+ createArgument,
2913
+ createOption,
2914
+ CommanderError,
2915
+ InvalidArgumentError,
2916
+ InvalidOptionArgumentError,
2917
+ // deprecated old name
2918
+ Command,
2919
+ Argument,
2920
+ Option,
2921
+ Help
2922
+ } = import_index.default;
2923
+
2924
+ // package.json
2925
+ var package_default = {
2926
+ version: "5.0.0"};
2927
+ var ALWAYS_EXTERNAL = ["uWebSockets.js"];
42
2928
  function getUserExternals(cwd) {
2929
+ let pkgExternals = [];
43
2930
  try {
44
2931
  const pkgPath = path4__default.default.join(cwd, "package.json");
45
2932
  if (fs__default.default.existsSync(pkgPath)) {
46
2933
  const pkg = JSON.parse(fs__default.default.readFileSync(pkgPath, "utf8"));
47
2934
  const deps = Object.keys(pkg.dependencies || {});
48
2935
  const devDeps = Object.keys(pkg.devDependencies || {});
49
- return [...deps, ...devDeps];
2936
+ pkgExternals = [...deps, ...devDeps];
50
2937
  }
51
2938
  } catch (err) {
2939
+ const message = err instanceof Error ? err.message : String(err);
52
2940
  console.warn(
53
- "[Axiomify CLI] Failed to read package.json, defaulting to empty externals."
2941
+ `[Axiomify CLI] Failed to read package.json (${message}); defaulting to empty externals.`
54
2942
  );
55
2943
  }
56
- return [];
2944
+ return Array.from(/* @__PURE__ */ new Set([...ALWAYS_EXTERNAL, ...pkgExternals]));
57
2945
  }
58
2946
 
59
2947
  // src/commands/build.ts
@@ -83,25 +2971,46 @@ async function devServer(entry) {
83
2971
  const entryPath = path4__default.default.resolve(process.cwd(), entry);
84
2972
  const outPath = path4__default.default.resolve(process.cwd(), ".axiomify/dev.js");
85
2973
  let child = null;
2974
+ let firstBuild = true;
2975
+ const startChild = () => {
2976
+ child = child_process.spawn("node", [outPath], { stdio: "inherit" });
2977
+ child.on("error", (err) => {
2978
+ console.error("\u274C Failed to start process:", err);
2979
+ });
2980
+ };
2981
+ const GRACEFUL_KILL_MS = 3e3;
86
2982
  const restartServer = () => {
87
- if (child) {
2983
+ if (child && child.exitCode === null && child.signalCode === null) {
88
2984
  child.removeAllListeners("exit");
89
- child.once("exit", () => {
90
- child = child_process.spawn("node", [outPath], { stdio: "inherit" });
2985
+ const oldChild = child;
2986
+ oldChild.once("exit", () => {
2987
+ startChild();
91
2988
  });
92
- child.kill("SIGKILL");
2989
+ oldChild.kill("SIGTERM");
2990
+ const forceKill = setTimeout(() => {
2991
+ if (oldChild.exitCode === null && oldChild.signalCode === null) {
2992
+ oldChild.kill("SIGKILL");
2993
+ }
2994
+ }, GRACEFUL_KILL_MS);
2995
+ forceKill.unref();
93
2996
  } else {
94
- child = child_process.spawn("node", [outPath], { stdio: "inherit" });
2997
+ startChild();
95
2998
  }
96
2999
  };
97
3000
  const watchPlugin = {
98
3001
  name: "watch-plugin",
99
3002
  setup(build3) {
100
3003
  build3.onEnd((result) => {
101
- if (result.errors.length > 0) {
102
- console.error("\u274C Build failed. Waiting for changes...");
3004
+ if (result.errors.length === 0) {
3005
+ if (firstBuild) {
3006
+ firstBuild = false;
3007
+ restartServer();
3008
+ } else {
3009
+ console.log("\u{1F504} Changes detected, restarting...");
3010
+ restartServer();
3011
+ }
103
3012
  } else {
104
- restartServer();
3013
+ console.error("\u274C Build failed. Fix errors to trigger a restart.");
105
3014
  }
106
3015
  });
107
3016
  }
@@ -111,6 +3020,7 @@ async function devServer(entry) {
111
3020
  entryPoints: [entryPath],
112
3021
  bundle: true,
113
3022
  platform: "node",
3023
+ format: "cjs",
114
3024
  outfile: outPath,
115
3025
  external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])],
116
3026
  plugins: [watchPlugin]
@@ -125,7 +3035,7 @@ async function devServer(entry) {
125
3035
  child.removeAllListeners("exit");
126
3036
  child.kill("SIGTERM");
127
3037
  setTimeout(() => {
128
- if (child && !child.killed) child.kill("SIGKILL");
3038
+ if (child && child.exitCode === null) child.kill("SIGKILL");
129
3039
  }, 2e3).unref();
130
3040
  }
131
3041
  try {
@@ -139,43 +3049,207 @@ async function devServer(entry) {
139
3049
  console.log(`\u{1F440} Axiomify Dev Engine watching for changes...`);
140
3050
  await ctx.watch();
141
3051
  }
3052
+ var DEV_COMMAND_BY_PM = {
3053
+ npm: "npm run dev",
3054
+ pnpm: "pnpm dev",
3055
+ yarn: "yarn dev"
3056
+ };
142
3057
  async function initProject(targetDir, options = {}) {
143
- const dir = path4__default.default.resolve(process.cwd(), targetDir);
144
- await fs2__default.default.mkdir(path4__default.default.join(dir, "src"), { recursive: true });
145
- const targets = [
146
- path4__default.default.join(dir, "package.json"),
147
- path4__default.default.join(dir, "tsconfig.json"),
148
- path4__default.default.join(dir, "src", "index.ts")
149
- ];
150
- const collisions = targets.filter((p) => fs.existsSync(p));
151
- if (collisions.length > 0 && !options.force) {
3058
+ console.log(pc__default.default.cyan(pc__default.default.bold("\n\u{1F680} Axiomify Project Initializer\n")));
3059
+ const questions = [];
3060
+ if (!targetDir) {
3061
+ questions.push({
3062
+ type: "input",
3063
+ name: "projectName",
3064
+ message: "What is your project name?",
3065
+ initial: "my-axiomify-app"
3066
+ });
3067
+ }
3068
+ questions.push(
3069
+ {
3070
+ type: "select",
3071
+ name: "adapter",
3072
+ message: "Which HTTP adapter do you want to use?",
3073
+ choices: [
3074
+ "Native (uWS \u2014 Fastest, 50k+ req/s)",
3075
+ "Fastify (High-throughput, recommended)",
3076
+ "Express (Max ecosystem compatibility)",
3077
+ "Hapi (Enterprise, plugin-first)",
3078
+ "Node HTTP (Zero dependency)"
3079
+ ],
3080
+ initial: 0
3081
+ // Native is the recommended default
3082
+ },
3083
+ {
3084
+ type: "input",
3085
+ name: "description",
3086
+ message: "Project description",
3087
+ initial: "A production-ready Axiomify service"
3088
+ },
3089
+ {
3090
+ type: "confirm",
3091
+ name: "useEslint",
3092
+ message: "Add ESLint + Prettier + EditorConfig?",
3093
+ initial: true
3094
+ },
3095
+ {
3096
+ type: "select",
3097
+ name: "packageManager",
3098
+ message: "Preferred package manager?",
3099
+ choices: ["npm", "pnpm", "yarn"],
3100
+ initial: 0
3101
+ },
3102
+ {
3103
+ type: "confirm",
3104
+ name: "useGit",
3105
+ message: "Initialize a git repository?",
3106
+ initial: true
3107
+ },
3108
+ {
3109
+ type: "confirm",
3110
+ name: "installDeps",
3111
+ message: "Install dependencies automatically?",
3112
+ initial: true
3113
+ }
3114
+ );
3115
+ const answers = await enquirer.prompt(questions);
3116
+ const projectName = targetDir || answers.projectName;
3117
+ if (!projectName || projectName.trim().length === 0) {
152
3118
  console.error(
153
- "\u274C Refusing to overwrite existing files:\n" + collisions.map((p) => ` - ${p}`).join("\n") + "\n\nRe-run with '--force' if you really want to replace them."
3119
+ pc__default.default.red(
3120
+ "\u274C A project name is required. Aborting to avoid writing into the current directory."
3121
+ )
154
3122
  );
155
3123
  process.exit(1);
156
3124
  }
3125
+ if (
3126
+ // eslint-disable-next-line no-control-regex
3127
+ /[<>:"|?*\u0000-\u001f]/.test(projectName) || projectName.includes("..")
3128
+ ) {
3129
+ console.error(
3130
+ pc__default.default.red(
3131
+ `\u274C Invalid project name: "${projectName}". Names cannot contain path traversal or control characters.`
3132
+ )
3133
+ );
3134
+ process.exit(1);
3135
+ }
3136
+ const dir = path4__default.default.resolve(process.cwd(), projectName);
3137
+ if (fs.existsSync(dir) && !options.force && targetDir) {
3138
+ const targets = [
3139
+ path4__default.default.join(dir, "package.json"),
3140
+ path4__default.default.join(dir, "tsconfig.json"),
3141
+ path4__default.default.join(dir, "src", "index.ts")
3142
+ ];
3143
+ const collisions = targets.filter((p) => fs.existsSync(p));
3144
+ if (collisions.length > 0) {
3145
+ console.error(
3146
+ pc__default.default.red("\u274C Refusing to overwrite existing files:\n") + collisions.map((p) => ` - ${p}`).join("\n") + pc__default.default.yellow(
3147
+ "\n\nRe-run with '--force' if you really want to replace them."
3148
+ )
3149
+ );
3150
+ process.exit(1);
3151
+ }
3152
+ }
3153
+ await fs2__default.default.mkdir(path4__default.default.join(dir, "src"), { recursive: true });
3154
+ const AXIOMIFY_VERSION = `^${package_default.version}`;
3155
+ let adapterPackage = "@axiomify/native";
3156
+ let adapterImport = "import { NativeAdapter } from '@axiomify/native';";
3157
+ let adapterInit = "const server = new NativeAdapter(app, { port: 3000 });\n server.listen(() => console.log(' Axiomify Native on :3000'));";
3158
+ if (answers.adapter.includes("Fastify")) {
3159
+ adapterPackage = "@axiomify/fastify";
3160
+ adapterImport = "import { FastifyAdapter } from '@axiomify/fastify';";
3161
+ adapterInit = "const server = new FastifyAdapter(app);\n await server.listen(3000);\n console.log(' Axiomify Fastify on :3000');";
3162
+ } else if (answers.adapter.includes("Express")) {
3163
+ adapterPackage = "@axiomify/express";
3164
+ adapterImport = "import { ExpressAdapter } from '@axiomify/express';";
3165
+ adapterInit = "const server = new ExpressAdapter(app);\n server.listen(3000, () => console.log(' Axiomify Express on :3000'));";
3166
+ } else if (answers.adapter.includes("Hapi")) {
3167
+ adapterPackage = "@axiomify/hapi";
3168
+ adapterImport = "import { HapiAdapter } from '@axiomify/hapi';";
3169
+ adapterInit = "const server = new HapiAdapter(app);\n await server.listen(3000);\n console.log(' Axiomify Hapi on :3000');";
3170
+ } else if (answers.adapter.includes("HTTP")) {
3171
+ adapterPackage = "@axiomify/http";
3172
+ adapterImport = "import { HttpAdapter } from '@axiomify/http';";
3173
+ adapterInit = "const server = new HttpAdapter(app);\n server.listen(3000, () => console.log(' Axiomify HTTP on :3000'));";
3174
+ }
157
3175
  const pkgJson = {
158
- name: "axiomify-app",
3176
+ name: projectName,
159
3177
  version: "1.0.0",
160
3178
  private: true,
3179
+ description: answers.description,
161
3180
  scripts: {
162
3181
  dev: "axiomify dev src/index.ts",
163
3182
  build: "axiomify build src/index.ts",
164
3183
  start: "node dist/index.js",
165
- routes: "axiomify routes src/index.ts"
3184
+ routes: "axiomify routes src/index.ts",
3185
+ typecheck: "tsc --noEmit"
166
3186
  },
167
3187
  dependencies: {
168
- "@axiomify/core": "latest",
169
- "@axiomify/express": "latest"
3188
+ "@axiomify/core": AXIOMIFY_VERSION,
3189
+ [adapterPackage]: AXIOMIFY_VERSION,
3190
+ // Inject selected adapter
3191
+ "@axiomify/helmet": AXIOMIFY_VERSION,
3192
+ "@axiomify/cors": AXIOMIFY_VERSION,
3193
+ "@axiomify/logger": AXIOMIFY_VERSION,
3194
+ "@axiomify/security": AXIOMIFY_VERSION,
3195
+ "@axiomify/rate-limit": AXIOMIFY_VERSION,
3196
+ "@axiomify/fingerprint": AXIOMIFY_VERSION
170
3197
  },
171
3198
  devDependencies: {
172
- // Keep scaffolded projects on the same TS major as the workspace
173
- // (^6) so types like `satisfies`, `const` type parameters, etc., don't
174
- // drift between the framework and user code.
175
- typescript: "^6.0.0",
176
- "@types/node": "^22.0.0"
3199
+ typescript: "^5.4.0",
3200
+ "@types/node": "^22.0.0",
3201
+ "@axiomify/cli": AXIOMIFY_VERSION
177
3202
  }
178
3203
  };
3204
+ if (answers.useEslint) {
3205
+ pkgJson.devDependencies = {
3206
+ ...pkgJson.devDependencies,
3207
+ eslint: "^8.57.0",
3208
+ prettier: "^3.0.0",
3209
+ "eslint-config-prettier": "^9.0.0",
3210
+ "eslint-plugin-prettier": "^5.0.0",
3211
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
3212
+ "@typescript-eslint/parser": "^7.0.0"
3213
+ };
3214
+ pkgJson.scripts.lint = "eslint . --ext .ts";
3215
+ pkgJson.scripts["lint:fix"] = "eslint . --ext .ts --fix";
3216
+ pkgJson.scripts.format = "prettier --write .";
3217
+ const eslintConfig = `module.exports = {
3218
+ root: true,
3219
+ parser: '@typescript-eslint/parser',
3220
+ plugins: ['@typescript-eslint', 'prettier'],
3221
+ extends: [
3222
+ 'eslint:recommended',
3223
+ 'plugin:@typescript-eslint/recommended',
3224
+ 'plugin:prettier/recommended',
3225
+ ],
3226
+ parserOptions: {
3227
+ ecmaVersion: 2022,
3228
+ sourceType: 'module',
3229
+ },
3230
+ env: {
3231
+ node: true,
3232
+ es2022: true,
3233
+ },
3234
+ };`;
3235
+ const prettierConfig = `{
3236
+ "semi": true,
3237
+ "trailingComma": "all",
3238
+ "singleQuote": true,
3239
+ "printWidth": 100,
3240
+ "tabWidth": 2
3241
+ }`;
3242
+ await fs2__default.default.writeFile(path4__default.default.join(dir, ".eslintrc.cjs"), eslintConfig);
3243
+ await fs2__default.default.writeFile(path4__default.default.join(dir, ".prettierrc"), prettierConfig);
3244
+ await fs2__default.default.writeFile(
3245
+ path4__default.default.join(dir, ".prettierignore"),
3246
+ "dist\nnode_modules\ncoverage\n"
3247
+ );
3248
+ await fs2__default.default.writeFile(
3249
+ path4__default.default.join(dir, ".editorconfig"),
3250
+ "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_style = space\nindent_size = 2\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
3251
+ );
3252
+ }
179
3253
  const tsConfig = {
180
3254
  compilerOptions: {
181
3255
  target: "ES2022",
@@ -185,30 +3259,54 @@ async function initProject(targetDir, options = {}) {
185
3259
  esModuleInterop: true,
186
3260
  skipLibCheck: true,
187
3261
  forceConsistentCasingInFileNames: true,
188
- outDir: "./dist"
3262
+ outDir: "./dist",
3263
+ rootDir: "./src",
3264
+ types: ["node"]
189
3265
  },
190
3266
  include: ["src/**/*"]
191
3267
  };
192
- const indexTs = `import { Axiomify, z } from '@axiomify/core';
193
- import { ExpressAdapter } from '@axiomify/express';
3268
+ const indexTs = `import { Axiomify } from '@axiomify/core';
3269
+ ${adapterImport}
3270
+ import { useHelmet } from '@axiomify/helmet';
3271
+ import { useCors } from '@axiomify/cors';
3272
+ import { useLogger } from '@axiomify/logger';
3273
+ import { useSecurity } from '@axiomify/security';
3274
+ import { useRateLimit, MemoryStore } from '@axiomify/rate-limit';
3275
+ import { useFingerprint } from '@axiomify/fingerprint';
194
3276
 
195
- // Exporting the app instance is required for the 'axiomify routes' CLI command
196
- export const app = new Axiomify();
3277
+ export const app = new Axiomify();
197
3278
 
198
- app.route({
199
- method: 'GET',
200
- path: '/health',
201
- handler: async (req, res) => {
202
- res.status(200).send({ status: 'healthy', timestamp: Date.now() }, 'System Operational');
203
- }
204
- });
3279
+ useHelmet(app);
3280
+ useCors(app, { credentials: false });
3281
+ useSecurity(app);
205
3282
 
206
- // Prevent listening during CLI inspection
207
- if (require.main === module) {
208
- const adapter = new ExpressAdapter(app);
209
- adapter.listen(3000, () => console.log('\u{1F680} Axiomify engine online on port 3000'));
210
- }
211
- `;
3283
+ // PRODUCTION NOTE
3284
+ // MemoryStore is per-process. For production, swap this for a RedisStore.
3285
+ useRateLimit(app, { max: 100, windowMs: 60_000, store: new MemoryStore() });
3286
+ useFingerprint(app);
3287
+ useLogger(app);
3288
+
3289
+ app.route({
3290
+ method: 'GET',
3291
+ path: '/health',
3292
+ handler: async (_req, res) => {
3293
+ res.status(200).send({ status: 'healthy' }, 'System Operational');
3294
+ },
3295
+ });
3296
+
3297
+ if (require.main === module) {
3298
+ ${adapterInit}
3299
+ }
3300
+ `;
3301
+ const gitignore = [
3302
+ "node_modules",
3303
+ "dist",
3304
+ ".axiomify",
3305
+ ".env",
3306
+ ".env.local",
3307
+ "coverage",
3308
+ "*.log"
3309
+ ].join("\n") + "\n";
212
3310
  await fs2__default.default.writeFile(
213
3311
  path4__default.default.join(dir, "package.json"),
214
3312
  JSON.stringify(pkgJson, null, 2)
@@ -218,8 +3316,42 @@ if (require.main === module) {
218
3316
  JSON.stringify(tsConfig, null, 2)
219
3317
  );
220
3318
  await fs2__default.default.writeFile(path4__default.default.join(dir, "src", "index.ts"), indexTs);
221
- console.log(`\u2705 Axiomify project initialized in ${dir}`);
222
- console.log(`\u{1F4E6} Run 'npm install' to install dependencies.`);
3319
+ await fs2__default.default.writeFile(path4__default.default.join(dir, ".gitignore"), gitignore);
3320
+ console.log(pc__default.default.green(`
3321
+ \u2705 Axiomify project initialized in ${pc__default.default.bold(dir)}`));
3322
+ if (answers.useGit && !fs.existsSync(path4__default.default.join(dir, ".git"))) {
3323
+ try {
3324
+ await execa.execa("git", ["init"], { cwd: dir });
3325
+ console.log(pc__default.default.green("\u2705 Git repository initialized"));
3326
+ } catch {
3327
+ console.log(pc__default.default.yellow("\u26A0\uFE0F Could not initialize git repository."));
3328
+ }
3329
+ }
3330
+ if (answers.installDeps) {
3331
+ const pkgManager = answers.packageManager || "npm";
3332
+ const installArgs = ["install"];
3333
+ console.log(pc__default.default.cyan(`\u{1F4E6} Installing dependencies using ${pkgManager}...`));
3334
+ try {
3335
+ await execa.execa(pkgManager, installArgs, { cwd: dir, stdio: "inherit" });
3336
+ console.log(pc__default.default.green("\u2705 Dependencies installed successfully!"));
3337
+ } catch {
3338
+ console.error(
3339
+ pc__default.default.red("\u274C Failed to install dependencies. Please install manually.")
3340
+ );
3341
+ }
3342
+ } else {
3343
+ console.log(
3344
+ pc__default.default.yellow(
3345
+ `
3346
+ \u{1F4E6} Run "cd ${projectName} && ${answers.packageManager || "npm"} install" to get started.`
3347
+ )
3348
+ );
3349
+ }
3350
+ const devCommand = DEV_COMMAND_BY_PM[answers.packageManager || "npm"];
3351
+ console.log(
3352
+ pc__default.default.cyan(`
3353
+ \u{1F525} Run "${devCommand}" to start your development server!`)
3354
+ );
223
3355
  }
224
3356
  async function inspectRoutes(entry) {
225
3357
  const entryPath = path4__default.default.resolve(process.cwd(), entry);
@@ -238,6 +3370,12 @@ async function inspectRoutes(entry) {
238
3370
  delete __require.cache[__require.resolve(tempPath)];
239
3371
  } catch (e) {
240
3372
  }
3373
+ const inspectionTimeout = setTimeout(() => {
3374
+ console.warn(
3375
+ "\n\u26A0\uFE0F Route inspection is taking longer than expected.\n Your entry file may be starting a server unconditionally.\n Wrap the listen() call in `if (require.main === module) { ... }`\n so it only runs when the file is executed directly.\n"
3376
+ );
3377
+ }, 5e3);
3378
+ inspectionTimeout.unref();
241
3379
  const mod = __require(tempPath);
242
3380
  const app = mod.app || mod.default;
243
3381
  if (!app || typeof app.registeredRoutes === "undefined") {
@@ -275,10 +3413,12 @@ async function inspectRoutes(entry) {
275
3413
  }
276
3414
 
277
3415
  // src/index.ts
278
- var program = new commander.Command();
279
- program.name("axiomify").description("The official CLI for the Axiomify framework").version("1.0.0");
280
- program.command("init").description("Bootstrap a new Axiomify project").argument("[directory]", "Target directory", ".").option("-f, --force", "Overwrite existing project files", false).action((directory, options) => initProject(directory, options));
281
- program.command("dev").description("Start the development server with hot-reload").argument("[entry]", "Entry file", "src/index.ts").action(devServer);
282
- program.command("build").description("Compile the application for production").argument("[entry]", "Entry file", "src/index.ts").action(buildProject);
283
- program.command("routes").description("Inspect and list all registered routes in the application").argument("[entry]", "Entry file", "src/index.ts").action(inspectRoutes);
284
- program.parse(process.argv);
3416
+ var program2 = new Command();
3417
+ program2.name("axiomify").description("The official CLI for the Axiomify framework").version(package_default.version);
3418
+ program2.command("init").description("Bootstrap a new Axiomify project").argument("[directory]", "Target directory").option("-f, --force", "Overwrite existing project files", false).action(
3419
+ (directory, options) => initProject(directory, options)
3420
+ );
3421
+ program2.command("dev").description("Start the development server with hot-reload").argument("[entry]", "Entry file", "src/index.ts").action(devServer);
3422
+ program2.command("build").description("Compile the application for production").argument("[entry]", "Entry file", "src/index.ts").action(buildProject);
3423
+ program2.command("routes").description("Inspect and list all registered routes in the application").argument("[entry]", "Entry file", "src/index.ts").action(inspectRoutes);
3424
+ program2.parse(process.argv);