@flowscripter/dynamic-cli-framework 1.2.2 → 1.3.1

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 (166) hide show
  1. package/README/core-service-providers.md +2 -2
  2. package/README/development.md +3 -6
  3. package/README/implementation-details.md +17 -17
  4. package/README/key-concepts.md +17 -17
  5. package/README.md +4 -4
  6. package/bun.lock +0 -2
  7. package/index.ts +22 -30
  8. package/package.json +19 -19
  9. package/src/api/argument/Argument.ts +1 -1
  10. package/src/api/argument/ArgumentValueTypes.ts +3 -10
  11. package/src/api/argument/ComplexOption.ts +5 -9
  12. package/src/api/command/GlobalCommand.ts +1 -4
  13. package/src/api/service/core/ArgumentPrompterService.ts +1 -3
  14. package/src/api/service/core/AsciiBannerGeneratorService.ts +1 -4
  15. package/src/api/service/core/CompletionService.ts +2 -6
  16. package/src/api/service/core/ImagePrinterService.ts +1 -2
  17. package/src/api/service/core/KeyValueService.ts +1 -2
  18. package/src/api/service/core/PrettyPrinterService.ts +1 -4
  19. package/src/api/service/core/PrinterService.ts +8 -9
  20. package/src/api/service/core/PrompterService.ts +4 -11
  21. package/src/api/service/core/ShutdownService.ts +1 -2
  22. package/src/api/service/core/SyntaxHighlighterService.ts +1 -5
  23. package/src/api/service/core/Table.ts +7 -25
  24. package/src/api/service/core/TreePrinterService.ts +1 -2
  25. package/src/cli/BaseCLI.ts +17 -47
  26. package/src/cli/DefaultRuntimeCLI.ts +1 -4
  27. package/src/command/CompletionCommand.ts +19 -45
  28. package/src/command/MultiCommandCliHelpCommand.ts +45 -92
  29. package/src/command/SingleCommandCliHelpCommand.ts +17 -28
  30. package/src/command/UsageCommand.ts +6 -12
  31. package/src/command/VersionCommand.ts +2 -6
  32. package/src/launcher.ts +4 -2
  33. package/src/runtime/DefaultContext.ts +2 -5
  34. package/src/runtime/argument/ArgumentTypeGuards.ts +1 -3
  35. package/src/runtime/command/CommandTypeGuards.ts +5 -14
  36. package/src/runtime/command/CommandValidator.ts +56 -118
  37. package/src/runtime/parser.ts +13 -17
  38. package/src/runtime/registry/CommandRegistry.ts +2 -7
  39. package/src/runtime/registry/DefaultCommandRegistry.ts +32 -84
  40. package/src/runtime/registry/DefaultServiceProviderRegistry.ts +3 -9
  41. package/src/runtime/runner.ts +103 -142
  42. package/src/runtime/scanner.ts +28 -46
  43. package/src/runtime/values/ValuePopulationResult.ts +1 -2
  44. package/src/runtime/values/argumentValueMerge.ts +16 -28
  45. package/src/runtime/values/argumentValueValidation.ts +21 -67
  46. package/src/runtime/values/globalCommandValuePopulation.ts +9 -18
  47. package/src/runtime/values/subCommandValuePopulation.ts +42 -65
  48. package/src/service/argumentPrompter/ArgumentPrompterServiceProvider.ts +3 -10
  49. package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +22 -59
  50. package/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.ts +5 -14
  51. package/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.ts +59 -77
  52. package/src/service/banner/BannerServiceProvider.ts +13 -35
  53. package/src/service/banner/command/NoBannerCommand.ts +2 -8
  54. package/src/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.ts +5 -10
  55. package/src/service/completion/CompletionServiceProvider.ts +20 -48
  56. package/src/service/completion/DefaultCompletionService.ts +17 -56
  57. package/src/service/completion/shell/ShellHandler.ts +1 -3
  58. package/src/service/completion/shell/fish.ts +1 -1
  59. package/src/service/completion/shell/powershell.ts +2 -12
  60. package/src/service/completion/shell/zsh.ts +1 -1
  61. package/src/service/configuration/ConfigurationServiceProvider.ts +40 -133
  62. package/src/service/configuration/DefaultKeyValueService.ts +6 -20
  63. package/src/service/configuration/DefaultSecretService.ts +10 -14
  64. package/src/service/configuration/command/ConfigCommand.ts +1 -4
  65. package/src/service/configuration/command/DumpConfigCommand.ts +9 -21
  66. package/src/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.ts +5 -14
  67. package/src/service/dataDumpGenerator/DefaultDataDumpGeneratorService.ts +5 -12
  68. package/src/service/imagePrinter/DefaultImagePrinterService.ts +1 -5
  69. package/src/service/imagePrinter/ImagePrinterServiceProvider.ts +1 -4
  70. package/src/service/prettyPrinter/DefaultPrettyPrinterService.ts +4 -12
  71. package/src/service/prettyPrinter/PrettyPrinterServiceProvider.ts +3 -10
  72. package/src/service/printer/DefaultPrinterService.ts +20 -83
  73. package/src/service/printer/PrinterServiceProvider.ts +3 -11
  74. package/src/service/printer/command/DarkModeCommand.ts +3 -10
  75. package/src/service/printer/command/LogLevelCommand.ts +7 -26
  76. package/src/service/printer/command/NoColorCommand.ts +3 -10
  77. package/src/service/printer/command/NoHyperlinksCommand.ts +3 -10
  78. package/src/service/printer/terminal/Progress.ts +99 -90
  79. package/src/service/printer/terminal/Spinner.ts +7 -26
  80. package/src/service/prompter/DefaultPrompterService.ts +2 -6
  81. package/src/service/prompter/PrompterServiceProvider.ts +3 -11
  82. package/src/service/prompter/command/NoPromptCommand.ts +3 -10
  83. package/src/service/prompter/prompt/PromptContext.ts +5 -18
  84. package/src/service/prompter/prompt/promptMultiSelect.ts +6 -21
  85. package/src/service/prompter/prompt/promptOpenUrl.ts +7 -22
  86. package/src/service/prompter/prompt/promptSingleSelect.ts +6 -23
  87. package/src/service/prompter/prompt/promptText.ts +10 -27
  88. package/src/service/prompter/prompt/promptToggle.ts +8 -8
  89. package/src/service/shutdown/ShutdownServiceProvider.ts +3 -10
  90. package/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.ts +13 -26
  91. package/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.ts +8 -21
  92. package/src/service/tableGenerator/DefaultTableGeneratorService.ts +44 -68
  93. package/src/service/tableGenerator/TableGeneratorServiceProvider.ts +7 -16
  94. package/src/service/treePrinter/DefaultTreePrinterService.ts +2 -7
  95. package/src/service/treePrinter/TreePrinterServiceProvider.ts +4 -12
  96. package/src/terminal/ImageRenderer.ts +35 -54
  97. package/src/terminal/PngDecoder.ts +10 -19
  98. package/src/terminal/TtyStyler.ts +11 -9
  99. package/src/terminal/TtyTerminal.ts +2 -10
  100. package/src/terminal/supportsHyperlinks.ts +4 -10
  101. package/src/util/configHelper.ts +3 -10
  102. package/src/util/envVarHelper.ts +50 -88
  103. package/src/util/helpHelper.ts +123 -193
  104. package/src/util/logger.ts +12 -42
  105. package/src/util/runnerHelper.ts +20 -61
  106. package/tests/cli/BaseCLI.test.ts +23 -80
  107. package/tests/command/CompletionCommand.test.ts +1 -6
  108. package/tests/command/MultiCommandCliHelpCommand.test.ts +51 -205
  109. package/tests/command/SingleCommandCliHelpCommand.test.ts +21 -103
  110. package/tests/command/UsageCommand.test.ts +4 -10
  111. package/tests/fixtures/Command.ts +87 -68
  112. package/tests/fixtures/CommandRegistry.ts +1 -3
  113. package/tests/fixtures/Context.ts +3 -11
  114. package/tests/fixtures/ServiceProviderRegistry.ts +1 -1
  115. package/tests/fixtures/prettierPluginFoo.ts +1 -1
  116. package/tests/fixtures/util.ts +2 -8
  117. package/tests/runtime/argument/ArgumentTypeGuards.test.ts +1 -3
  118. package/tests/runtime/command/CommandValidator.test.ts +881 -604
  119. package/tests/runtime/parser.test.ts +222 -246
  120. package/tests/runtime/registry/DefaultCommandRegistry.test.ts +15 -37
  121. package/tests/runtime/registry/DefaultServiceProviderRegistry.test.ts +2 -8
  122. package/tests/runtime/runner.test.ts +231 -281
  123. package/tests/runtime/scanner.test.ts +277 -475
  124. package/tests/runtime/values/argumentValueMerge.test.ts +133 -81
  125. package/tests/runtime/values/argumentValueValidation.test.ts +444 -588
  126. package/tests/runtime/values/globalCommandValuePopulation.test.ts +71 -253
  127. package/tests/runtime/values/subCommandValuePopulation.test.ts +1342 -1570
  128. package/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.ts +3 -12
  129. package/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.ts +36 -45
  130. package/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.ts +2 -8
  131. package/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.ts +40 -62
  132. package/tests/service/banner/BannerServiceProvider.test.ts +5 -18
  133. package/tests/service/banner/command/NoBannerCommand.test.ts +1 -4
  134. package/tests/service/completion/CompletionServiceProvider.test.ts +145 -214
  135. package/tests/service/completion/DefaultCompletionService.test.ts +17 -79
  136. package/tests/service/completion/shell/fish.test.ts +1 -3
  137. package/tests/service/configuration/ConfigurationServiceProvider.test.ts +26 -75
  138. package/tests/service/configuration/DefaultKeyValueService.test.ts +9 -21
  139. package/tests/service/configuration/DefaultSecretService.test.ts +7 -15
  140. package/tests/service/configuration/command/DumpConfigCommand.test.ts +4 -13
  141. package/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.ts +6 -12
  142. package/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.ts +1 -10
  143. package/tests/service/imagePrinter/DefaultImagePrinterService.test.ts +5 -70
  144. package/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.ts +4 -11
  145. package/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.ts +2 -6
  146. package/tests/service/printer/DefaultPrinterService.test.ts +57 -255
  147. package/tests/service/printer/PrinterServiceProvider.test.ts +2 -8
  148. package/tests/service/printer/command/DarkModeCommand.test.ts +4 -12
  149. package/tests/service/printer/command/LogLevelCommand.test.ts +4 -17
  150. package/tests/service/printer/command/NoColorCommand.test.ts +4 -12
  151. package/tests/service/printer/command/NoHyperlinksCommand.test.ts +7 -21
  152. package/tests/service/printer/terminal/Progress.test.ts +1 -3
  153. package/tests/service/printer/terminal/Spinner.test.ts +2 -8
  154. package/tests/service/prompter/DefaultPrompterService.test.ts +52 -69
  155. package/tests/service/prompter/PrompterServiceProvider.test.ts +2 -8
  156. package/tests/service/shutdown/ShutdownServiceProvider.test.ts +1 -3
  157. package/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.ts +13 -99
  158. package/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.ts +2 -7
  159. package/tests/service/tableGenerator/DefaultTableGeneratorService.test.ts +12 -33
  160. package/tests/service/tableGenerator/TableGeneratorServiceProvider.test.ts +2 -2
  161. package/tests/service/treePrinter/DefaultTreePrinterService.test.ts +4 -6
  162. package/tests/service/treePrinter/TreePrinterServiceProvider.test.ts +4 -8
  163. package/tests/terminal/ImageRenderer.test.ts +2 -11
  164. package/tests/terminal/PngDecoder.test.ts +2 -6
  165. package/tests/util/configHelper.test.ts +55 -137
  166. package/tests/util/envVarHelper.test.ts +46 -110
