@flowscripter/dynamic-cli-framework 1.2.1 → 1.3.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 (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
@@ -107,23 +107,21 @@ abstract class SingleCommandCliAbstractHelpCommand {
107
107
  });
108
108
  });
109
109
  }
110
- helpSection.helpEntries.sort((a: HelpEntry, b: HelpEntry) =>
111
- a.syntax.localeCompare(b.syntax)
112
- );
110
+ helpSection.helpEntries.sort((a: HelpEntry, b: HelpEntry) => a.syntax.localeCompare(b.syntax));
113
111
  return helpSection;
114
112
  }
115
113
 
116
- public async execute(
117
- context: Context,
118
- ): Promise<void> {
114
+ public async execute(context: Context): Promise<void> {
119
115
  const helpSections: Array<HelpSection> = [];
120
116
  helpSections.push({
121
117
  title: "Usage",
122
- helpEntries: [{
123
- syntax: `${context.cliConfig.name || ""}${
124
- getSubCommandArgumentsSyntax(this.#defaultCommand)
125
- }`,
126
- }],
118
+ helpEntries: [
119
+ {
120
+ syntax: `${context.cliConfig.name || ""}${getSubCommandArgumentsSyntax(
121
+ this.#defaultCommand,
122
+ )}`,
123
+ },
124
+ ],
127
125
  });
128
126
 
129
127
  helpSections.push(
@@ -135,8 +133,7 @@ abstract class SingleCommandCliAbstractHelpCommand {
135
133
  ),
136
134
  );
137
135
 
138
- const globalModifierCommands = this.#commandRegistry
139
- .getGlobalModifierCommands();
136
+ const globalModifierCommands = this.#commandRegistry.getGlobalModifierCommands();
140
137
  const globalCommands = this.#commandRegistry.getGlobalCommands();
141
138
  helpSections.push(
142
139
  this.#getAmalgamatedGenericHelpSection(
@@ -148,26 +145,16 @@ abstract class SingleCommandCliAbstractHelpCommand {
148
145
  ),
149
146
  );
150
147
 
151
- const printerService = context.getServiceById(
152
- PRINTER_SERVICE_ID,
153
- ) as PrinterService;
148
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
154
149
  const tableGeneratorService = context.getServiceById(
155
150
  TABLE_GENERATOR_SERVICE_ID,
156
151
  ) as TableGeneratorService;
157
152
 
158
153
  helpSections.push(
159
- ...getCommandExamplesHelpSections(
160
- printerService,
161
- context,
162
- this.#defaultCommand,
163
- ),
154
+ ...getCommandExamplesHelpSections(printerService, context, this.#defaultCommand),
164
155
  );
165
156
 
166
- await printHelpSections(
167
- printerService,
168
- tableGeneratorService,
169
- helpSections,
170
- );
157
+ await printHelpSections(printerService, tableGeneratorService, helpSections);
171
158
  }
172
159
  }
173
160
 
@@ -176,7 +163,8 @@ abstract class SingleCommandCliAbstractHelpCommand {
176
163
  */
177
164
  export class SingleCommandCliHelpGlobalCommand
178
165
  extends SingleCommandCliAbstractHelpCommand
179
- implements GlobalCommand {
166
+ implements GlobalCommand
167
+ {
180
168
  readonly shortAlias = "h";
181
169
  }
182
170
 
@@ -185,7 +173,8 @@ export class SingleCommandCliHelpGlobalCommand
185
173
  */
186
174
  export class SingleCommandCliHelpSubCommand
187
175
  extends SingleCommandCliAbstractHelpCommand
188
- implements SubCommand {
176
+ implements SubCommand
177
+ {
189
178
  public readonly options: ReadonlyArray<Option> = [];
190
179
 
191
180
  public readonly positionals: ReadonlyArray<Positional> = [];
@@ -13,23 +13,17 @@ export default class UsageCommand implements GlobalCommand {
13
13
 
14
14
  readonly #helpCommand: Command;
15
15
 
16
- public constructor(
17
- helpCommand: Command,
18
- ) {
16
+ public constructor(helpCommand: Command) {
19
17
  this.#helpCommand = helpCommand;
20
18
  }
21
19
 
22
- public async execute(
23
- context: Context,
24
- ): Promise<void> {
25
- const printerService = context.getServiceById(
26
- PRINTER_SERVICE_ID,
27
- ) as PrinterService;
20
+ public async execute(context: Context): Promise<void> {
21
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
28
22
 
29
23
  await printerService.print(
30
- `${printerService.secondary("Try running:")}\n\n ${
31
- printerService.primary(context.cliConfig.name)
32
- } --${printerService.primary(this.#helpCommand.name)}\n\n`,
24
+ `${printerService.secondary("Try running:")}\n\n ${printerService.primary(
25
+ context.cliConfig.name,
26
+ )} --${printerService.primary(this.#helpCommand.name)}\n\n`,
33
27
  );
34
28
  }
35
29
  }
@@ -11,12 +11,8 @@ export default class VersionCommand implements GlobalCommand {
11
11
  readonly description = "Show version information";
12
12
  readonly shortAlias = "v";
13
13
 
14
- public async execute(
15
- context: Context,
16
- ): Promise<void> {
17
- const printerService = context.getServiceById(
18
- PRINTER_SERVICE_ID,
19
- ) as PrinterService;
14
+ public async execute(context: Context): Promise<void> {
15
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
20
16
  await printerService.print(`${context.cliConfig.version}\n`);
21
17
  }
22
18
  }
package/src/launcher.ts CHANGED
@@ -27,7 +27,8 @@ export async function launchSingleCommandCLI(
27
27
 
28
28
  const mergedOptions: BaseCLIFeatureOptions = {
29
29
  ...options,
30
- validateAllCommands: (options?.validateAllCommands ?? false) ||
30
+ validateAllCommands:
31
+ (options?.validateAllCommands ?? false) ||
31
32
  process.env.DYNAMIC_CLI_FRAMEWORK_VALIDATE_ALL !== undefined,
32
33
  };
33
34
  const cli = new DefaultRuntimeCLI(cliConfig, mergedOptions);
@@ -58,7 +59,8 @@ export async function launchMultiCommandCLI(
58
59
 
59
60
  const mergedOptions: BaseCLIFeatureOptions = {
60
61
  ...options,
61
- validateAllCommands: (options?.validateAllCommands ?? false) ||
62
+ validateAllCommands:
63
+ (options?.validateAllCommands ?? false) ||
62
64
  process.env.DYNAMIC_CLI_FRAMEWORK_VALIDATE_ALL !== undefined,
63
65
  };
64
66
  const cli = new DefaultRuntimeCLI(cliConfig, mergedOptions);
@@ -7,14 +7,11 @@ import type CLIConfig from "../api/CLIConfig.ts";
7
7
  export default class DefaultContext implements Context {
8
8
  readonly #serviceInstancesById: Map<string, unknown> = new Map();
9
9
 
10
- public constructor(readonly cliConfig: CLIConfig) {
11
- }
10
+ public constructor(readonly cliConfig: CLIConfig) {}
12
11
 
13
12
  public addServiceInstance(id: string, serviceInstance: unknown) {
14
13
  if (this.#serviceInstancesById.has(id)) {
15
- throw new Error(
16
- `Service ID: ${id} duplicates the ID of an existing service`,
17
- );
14
+ throw new Error(`Service ID: ${id} duplicates the ID of an existing service`);
18
15
  }
19
16
  this.#serviceInstancesById.set(id, serviceInstance);
20
17
  }
@@ -1,8 +1,6 @@
1
1
  import type Argument from "../../api/argument/Argument.ts";
2
2
  import type ComplexOption from "../../api/argument/ComplexOption.ts";
3
3
 
4
- export function isComplexOption(
5
- argument: Argument | ComplexOption,
6
- ): argument is ComplexOption {
4
+ export function isComplexOption(argument: Argument | ComplexOption): argument is ComplexOption {
7
5
  return (argument as ComplexOption).properties !== undefined;
8
6
  }
@@ -4,27 +4,18 @@ import type GlobalCommand from "../../api/command/GlobalCommand.ts";
4
4
  import type GlobalModifierCommand from "../../api/command/GlobalModifierCommand.ts";
5
5
  import type Command from "../../api/command/Command.ts";
6
6
 
7
- export function isGroupCommand(
8
- command: Command,
9
- ): command is GroupCommand {
7
+ export function isGroupCommand(command: Command): command is GroupCommand {
10
8
  return (command as GroupCommand).memberSubCommands !== undefined;
11
9
  }
12
10
 
13
- export function isSubCommand(
14
- command: Command,
15
- ): command is SubCommand {
11
+ export function isSubCommand(command: Command): command is SubCommand {
16
12
  return (command as SubCommand).options !== undefined;
17
13
  }
18
14
 
19
- export function isGlobalModifierCommand(
20
- command: Command,
21
- ): command is GlobalModifierCommand {
15
+ export function isGlobalModifierCommand(command: Command): command is GlobalModifierCommand {
22
16
  return (command as GlobalModifierCommand).executePriority !== undefined;
23
17
  }
24
18
 
25
- export function isGlobalCommand(
26
- command: Command,
27
- ): command is GlobalCommand {
28
- return !isGroupCommand(command) && !isSubCommand(command) &&
29
- !isGlobalModifierCommand(command);
19
+ export function isGlobalCommand(command: Command): command is GlobalCommand {
20
+ return !isGroupCommand(command) && !isSubCommand(command) && !isGlobalModifierCommand(command);
30
21
  }
@@ -4,9 +4,7 @@ import type GlobalCommand from "../../api/command/GlobalCommand.ts";
4
4
  import type Argument from "../../api/argument/Argument.ts";
5
5
  import type GroupCommand from "../../api/command/GroupCommand.ts";
6
6
  import type SubCommand from "../../api/command/SubCommand.ts";
7
- import type {
8
- ArgumentSingleValueType,
9
- } from "../../api/argument/ArgumentValueTypes.ts";
7
+ import type { ArgumentSingleValueType } from "../../api/argument/ArgumentValueTypes.ts";
10
8
  import {
11
9
  ArgumentValueTypeName,
12
10
  ComplexValueTypeName,
@@ -49,7 +47,7 @@ function validateValueType(
49
47
  }
50
48
  break;
51
49
  case ArgumentValueTypeName.NUMBER:
52
- if ((typeof value !== "number") || !Number.isFinite(value)) {
50
+ if (typeof value !== "number" || !Number.isFinite(value)) {
53
51
  throw new Error(
54
52
  `Specified ${
55
53
  isDefaultValue ? "default" : isRangeValue ? "range" : "allowable"
@@ -58,7 +56,7 @@ function validateValueType(
58
56
  }
59
57
  break;
60
58
  case ArgumentValueTypeName.INTEGER:
61
- if ((typeof value !== "number") || !Number.isInteger(value)) {
59
+ if (typeof value !== "number" || !Number.isInteger(value)) {
62
60
  throw new Error(
63
61
  `Specified ${
64
62
  isDefaultValue ? "default" : isRangeValue ? "range" : "allowable"
@@ -91,26 +89,25 @@ function isUppercaseAlphaNumericOrUnderscore(value: string): boolean {
91
89
  }
92
90
 
93
91
  function isNameLegal(name: string): boolean {
94
- return (name.length > 0) && isAlphaNumericOrDashOrUnderscore(name) &&
95
- (name[0] !== "-");
92
+ return name.length > 0 && isAlphaNumericOrDashOrUnderscore(name) && name[0] !== "-";
96
93
  }
97
94
 
98
95
  function isConfigurationKeyLegal(configurationKey: string): boolean {
99
- return (configurationKey.length > 0) &&
96
+ return (
97
+ configurationKey.length > 0 &&
100
98
  isUppercaseAlphaNumericOrUnderscore(configurationKey) &&
101
- !configurationKey[0]!.match(/[0-9]/);
99
+ !configurationKey[0]!.match(/[0-9]/)
100
+ );
102
101
  }
103
102
 
104
103
  function validateArgument(argument: Argument, name: string): void {
105
104
  if (
106
- (argument.type !== ArgumentValueTypeName.NUMBER) &&
107
- (argument.type !== ArgumentValueTypeName.INTEGER) &&
108
- (argument.type !== ArgumentValueTypeName.STRING) &&
109
- (argument.type !== ArgumentValueTypeName.BOOLEAN)
105
+ argument.type !== ArgumentValueTypeName.NUMBER &&
106
+ argument.type !== ArgumentValueTypeName.INTEGER &&
107
+ argument.type !== ArgumentValueTypeName.STRING &&
108
+ argument.type !== ArgumentValueTypeName.BOOLEAN
110
109
  ) {
111
- throw new Error(
112
- `Illegal type: '${argument.type}' for argument: '${name}'`,
113
- );
110
+ throw new Error(`Illegal type: '${argument.type}' for argument: '${name}'`);
114
111
  }
115
112
  if (argument.allowableValues) {
116
113
  if (argument.type === ArgumentValueTypeName.BOOLEAN) {
@@ -123,10 +120,7 @@ function validateArgument(argument: Argument, name: string): void {
123
120
  });
124
121
  }
125
122
  if (argument.isCaseInsensitive !== undefined) {
126
- if (
127
- (argument.type === ArgumentValueTypeName.BOOLEAN) &&
128
- (argument.isCaseInsensitive === false)
129
- ) {
123
+ if (argument.type === ArgumentValueTypeName.BOOLEAN && argument.isCaseInsensitive === false) {
130
124
  throw new Error(
131
125
  `Illegal type: '${argument.type}' for argument: '${name}' must always be case insensitive`,
132
126
  );
@@ -138,8 +132,8 @@ function validateArgument(argument: Argument, name: string): void {
138
132
  }
139
133
  if (argument.minValueInclusive !== undefined) {
140
134
  if (
141
- (argument.type !== ArgumentValueTypeName.NUMBER) &&
142
- (argument.type !== ArgumentValueTypeName.INTEGER)
135
+ argument.type !== ArgumentValueTypeName.NUMBER &&
136
+ argument.type !== ArgumentValueTypeName.INTEGER
143
137
  ) {
144
138
  throw new Error(
145
139
  `Illegal type: '${argument.type}' for argument: '${name}' with min value specified`,
@@ -150,18 +144,12 @@ function validateArgument(argument: Argument, name: string): void {
150
144
  `Illegal combination of allowable values and min value for argument: '${name}'`,
151
145
  );
152
146
  }
153
- validateValueType(
154
- argument.type,
155
- argument.minValueInclusive,
156
- name,
157
- false,
158
- true,
159
- );
147
+ validateValueType(argument.type, argument.minValueInclusive, name, false, true);
160
148
  }
161
149
  if (argument.maxValueInclusive !== undefined) {
162
150
  if (
163
- (argument.type !== ArgumentValueTypeName.NUMBER) &&
164
- (argument.type !== ArgumentValueTypeName.INTEGER)
151
+ argument.type !== ArgumentValueTypeName.NUMBER &&
152
+ argument.type !== ArgumentValueTypeName.INTEGER
165
153
  ) {
166
154
  throw new Error(
167
155
  `Illegal type: '${argument.type}' for argument: '${name}' with max value specified`,
@@ -172,19 +160,11 @@ function validateArgument(argument: Argument, name: string): void {
172
160
  `Illegal combination of allowable values and max value for argument: '${name}'`,
173
161
  );
174
162
  }
175
- validateValueType(
176
- argument.type,
177
- argument.maxValueInclusive,
178
- name,
179
- false,
180
- true,
181
- );
163
+ validateValueType(argument.type, argument.maxValueInclusive, name, false, true);
182
164
  }
183
165
  }
184
166
 
185
- function validateSubCommandArgument(
186
- subCommandArgument: SubCommandArgument,
187
- ): void {
167
+ function validateSubCommandArgument(subCommandArgument: SubCommandArgument): void {
188
168
  if (!isNameLegal(subCommandArgument.name)) {
189
169
  throw new Error(`Illegal argument name: '${subCommandArgument.name}'`);
190
170
  }
@@ -236,8 +216,7 @@ export default class CommandValidator {
236
216
  }
237
217
  if (
238
218
  globalCommand.shortAlias &&
239
- (globalCommand.shortAlias.length !== 1 ||
240
- !isAlphaNumeric(globalCommand.shortAlias))
219
+ (globalCommand.shortAlias.length !== 1 || !isAlphaNumeric(globalCommand.shortAlias))
241
220
  ) {
242
221
  throw new Error(
243
222
  `Illegal short alias: '${globalCommand.shortAlias}' for global command: '${globalCommand.name}'`,
@@ -248,25 +227,16 @@ export default class CommandValidator {
248
227
  validateArgument(argument, globalCommand.name);
249
228
  if (argument.defaultValue) {
250
229
  const invalidArguments: Array<InvalidArgument> = [];
251
- validateGlobalCommandArgumentValue(
252
- globalCommand,
253
- argument.defaultValue,
254
- invalidArguments,
255
- );
230
+ validateGlobalCommandArgumentValue(globalCommand, argument.defaultValue, invalidArguments);
256
231
  if (invalidArguments.length > 0) {
257
232
  throw new Error(
258
- `Illegal default value for global command: '${globalCommand.name}' => ${
259
- invalidArguments.map((invalidArgument) =>
260
- getInvalidArgumentString(invalidArgument, true)
261
- ).join(", ")
262
- }`,
233
+ `Illegal default value for global command: '${globalCommand.name}' => ${invalidArguments
234
+ .map((invalidArgument) => getInvalidArgumentString(invalidArgument, true))
235
+ .join(", ")}`,
263
236
  );
264
237
  }
265
238
  }
266
- this.#validateGlobalCommandArgumentConfigurationKey(
267
- globalCommand,
268
- argument,
269
- );
239
+ this.#validateGlobalCommandArgumentConfigurationKey(globalCommand, argument);
270
240
  }
271
241
  }
272
242
 
@@ -289,9 +259,7 @@ export default class CommandValidator {
289
259
  throw new Error(`Illegal group command name: '${groupCommand.name}'`);
290
260
  }
291
261
  if (groupCommand.memberSubCommands.length === 0) {
292
- throw new Error(
293
- `Group command: '${groupCommand.name}' has no member sub-commands`,
294
- );
262
+ throw new Error(`Group command: '${groupCommand.name}' has no member sub-commands`);
295
263
  }
296
264
  const subCommandNames: Array<string> = [];
297
265
  groupCommand.memberSubCommands.forEach((subCommand) => {
@@ -378,16 +346,14 @@ export default class CommandValidator {
378
346
  argumentNames.push(positional.name);
379
347
 
380
348
  if (
381
- (i < subCommand.positionals.length - 1) &&
349
+ i < subCommand.positionals.length - 1 &&
382
350
  (positional.isVarargOptional || positional.isVarargMultiple)
383
351
  ) {
384
352
  throw new Error(
385
353
  `Positional: '${positional.name}' for the command: '${subCommand.name}' is defined as a vararg but it is not the last positional argument`,
386
354
  );
387
355
  }
388
- this.#validateSubCommandArgumentConfigurationKey(subCommand, [
389
- positional,
390
- ]);
356
+ this.#validateSubCommandArgumentConfigurationKey(subCommand, [positional]);
391
357
  }
392
358
  }
393
359
  }
@@ -399,12 +365,10 @@ export default class CommandValidator {
399
365
  const argument = argumentAncestry[argumentAncestry.length - 1]!;
400
366
  if (command.enableConfiguration === true) {
401
367
  if (
402
- (argument.configurationKey !== undefined) &&
368
+ argument.configurationKey !== undefined &&
403
369
  !isConfigurationKeyLegal(argument.configurationKey)
404
370
  ) {
405
- throw new Error(
406
- `Illegal configuration key: '${argument.configurationKey}'`,
407
- );
371
+ throw new Error(`Illegal configuration key: '${argument.configurationKey}'`);
408
372
  }
409
373
  const configurationKey = getSubCommandArgumentConfigurationKey(
410
374
  this.#cliConfig,
@@ -433,12 +397,10 @@ export default class CommandValidator {
433
397
  ) {
434
398
  if (command.enableConfiguration === true) {
435
399
  if (
436
- (globalCommandArgument.configurationKey !== undefined) &&
400
+ globalCommandArgument.configurationKey !== undefined &&
437
401
  !isConfigurationKeyLegal(globalCommandArgument.configurationKey)
438
402
  ) {
439
- throw new Error(
440
- `Illegal configuration key: '${globalCommandArgument.configurationKey}'`,
441
- );
403
+ throw new Error(`Illegal configuration key: '${globalCommandArgument.configurationKey}'`);
442
404
  }
443
405
  const configurationKey = getGlobalCommandArgumentConfigurationKey(
444
406
  this.#cliConfig,
@@ -472,24 +434,16 @@ export default class CommandValidator {
472
434
  option.shortAlias &&
473
435
  (option.shortAlias.length !== 1 || !isAlphaNumeric(option.shortAlias))
474
436
  ) {
475
- throw new Error(
476
- `Illegal short alias: '${option.shortAlias}' for option: '${option.name}'`,
477
- );
437
+ throw new Error(`Illegal short alias: '${option.shortAlias}' for option: '${option.name}'`);
478
438
  }
479
439
  if (isComplexOption(option)) {
480
- this.#validateComplexOption(
481
- subCommand,
482
- option,
483
- currentOptionPaths,
484
- allOptionPaths,
485
- [...argumentAncestry, option as unknown as SubCommandArgument],
486
- );
487
- } else {
488
- this.#validateOption(option, currentOptionPaths, allOptionPaths);
489
- this.#validateSubCommandArgumentConfigurationKey(subCommand, [
440
+ this.#validateComplexOption(subCommand, option, currentOptionPaths, allOptionPaths, [
490
441
  ...argumentAncestry,
491
- option,
442
+ option as unknown as SubCommandArgument,
492
443
  ]);
444
+ } else {
445
+ this.#validateOption(option, currentOptionPaths, allOptionPaths);
446
+ this.#validateSubCommandArgumentConfigurationKey(subCommand, [...argumentAncestry, option]);
493
447
  }
494
448
  }
495
449
 
@@ -501,25 +455,19 @@ export default class CommandValidator {
501
455
  validateSubCommandArgument(option);
502
456
  if (Array.isArray(option.defaultValue) && !option.isArray) {
503
457
  throw new Error(
504
- `Illegal array default value: '${
505
- option.defaultValue.join(",")
506
- }' for non-array option: '${option.name}'`,
458
+ `Illegal array default value: '${option.defaultValue.join(
459
+ ",",
460
+ )}' for non-array option: '${option.name}'`,
507
461
  );
508
462
  }
509
463
  if (option.defaultValue) {
510
464
  const invalidArguments: Array<InvalidArgument> = [];
511
- validateOptionValue(
512
- option,
513
- option.defaultValue,
514
- invalidArguments,
515
- );
465
+ validateOptionValue(option, option.defaultValue, invalidArguments);
516
466
  if (invalidArguments.length > 0) {
517
467
  throw new Error(
518
- `Illegal default value for option: '${option.name}' => ${
519
- invalidArguments.map((invalidArgument) =>
520
- getInvalidArgumentString(invalidArgument, true)
521
- ).join(", ")
522
- }`,
468
+ `Illegal default value for option: '${option.name}' => ${invalidArguments
469
+ .map((invalidArgument) => getInvalidArgumentString(invalidArgument, true))
470
+ .join(", ")}`,
523
471
  );
524
472
  }
525
473
  }
@@ -562,32 +510,24 @@ export default class CommandValidator {
562
510
  }
563
511
  if (Array.isArray(complexOption.defaultValue) && !complexOption.isArray) {
564
512
  throw new Error(
565
- `Illegal array default value: '${
566
- JSON.stringify(complexOption.defaultValue)
567
- }' for non-array option: '${complexOption.name}'`,
513
+ `Illegal array default value: '${JSON.stringify(
514
+ complexOption.defaultValue,
515
+ )}' for non-array option: '${complexOption.name}'`,
568
516
  );
569
517
  }
570
518
  if (complexOption.defaultValue) {
571
519
  const invalidArguments: Array<InvalidArgument> = [];
572
- validateOptionValue(
573
- complexOption,
574
- complexOption.defaultValue,
575
- invalidArguments,
576
- );
520
+ validateOptionValue(complexOption, complexOption.defaultValue, invalidArguments);
577
521
  if (invalidArguments.length > 0) {
578
522
  throw new Error(
579
- `Illegal default value for option: '${complexOption.name}' => ${
580
- invalidArguments.map((invalidArgument) =>
581
- getInvalidArgumentString(invalidArgument, true)
582
- ).join(", ")
583
- }`,
523
+ `Illegal default value for option: '${complexOption.name}' => ${invalidArguments
524
+ .map((invalidArgument) => getInvalidArgumentString(invalidArgument, true))
525
+ .join(", ")}`,
584
526
  );
585
527
  }
586
528
  }
587
529
  if (complexOption.properties.length === 0) {
588
- throw new Error(
589
- `Complex option: '${complexOption.name}' has no properties`,
590
- );
530
+ throw new Error(`Complex option: '${complexOption.name}' has no properties`);
591
531
  }
592
532
  complexOption.properties.forEach((property) => {
593
533
  const newCurrentOptionPaths: Array<string> = [];
@@ -596,9 +536,7 @@ export default class CommandValidator {
596
536
  });
597
537
  if (property.shortAlias) {
598
538
  currentOptionPaths.forEach((currentOptionPath) => {
599
- newCurrentOptionPaths.push(
600
- `${currentOptionPath}.${property.shortAlias}`,
601
- );
539
+ newCurrentOptionPaths.push(`${currentOptionPath}.${property.shortAlias}`);
602
540
  });
603
541
  }
604
542
  this.#validateOptionOrComplexOption(
@@ -21,7 +21,7 @@ import type SubCommand from "../api/command/SubCommand.ts";
21
21
  const logger = getLogger("parser");
22
22
 
23
23
  /**
24
- * A container holding the result of a {@link CommandClause} parsing operation.
24
+ * A container holding the result of a command clause parsing operation.
25
25
  */
26
26
  export interface ParseResult {
27
27
  /**
@@ -40,9 +40,7 @@ export interface ParseResult {
40
40
  * {@link PopulatedArgumentSingleValueType} is for {@link GlobalCommand} values, {@link PopulatedArgumentValues} is for
41
41
  * {@link SubCommand} values.
42
42
  */
43
- readonly populatedArgumentValues:
44
- | PopulatedArgumentValues
45
- | PopulatedArgumentSingleValueType;
43
+ readonly populatedArgumentValues: PopulatedArgumentValues | PopulatedArgumentSingleValueType;
46
44
 
47
45
  /**
48
46
  * Any arguments which were invalid.
@@ -72,7 +70,7 @@ export function parseSubCommandClause(
72
70
  const invalidArguments: Array<InvalidArgument> = [];
73
71
 
74
72
  // check if we need to process any arguments at all
75
- if ((command.options.length === 0) && (command.positionals.length === 0)) {
73
+ if (command.options.length === 0 && command.positionals.length === 0) {
76
74
  return {
77
75
  command,
78
76
  groupCommand,
@@ -82,12 +80,11 @@ export function parseSubCommandClause(
82
80
  };
83
81
  }
84
82
 
85
- const { populatedArgumentValues, unusedArgs, invalidArgument } =
86
- populateSubCommandValues(
87
- command,
88
- potentialArgs,
89
- defaultValues,
90
- );
83
+ const { populatedArgumentValues, unusedArgs, invalidArgument } = populateSubCommandValues(
84
+ command,
85
+ potentialArgs,
86
+ defaultValues,
87
+ );
91
88
 
92
89
  if (invalidArgument) {
93
90
  invalidArguments.push(invalidArgument);
@@ -172,12 +169,11 @@ export function parseGlobalCommandClause(
172
169
  };
173
170
  }
174
171
 
175
- let { populatedArgumentValue, unusedArgs, invalidArgument } =
176
- populateGlobalCommandValue(
177
- command,
178
- potentialArgs,
179
- defaultValue,
180
- );
172
+ let { populatedArgumentValue, unusedArgs, invalidArgument } = populateGlobalCommandValue(
173
+ command,
174
+ potentialArgs,
175
+ defaultValue,
176
+ );
181
177
 
182
178
  if (invalidArgument) {
183
179
  invalidArguments.push(invalidArgument);
@@ -59,9 +59,7 @@ export default interface CommandRegistry {
59
59
  /**
60
60
  * Get a registered {@link GlobalModifierCommand} by name.
61
61
  */
62
- getGlobalModifierCommandByName(
63
- name: string,
64
- ): GlobalModifierCommand | undefined;
62
+ getGlobalModifierCommandByName(name: string): GlobalModifierCommand | undefined;
65
63
 
66
64
  /**
67
65
  * Get a registered {@link GlobalModifierCommand} by short alias.
@@ -96,10 +94,7 @@ export default interface CommandRegistry {
96
94
  /**
97
95
  * Get a map of all registered {@link GlobalModifierCommand} instances by name not provided by a service.
98
96
  */
99
- getGlobalModifierCommandsByNameNotProvidedByService(): ReadonlyMap<
100
- string,
101
- GlobalModifierCommand
102
- >;
97
+ getGlobalModifierCommandsByNameNotProvidedByService(): ReadonlyMap<string, GlobalModifierCommand>;
103
98
 
104
99
  /**
105
100
  * Get a map of all registered {@link GlobalModifierCommand} instances by short alias not provided by a service.