@@ -1,7 +1,6 @@
1
1
  import type { ArgumentSingleValueType } from "../../argument/ArgumentValueTypes.ts";
2
2
 
3
- export const PROMPTER_SERVICE_ID =
4
- "@flowscripter/dynamic-cli-framework/prompter-service";
3
+ export const PROMPTER_SERVICE_ID = "@flowscripter/dynamic-cli-framework/prompter-service";
5
4
 
6
5
  export enum PromptType {
7
6
  SINGLE_SELECT = 0,
@@ -17,9 +16,7 @@ export interface PromptOption {
17
16
  readonly returnedValue: ArgumentSingleValueType;
18
17
  readonly min?: number;
19
18
  readonly max?: number;
20
- readonly validate?: (
21
- value: ArgumentSingleValueType,
22
- ) => string | undefined;
19
+ readonly validate?: (value: ArgumentSingleValueType) => string | undefined;
23
20
  }
24
21
 
25
22
  export interface Prompt {
@@ -33,9 +30,7 @@ export interface Prompt {
33
30
 
34
31
  export interface PromptResult {
35
32
  readonly name: string;
36
- readonly value:
37
- | ArgumentSingleValueType
38
- | ReadonlyArray<ArgumentSingleValueType>;
33
+ readonly value: ArgumentSingleValueType | ReadonlyArray<ArgumentSingleValueType>;
39
34
  }
40
35
 
41
36
  export default interface PrompterService {
@@ -43,7 +38,5 @@ export default interface PrompterService {
43
38
 
44
39
  prompt(prompt: Prompt): Promise<PromptResult>;
45
40
 
46
- promptAll(
47
- prompts: ReadonlyArray<Prompt>,
48
- ): Promise<ReadonlyArray<PromptResult>>;
41
+ promptAll(prompts: ReadonlyArray<Prompt>): Promise<ReadonlyArray<PromptResult>>;
49
42
  }
@@ -1,5 +1,4 @@
1
- export const SHUTDOWN_SERVICE_ID =
2
- "@flowscripter/dynamic-cli-framework/shutdown-service";
1
+ export const SHUTDOWN_SERVICE_ID = "@flowscripter/dynamic-cli-framework/shutdown-service";
3
2
 
4
3
  /**
5
4
  * Service allowing registration of callbacks for CLI shutdown.
@@ -50,9 +50,5 @@ export default interface SyntaxHighlighterService {
50
50
  * @param syntaxName the syntax to use.
51
51
  * @param colorScheme the color scheme to use.
52
52
  */
53
- highlight(
54
- text: string,
55
- syntaxName: string,
56
- colorScheme?: ColorScheme,
57
- ): string;
53
+ highlight(text: string, syntaxName: string, colorScheme?: ColorScheme): string;
58
54
  }
@@ -12,14 +12,9 @@ export default class Table {
12
12
 
13
13
  readonly #columnOptions: Map<number, ColumnOptions> = new Map();
14
14
  readonly #rowOptions: Map<number, RowOptions> = new Map();
15
- readonly #cells: Map<string, { contents: string; options?: CellOptions }> =
16
- new Map();
15
+ readonly #cells: Map<string, { contents: string; options?: CellOptions }> = new Map();
17
16
 
18
- constructor(
19
- rowCount: number,
20
- columnCount: number,
21
- options?: TableOptions,
22
- ) {
17
+ constructor(rowCount: number, columnCount: number, options?: TableOptions) {
23
18
  this.rowCount = rowCount;
24
19
  this.columnCount = columnCount;
25
20
  this.options = options ?? {};
@@ -27,9 +22,7 @@ export default class Table {
27
22
 
28
23
  row(rowIndex: number, rowOptions: RowOptions): Table {
29
24
  if (rowIndex < 0 || rowIndex >= this.rowCount) {
30
- throw new Error(
31
- `Row index ${rowIndex} out of bounds [0, ${this.rowCount})`,
32
- );
25
+ throw new Error(`Row index ${rowIndex} out of bounds [0, ${this.rowCount})`);
33
26
  }
34
27
  this.#rowOptions.set(rowIndex, rowOptions);
35
28
  return this;
@@ -37,29 +30,18 @@ export default class Table {
37
30
 
38
31
  column(columnIndex: number, columnOptions: ColumnOptions): Table {
39
32
  if (columnIndex < 0 || columnIndex >= this.columnCount) {
40
- throw new Error(
41
- `Column index ${columnIndex} out of bounds [0, ${this.columnCount})`,
42
- );
33
+ throw new Error(`Column index ${columnIndex} out of bounds [0, ${this.columnCount})`);
43
34
  }
44
35
  this.#columnOptions.set(columnIndex, columnOptions);
45
36
  return this;
46
37
  }
47
38
 
48
- cell(
49
- rowIndex: number,
50
- columnIndex: number,
51
- contents: string,
52
- cellOptions?: CellOptions,
53
- ): Table {
39
+ cell(rowIndex: number, columnIndex: number, contents: string, cellOptions?: CellOptions): Table {
54
40
  if (rowIndex < 0 || rowIndex >= this.rowCount) {
55
- throw new Error(
56
- `Row index ${rowIndex} out of bounds [0, ${this.rowCount})`,
57
- );
41
+ throw new Error(`Row index ${rowIndex} out of bounds [0, ${this.rowCount})`);
58
42
  }
59
43
  if (columnIndex < 0 || columnIndex >= this.columnCount) {
60
- throw new Error(
61
- `Column index ${columnIndex} out of bounds [0, ${this.columnCount})`,
62
- );
44
+ throw new Error(`Column index ${columnIndex} out of bounds [0, ${this.columnCount})`);
63
45
  }
64
46
  this.#cells.set(`${rowIndex},${columnIndex}`, {
65
47
  contents,
@@ -1,5 +1,4 @@
1
- export const TREE_PRINTER_SERVICE_ID =
2
- "@flowscripter/dynamic-cli-framework/tree-printer-service";
1
+ export const TREE_PRINTER_SERVICE_ID = "@flowscripter/dynamic-cli-framework/tree-printer-service";
3
2
 
4
3
  export interface TreeNode {
5
4
  label: string;
@@ -113,13 +113,10 @@ export default class BaseCLI implements CLI {
113
113
  `Invalid CLI name starting with a digit or dash provided: '${cliConfig.name}'`,
114
114
  );
115
115
  }
116
- if (
117
- (cliConfig.description !== undefined) &&
118
- (cliConfig.description.length === 0)
119
- ) {
116
+ if (cliConfig.description !== undefined && cliConfig.description.length === 0) {
120
117
  throw new Error("Invalid empty CLI description provided");
121
118
  }
122
- if ((cliConfig.version !== undefined) && (cliConfig.version.length === 0)) {
119
+ if (cliConfig.version !== undefined && cliConfig.version.length === 0) {
123
120
  throw new Error("Invalid empty CLI version provided");
124
121
  }
125
122
  this.#cliConfig = cliConfig;
@@ -197,13 +194,11 @@ export default class BaseCLI implements CLI {
197
194
 
198
195
  async run(args: ReadonlyArray<string>): Promise<RunResult> {
199
196
  if (this.#addedNonModifierCommands.length === 0) {
200
- throw new Error(
201
- "No non-modifier commands added to the CLI, nothing to run!",
202
- );
197
+ throw new Error("No non-modifier commands added to the CLI, nothing to run!");
203
198
  }
204
199
 
205
200
  if (
206
- (this.#addedNonModifierCommands.length === 1) &&
201
+ this.#addedNonModifierCommands.length === 1 &&
207
202
  !isSubCommand(this.#addedNonModifierCommands[0]!) &&
208
203
  !isGlobalCommand(this.#addedNonModifierCommands[0]!) &&
209
204
  !isGroupCommand(this.#addedNonModifierCommands[0]!)
@@ -215,12 +210,7 @@ export default class BaseCLI implements CLI {
215
210
 
216
211
  // create and add core services
217
212
  this.addServiceProvider(new ShutdownServiceProvider(100));
218
- this.addServiceProvider(
219
- new PrinterServiceProvider(
220
- 80,
221
- this.#printerService,
222
- ),
223
- );
213
+ this.addServiceProvider(new PrinterServiceProvider(80, this.#printerService));
224
214
  this.addServiceProvider(new TableGeneratorServiceProvider(70));
225
215
 
226
216
  const prompterService = new DefaultPrompterService(
@@ -232,26 +222,18 @@ export default class BaseCLI implements CLI {
232
222
  this.addServiceProvider(new PrompterServiceProvider(75, prompterService));
233
223
 
234
224
  if (this.#options.argumentPrompterServiceEnabled) {
235
- const argumentPrompterService = new DefaultArgumentPrompterService(
236
- prompterService,
237
- );
238
- this.addServiceProvider(
239
- new ArgumentPrompterServiceProvider(65, argumentPrompterService),
240
- );
225
+ const argumentPrompterService = new DefaultArgumentPrompterService(prompterService);
226
+ this.addServiceProvider(new ArgumentPrompterServiceProvider(65, argumentPrompterService));
241
227
  }
242
228
 
243
229
  if (this.#options.imagePrinterServiceEnabled) {
244
- this.addServiceProvider(
245
- new ImagePrinterServiceProvider(55, this.#stdoutTerminal),
246
- );
230
+ this.addServiceProvider(new ImagePrinterServiceProvider(55, this.#stdoutTerminal));
247
231
  }
248
232
 
249
233
  let completionService: DefaultCompletionService | undefined;
250
234
  if (this.#options.completionServiceEnabled) {
251
235
  completionService = new DefaultCompletionService();
252
- this.addServiceProvider(
253
- new CompletionServiceProvider(60, completionService),
254
- );
236
+ this.addServiceProvider(new CompletionServiceProvider(60, completionService));
255
237
  }
256
238
 
257
239
  const configurationServiceProvider = new ConfigurationServiceProvider(
@@ -263,17 +245,11 @@ export default class BaseCLI implements CLI {
263
245
  );
264
246
  this.addServiceProvider(configurationServiceProvider);
265
247
 
266
- for (
267
- const serviceProvider of this.#serviceProviderRegistry
268
- .getServiceProviders()
269
- ) {
248
+ for (const serviceProvider of this.#serviceProviderRegistry.getServiceProviders()) {
270
249
  const serviceInfo = await serviceProvider.getServiceInfo(this.#cliConfig);
271
250
 
272
251
  if (serviceInfo.service) {
273
- this.#context.addServiceInstance(
274
- serviceProvider.serviceId,
275
- serviceInfo.service,
276
- );
252
+ this.#context.addServiceInstance(serviceProvider.serviceId, serviceInfo.service);
277
253
  }
278
254
 
279
255
  serviceInfo.commands.forEach((command) => {
@@ -349,16 +325,13 @@ export default class BaseCLI implements CLI {
349
325
  await new UsageCommand(helpGlobalCommand).execute(this.#context);
350
326
  } else if (runResult.runState === RunState.PARSE_ERROR) {
351
327
  if (
352
- (runResult.command !== undefined) && (
353
- isSubCommand(runResult.command) ||
354
- isGlobalCommand(runResult.command)
355
- )
328
+ runResult.command !== undefined &&
329
+ (isSubCommand(runResult.command) || isGlobalCommand(runResult.command))
356
330
  ) {
357
331
  // print help on specific command
358
- await helpSubCommand.execute(
359
- this.#context,
360
- { command: runResult.command!.name },
361
- );
332
+ await helpSubCommand.execute(this.#context, {
333
+ command: runResult.command!.name,
334
+ });
362
335
  } else {
363
336
  // print usage
364
337
  await new UsageCommand(helpGlobalCommand).execute(this.#context);
@@ -366,10 +339,7 @@ export default class BaseCLI implements CLI {
366
339
  }
367
340
  return runResult;
368
341
  } catch (error) {
369
- if (
370
- shutdownState.shutdownRequested ||
371
- (error as Error).message === "Interrupted"
372
- ) {
342
+ if (shutdownState.shutdownRequested || (error as Error).message === "Interrupted") {
373
343
  return { runState: RunState.INTERRUPTED };
374
344
  }
375
345
  logger.error("Runtime error: %s", (error as Error).message);
@@ -15,10 +15,7 @@ import supportsHyperlinks from "../terminal/supportsHyperlinks.ts";
15
15
  * Default Bun implementation of a {@link CLI} using `process.stdout`, `process.stderr` and `process.argv`.
16
16
  */
17
17
  export default class DefaultRuntimeCLI extends BaseCLI {
18
- constructor(
19
- cliConfig: CLIConfig,
20
- options?: BaseCLIFeatureOptions,
21
- ) {
18
+ constructor(cliConfig: CLIConfig, options?: BaseCLIFeatureOptions) {
22
19
  super(
23
20
  cliConfig,
24
21
  Writable.toWeb(process.stdout),
@@ -3,19 +3,10 @@ import type SubCommand from "../api/command/SubCommand.ts";
3
3
  import type Option from "../api/argument/Option.ts";
4
4
  import type Positional from "../api/argument/Positional.ts";
5
5
  import type Context from "../api/Context.ts";
6
- import {
7
- type ArgumentValues,
8
- ArgumentValueTypeName,
9
- } from "../api/argument/ArgumentValueTypes.ts";
10
- import {
11
- COMPLETION_SERVICE_ID,
12
- ShellType,
13
- } from "../api/service/core/CompletionService.ts";
6
+ import { type ArgumentValues, ArgumentValueTypeName } from "../api/argument/ArgumentValueTypes.ts";
7
+ import { COMPLETION_SERVICE_ID, ShellType } from "../api/service/core/CompletionService.ts";
14
8
  import type DefaultCompletionService from "../service/completion/DefaultCompletionService.ts";
15
- import {
16
- Icon,
17
- PRINTER_SERVICE_ID,
18
- } from "../api/service/core/PrinterService.ts";
9
+ import { Icon, PRINTER_SERVICE_ID } from "../api/service/core/PrinterService.ts";
19
10
  import type PrinterService from "../api/service/core/PrinterService.ts";
20
11
 
21
12
  export class CompletionIntegrationSubCommand implements SubCommand {
@@ -41,16 +32,11 @@ export class CompletionIntegrationSubCommand implements SubCommand {
41
32
  },
42
33
  ];
43
34
 
44
- async execute(
45
- context: Context,
46
- argumentValues: ArgumentValues,
47
- ): Promise<void> {
35
+ async execute(context: Context, argumentValues: ArgumentValues): Promise<void> {
48
36
  const completionService = context.getServiceById(
49
37
  COMPLETION_SERVICE_ID,
50
38
  ) as DefaultCompletionService;
51
- const printerService = context.getServiceById(
52
- PRINTER_SERVICE_ID,
53
- ) as PrinterService;
39
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
54
40
 
55
41
  const shellType = argumentValues.shell as ShellType;
56
42
  const configPathArg = argumentValues["config-path"] as string | undefined;
@@ -63,13 +49,9 @@ export class CompletionIntegrationSubCommand implements SubCommand {
63
49
  );
64
50
  }
65
51
 
66
- const configPath = configPathArg ||
67
- completionService.getDefaultConfigPath(shellType);
52
+ const configPath = configPathArg || completionService.getDefaultConfigPath(shellType);
68
53
  const cliName = context.cliConfig.name;
69
- const bootstrapScript = completionService.getBootstrapScript(
70
- shellType,
71
- cliName,
72
- );
54
+ const bootstrapScript = completionService.getBootstrapScript(shellType, cliName);
73
55
 
74
56
  const beginMarker = `# BEGIN ${cliName} completion`;
75
57
  const endMarker = `# END ${cliName} completion`;
@@ -86,16 +68,17 @@ export class CompletionIntegrationSubCommand implements SubCommand {
86
68
  const beginIdx = existingContent.indexOf(beginMarker);
87
69
  const endIdx = existingContent.indexOf(endMarker);
88
70
  if (beginIdx !== -1 && endIdx !== -1) {
89
- newContent = existingContent.substring(0, beginIdx) +
71
+ newContent =
72
+ existingContent.substring(0, beginIdx) +
90
73
  block +
91
74
  existingContent.substring(endIdx + endMarker.length);
92
75
  } else {
93
- const separator = existingContent.length > 0 &&
94
- !existingContent.endsWith("\n")
95
- ? "\n\n"
96
- : existingContent.length > 0
97
- ? "\n"
98
- : "";
76
+ const separator =
77
+ existingContent.length > 0 && !existingContent.endsWith("\n")
78
+ ? "\n\n"
79
+ : existingContent.length > 0
80
+ ? "\n"
81
+ : "";
99
82
  newContent = existingContent + separator + block + "\n";
100
83
  }
101
84
 
@@ -130,24 +113,16 @@ export class CompletionCompleteSubCommand implements SubCommand {
130
113
  },
131
114
  ];
132
115
 
133
- async execute(
134
- context: Context,
135
- argumentValues: ArgumentValues,
136
- ): Promise<void> {
116
+ async execute(context: Context, argumentValues: ArgumentValues): Promise<void> {
137
117
  const completionService = context.getServiceById(
138
118
  COMPLETION_SERVICE_ID,
139
119
  ) as DefaultCompletionService;
140
- const printerService = context.getServiceById(
141
- PRINTER_SERVICE_ID,
142
- ) as PrinterService;
120
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
143
121
 
144
122
  const shellType = argumentValues.shell as ShellType;
145
123
  const args = (argumentValues.args || []) as string[];
146
124
 
147
- const completionContext = completionService.parseCompletionContext(
148
- shellType,
149
- args,
150
- );
125
+ const completionContext = completionService.parseCompletionContext(shellType, args);
151
126
  const completions = await completionService.generateCompletions(
152
127
  shellType,
153
128
  completionContext.line,
@@ -174,6 +149,5 @@ export class CompletionGroupCommand implements GroupCommand {
174
149
  this.memberSubCommands = [integrationCommand, completeCommand];
175
150
  }
176
151
 
177
- async execute(_context: Context): Promise<void> {
178
- }
152
+ async execute(_context: Context): Promise<void> {}
179
153
  }
@@ -22,10 +22,7 @@ import {
22
22
  import type GlobalModifierCommand from "../api/command/GlobalModifierCommand.ts";
23
23
  import type CommandRegistry from "../runtime/registry/CommandRegistry.ts";
24
24
  import type PrinterService from "../api/service/core/PrinterService.ts";
25
- import {
26
- Icon,
27
- PRINTER_SERVICE_ID,
28
- } from "../api/service/core/PrinterService.ts";
25
+ import { Icon, PRINTER_SERVICE_ID } from "../api/service/core/PrinterService.ts";
29
26
  import type TableGeneratorService from "../api/service/core/TableGeneratorService.ts";
30
27
  import { TABLE_GENERATOR_SERVICE_ID } from "../api/service/core/TableGeneratorService.ts";
31
28
 
@@ -38,10 +35,7 @@ abstract class MultiCommandCliAbstractHelpCommand {
38
35
  readonly #includeEnvVars: boolean;
39
36
  readonly #commandRegistry: CommandRegistry;
40
37
 
41
- constructor(
42
- includeEnvVars: boolean,
43
- commandRegistry: CommandRegistry,
44
- ) {
38
+ constructor(includeEnvVars: boolean, commandRegistry: CommandRegistry) {
45
39
  this.#includeEnvVars = includeEnvVars;
46
40
  this.#commandRegistry = commandRegistry;
47
41
  }
@@ -72,9 +66,7 @@ abstract class MultiCommandCliAbstractHelpCommand {
72
66
  });
73
67
  }
74
68
  });
75
- globalCommandsSection.helpEntries.sort((a, b) =>
76
- a.syntax.localeCompare(b.syntax)
77
- );
69
+ globalCommandsSection.helpEntries.sort((a, b) => a.syntax.localeCompare(b.syntax));
78
70
  return globalCommandsSection;
79
71
  }
80
72
 
@@ -85,8 +77,7 @@ abstract class MultiCommandCliAbstractHelpCommand {
85
77
  groupCommands: ReadonlyArray<GroupCommand>,
86
78
  subCommands: ReadonlyArray<SubCommand>,
87
79
  ): Array<HelpSection> {
88
- const globalPrefix =
89
- ((groupCommands.length > 0) || (subCommands.length > 0)) ? "Global " : "";
80
+ const globalPrefix = groupCommands.length > 0 || subCommands.length > 0 ? "Global " : "";
90
81
  const helpSections: HelpSection[] = [];
91
82
  if (globalModifierCommands.length > 0) {
92
83
  helpSections.push(
@@ -99,18 +90,12 @@ abstract class MultiCommandCliAbstractHelpCommand {
99
90
  }
100
91
  if (globalCommands.length > 0) {
101
92
  helpSections.push(
102
- this.#getGlobalCommandsHelpSection(
103
- context,
104
- `${globalPrefix}Commands`,
105
- globalCommands,
106
- ),
93
+ this.#getGlobalCommandsHelpSection(context, `${globalPrefix}Commands`, globalCommands),
107
94
  );
108
95
  }
109
96
  groupCommands.forEach((groupCommand) => {
110
97
  const topicSection: HelpSection = {
111
- title: `${
112
- groupCommand.name.charAt(0).toUpperCase() + groupCommand.name.slice(1)
113
- } Commands`,
98
+ title: `${groupCommand.name.charAt(0).toUpperCase() + groupCommand.name.slice(1)} Commands`,
114
99
  helpEntries: [],
115
100
  };
116
101
  groupCommand.memberSubCommands.forEach((memberCommand) => {
@@ -156,9 +141,10 @@ abstract class MultiCommandCliAbstractHelpCommand {
156
141
 
157
142
  if (otherSubCommands.length > 0) {
158
143
  const topicSection: HelpSection = {
159
- title: (subCommandsByTopic.size > 0 || groupCommands.length > 0)
160
- ? "Other Commands"
161
- : "Sub-Commands",
144
+ title:
145
+ subCommandsByTopic.size > 0 || groupCommands.length > 0
146
+ ? "Other Commands"
147
+ : "Sub-Commands",
162
148
  helpEntries: [],
163
149
  };
164
150
  otherSubCommands.sort((a, b) => a.name.localeCompare(b.name));
@@ -174,18 +160,13 @@ abstract class MultiCommandCliAbstractHelpCommand {
174
160
  return helpSections;
175
161
  }
176
162
 
177
- protected async printGenericHelp(
178
- context: Context,
179
- ): Promise<void> {
180
- const printerService = context.getServiceById(
181
- PRINTER_SERVICE_ID,
182
- ) as PrinterService;
163
+ protected async printGenericHelp(context: Context): Promise<void> {
164
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
183
165
  const tableGeneratorService = context.getServiceById(
184
166
  TABLE_GENERATOR_SERVICE_ID,
185
167
  ) as TableGeneratorService;
186
168
 
187
- const globalModifierCommands = this.#commandRegistry
188
- .getGlobalModifierCommands();
169
+ const globalModifierCommands = this.#commandRegistry.getGlobalModifierCommands();
189
170
  const globalCommands = this.#commandRegistry.getGlobalCommands();
190
171
  const groupCommands = this.#commandRegistry.getGroupCommands();
191
172
  const subCommands = this.#commandRegistry.getSubCommands();
@@ -215,20 +196,11 @@ abstract class MultiCommandCliAbstractHelpCommand {
215
196
  ),
216
197
  );
217
198
 
218
- await printHelpSections(
219
- printerService,
220
- tableGeneratorService,
221
- helpSections,
222
- );
199
+ await printHelpSections(printerService, tableGeneratorService, helpSections);
223
200
  }
224
201
 
225
- protected async printUsageHelp(
226
- context: Context,
227
- commandName: string,
228
- ): Promise<void> {
229
- const printerService = context.getServiceById(
230
- PRINTER_SERVICE_ID,
231
- ) as PrinterService;
202
+ protected async printUsageHelp(context: Context, commandName: string): Promise<void> {
203
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
232
204
  const tableGeneratorService = context.getServiceById(
233
205
  TABLE_GENERATOR_SERVICE_ID,
234
206
  ) as TableGeneratorService;
@@ -242,8 +214,8 @@ abstract class MultiCommandCliAbstractHelpCommand {
242
214
  let groupCommand: GroupCommand | undefined;
243
215
 
244
216
  if (subCommand === undefined) {
245
- const result = this.#commandRegistry
246
- .getGroupCommandAndMemberSubCommandByJoinedName(commandName);
217
+ const result =
218
+ this.#commandRegistry.getGroupCommandAndMemberSubCommandByJoinedName(commandName);
247
219
  if (result !== undefined) {
248
220
  groupCommand = result.groupCommand;
249
221
  subCommand = result.command;
@@ -273,50 +245,39 @@ abstract class MultiCommandCliAbstractHelpCommand {
273
245
  }
274
246
 
275
247
  // display command help
276
- const name = (groupCommand === undefined)
277
- ? subCommand.name
278
- : `${groupCommand.name}:${subCommand.name}`;
248
+ const name =
249
+ groupCommand === undefined ? subCommand.name : `${groupCommand.name}:${subCommand.name}`;
279
250
  const helpSections: HelpSection[] = [];
280
251
 
281
- if (
282
- (subCommand.description !== undefined) &&
283
- (subCommand.description.length > 0)
284
- ) {
252
+ if (subCommand.description !== undefined && subCommand.description.length > 0) {
285
253
  helpSections.push({
286
254
  title: "Command",
287
- helpEntries: [{
288
- syntax: subCommand.name,
289
- description: subCommand.description,
290
- }],
255
+ helpEntries: [
256
+ {
257
+ syntax: subCommand.name,
258
+ description: subCommand.description,
259
+ },
260
+ ],
291
261
  });
292
262
  }
293
263
  helpSections.push({
294
264
  title: "Usage",
295
- helpEntries: [{
296
- syntax: `${context.cliConfig.name}${name.length > 0 ? ` ${name}` : ""}${
297
- getSubCommandArgumentsSyntax(subCommand)
298
- }`,
299
- }],
265
+ helpEntries: [
266
+ {
267
+ syntax: `${context.cliConfig.name}${
268
+ name.length > 0 ? ` ${name}` : ""
269
+ }${getSubCommandArgumentsSyntax(subCommand)}`,
270
+ },
271
+ ],
300
272
  });
301
273
 
302
274
  helpSections.push(
303
- ...getCommandArgsHelpSections(
304
- context.cliConfig,
305
- this.#includeEnvVars,
306
- subCommand,
307
- false,
308
- ),
275
+ ...getCommandArgsHelpSections(context.cliConfig, this.#includeEnvVars, subCommand, false),
309
276
  );
310
277
 
311
- helpSections.push(
312
- ...getCommandExamplesHelpSections(printerService, context, subCommand),
313
- );
278
+ helpSections.push(...getCommandExamplesHelpSections(printerService, context, subCommand));
314
279
 
315
- await printHelpSections(
316
- printerService,
317
- tableGeneratorService,
318
- helpSections,
319
- );
280
+ await printHelpSections(printerService, tableGeneratorService, helpSections);
320
281
  }
321
282
  }
322
283
 
@@ -325,7 +286,8 @@ abstract class MultiCommandCliAbstractHelpCommand {
325
286
  */
326
287
  export class MultiCommandCliHelpGlobalCommand
327
288
  extends MultiCommandCliAbstractHelpCommand
328
- implements GlobalCommand {
289
+ implements GlobalCommand
290
+ {
329
291
  readonly shortAlias = "h";
330
292
 
331
293
  readonly argument = {
@@ -334,13 +296,8 @@ export class MultiCommandCliHelpGlobalCommand
334
296
  isOptional: true,
335
297
  };
336
298
 
337
- public async execute(
338
- context: Context,
339
- argumentValue?: ArgumentSingleValueType,
340
- ): Promise<void> {
341
- const commandName = argumentValue as
342
- | string
343
- | undefined;
299
+ public async execute(context: Context, argumentValue?: ArgumentSingleValueType): Promise<void> {
300
+ const commandName = argumentValue as string | undefined;
344
301
  if (commandName !== undefined) {
345
302
  await this.printUsageHelp(context, commandName);
346
303
  } else {
@@ -354,7 +311,8 @@ export class MultiCommandCliHelpGlobalCommand
354
311
  */
355
312
  export class MultiCommandCliHelpSubCommand
356
313
  extends MultiCommandCliAbstractHelpCommand
357
- implements SubCommand {
314
+ implements SubCommand
315
+ {
358
316
  public readonly options: ReadonlyArray<Option> = [];
359
317
 
360
318
  public readonly positionals: ReadonlyArray<Positional> = [
@@ -366,13 +324,8 @@ export class MultiCommandCliHelpSubCommand
366
324
  },
367
325
  ];
368
326
 
369
- public async execute(
370
- context: Context,
371
- argumentValues: ArgumentValues,
372
- ): Promise<void> {
373
- const commandName = argumentValues["command"] as
374
- | string
375
- | undefined;
327
+ public async execute(context: Context, argumentValues: ArgumentValues): Promise<void> {
328
+ const commandName = argumentValues["command"] as string | undefined;
376
329
  if (commandName !== undefined) {
377
330
  await this.printUsageHelp(context, commandName);
378
331
  } else {