@flowscripter/dynamic-cli-framework 2.4.0 → 3.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 (143) hide show
  1. package/dist/index.d.ts +6 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -1
  4. package/dist/src/cli/BaseCLI.d.ts +1 -0
  5. package/dist/src/cli/BaseCLI.d.ts.map +1 -1
  6. package/dist/src/cli/BaseCLI.js +6 -0
  7. package/dist/src/cli/BaseCLIFeatureOptions.d.ts +1 -0
  8. package/dist/src/cli/BaseCLIFeatureOptions.d.ts.map +1 -1
  9. package/dist/src/command/MultiCommandCliHelpCommand.d.ts +4 -4
  10. package/dist/src/command/MultiCommandCliHelpCommand.d.ts.map +1 -1
  11. package/dist/src/command/MultiCommandCliHelpCommand.js +3 -3
  12. package/dist/src/runtime/command/CommandValidator.d.ts.map +1 -1
  13. package/dist/src/runtime/command/CommandValidator.js +14 -16
  14. package/dist/src/runtime/parser.d.ts +5 -5
  15. package/dist/src/runtime/parser.d.ts.map +1 -1
  16. package/dist/src/runtime/parser.js +2 -2
  17. package/dist/src/runtime/runner.d.ts.map +1 -1
  18. package/dist/src/runtime/values/ValuePopulationResult.d.ts +3 -3
  19. package/dist/src/runtime/values/ValuePopulationResult.d.ts.map +1 -1
  20. package/dist/src/runtime/values/argumentValueMerge.d.ts +2 -2
  21. package/dist/src/runtime/values/argumentValueMerge.d.ts.map +1 -1
  22. package/dist/src/runtime/values/argumentValueValidation.d.ts +4 -4
  23. package/dist/src/runtime/values/argumentValueValidation.d.ts.map +1 -1
  24. package/dist/src/runtime/values/argumentValueValidation.js +6 -6
  25. package/dist/src/runtime/values/globalCommandValuePopulation.d.ts +4 -4
  26. package/dist/src/runtime/values/globalCommandValuePopulation.d.ts.map +1 -1
  27. package/dist/src/runtime/values/globalCommandValuePopulation.js +5 -5
  28. package/dist/src/runtime/values/subCommandValuePopulation.d.ts +5 -5
  29. package/dist/src/runtime/values/subCommandValuePopulation.d.ts.map +1 -1
  30. package/dist/src/runtime/values/subCommandValuePopulation.js +8 -7
  31. package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.d.ts.map +1 -1
  32. package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.js +6 -6
  33. package/dist/src/service/banner/command/NoBannerCommand.d.ts +2 -2
  34. package/dist/src/service/banner/command/NoBannerCommand.d.ts.map +1 -1
  35. package/dist/src/service/banner/command/NoBannerCommand.js +2 -2
  36. package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts +2 -2
  37. package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts.map +1 -1
  38. package/dist/src/service/completion/command/CompletionCompleteSubCommand.js +3 -3
  39. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts +2 -2
  40. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts.map +1 -1
  41. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.js +3 -3
  42. package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts +6 -6
  43. package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts.map +1 -1
  44. package/dist/src/service/configuration/ConfigurationServiceProvider.js +4 -4
  45. package/dist/src/service/configuration/command/ConfigCommand.d.ts +2 -2
  46. package/dist/src/service/configuration/command/ConfigCommand.d.ts.map +1 -1
  47. package/dist/src/service/configuration/command/ConfigCommand.js +2 -2
  48. package/dist/src/service/fetch/DefaultFetchService.d.ts +7 -0
  49. package/dist/src/service/fetch/DefaultFetchService.d.ts.map +1 -0
  50. package/dist/src/service/fetch/DefaultFetchService.js +44 -0
  51. package/dist/src/service/fetch/FetchServiceProvider.d.ts +10 -0
  52. package/dist/src/service/fetch/FetchServiceProvider.d.ts.map +1 -0
  53. package/dist/src/service/fetch/FetchServiceProvider.js +22 -0
  54. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts +2 -1
  55. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts.map +1 -1
  56. package/dist/src/service/plugin/DefaultPluginServiceProvider.js +23 -8
  57. package/dist/src/service/plugin/FetchInterfaceAdapter.d.ts +17 -0
  58. package/dist/src/service/plugin/FetchInterfaceAdapter.d.ts.map +1 -0
  59. package/dist/src/service/plugin/FetchInterfaceAdapter.js +16 -0
  60. package/dist/src/service/plugin/SpawnInterfaceAdapter.js +1 -1
  61. package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts +4 -4
  62. package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -1
  63. package/dist/src/service/plugin/command/PluginAddSubCommand.js +2 -2
  64. package/dist/src/service/plugin/command/PluginListSubCommand.d.ts +2 -2
  65. package/dist/src/service/plugin/command/PluginListSubCommand.d.ts.map +1 -1
  66. package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts +4 -4
  67. package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts.map +1 -1
  68. package/dist/src/service/plugin/command/PluginRemoveSubCommand.js +2 -2
  69. package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts +4 -4
  70. package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts.map +1 -1
  71. package/dist/src/service/plugin/command/PluginSearchSubCommand.js +2 -2
  72. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts +2 -2
  73. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts.map +1 -1
  74. package/dist/src/service/printer/command/DarkModeCommand.d.ts +2 -2
  75. package/dist/src/service/printer/command/DarkModeCommand.d.ts.map +1 -1
  76. package/dist/src/service/printer/command/DarkModeCommand.js +2 -2
  77. package/dist/src/service/printer/command/LogLevelCommand.d.ts +2 -2
  78. package/dist/src/service/printer/command/LogLevelCommand.d.ts.map +1 -1
  79. package/dist/src/service/printer/command/LogLevelCommand.js +2 -2
  80. package/dist/src/service/printer/command/NoColorCommand.d.ts +2 -2
  81. package/dist/src/service/printer/command/NoColorCommand.d.ts.map +1 -1
  82. package/dist/src/service/printer/command/NoColorCommand.js +2 -2
  83. package/dist/src/service/printer/command/NoHyperlinksCommand.d.ts +2 -2
  84. package/dist/src/service/printer/command/NoHyperlinksCommand.d.ts.map +1 -1
  85. package/dist/src/service/printer/command/NoHyperlinksCommand.js +2 -2
  86. package/dist/src/service/prompter/command/NoPromptCommand.d.ts +2 -2
  87. package/dist/src/service/prompter/command/NoPromptCommand.d.ts.map +1 -1
  88. package/dist/src/service/prompter/command/NoPromptCommand.js +2 -2
  89. package/dist/src/service/spawn/DefaultSpawnService.js +6 -6
  90. package/dist/src/service/upgrade/DefaultUpgradeService.d.ts +2 -2
  91. package/dist/src/service/upgrade/DefaultUpgradeService.d.ts.map +1 -1
  92. package/dist/src/service/upgrade/DefaultUpgradeService.js +33 -51
  93. package/dist/src/service/upgrade/UpgradeServiceProvider.d.ts.map +1 -1
  94. package/dist/src/service/upgrade/UpgradeServiceProvider.js +12 -9
  95. package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts +2 -2
  96. package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts.map +1 -1
  97. package/dist/src/service/upgrade/command/UpgradeSubCommand.js +3 -3
  98. package/dist/src/util/envVarHelper.d.ts +3 -3
  99. package/dist/src/util/envVarHelper.d.ts.map +1 -1
  100. package/dist/src/util/envVarHelper.js +9 -12
  101. package/dist/src/util/helpHelper.d.ts.map +1 -1
  102. package/dist/src/util/helpHelper.js +27 -28
  103. package/index.ts +12 -10
  104. package/package.json +3 -3
  105. package/src/cli/BaseCLI.ts +7 -0
  106. package/src/cli/BaseCLIFeatureOptions.ts +1 -0
  107. package/src/command/MultiCommandCliHelpCommand.ts +7 -7
  108. package/src/runtime/command/CommandValidator.ts +17 -26
  109. package/src/runtime/parser.ts +8 -8
  110. package/src/runtime/runner.ts +16 -19
  111. package/src/runtime/values/ValuePopulationResult.ts +4 -4
  112. package/src/runtime/values/argumentValueMerge.ts +33 -50
  113. package/src/runtime/values/argumentValueValidation.ts +38 -52
  114. package/src/runtime/values/globalCommandValuePopulation.ts +7 -7
  115. package/src/runtime/values/subCommandValuePopulation.ts +42 -47
  116. package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +23 -26
  117. package/src/service/banner/command/NoBannerCommand.ts +3 -6
  118. package/src/service/completion/command/CompletionCompleteSubCommand.ts +4 -7
  119. package/src/service/completion/command/CompletionIntegrationSubCommand.ts +4 -7
  120. package/src/service/configuration/ConfigurationServiceProvider.ts +21 -21
  121. package/src/service/configuration/command/ConfigCommand.ts +3 -6
  122. package/src/service/fetch/DefaultFetchService.ts +55 -0
  123. package/src/service/fetch/FetchServiceProvider.ts +33 -0
  124. package/src/service/plugin/DefaultPluginServiceProvider.ts +29 -12
  125. package/src/service/plugin/FetchInterfaceAdapter.ts +28 -0
  126. package/src/service/plugin/SpawnInterfaceAdapter.ts +1 -1
  127. package/src/service/plugin/command/PluginAddSubCommand.ts +4 -4
  128. package/src/service/plugin/command/PluginListSubCommand.ts +2 -2
  129. package/src/service/plugin/command/PluginRemoveSubCommand.ts +4 -4
  130. package/src/service/plugin/command/PluginSearchSubCommand.ts +4 -4
  131. package/src/service/plugin/command/PluginUpgradeSubCommand.ts +2 -2
  132. package/src/service/printer/command/DarkModeCommand.ts +3 -6
  133. package/src/service/printer/command/LogLevelCommand.ts +3 -6
  134. package/src/service/printer/command/NoColorCommand.ts +3 -6
  135. package/src/service/printer/command/NoHyperlinksCommand.ts +3 -6
  136. package/src/service/prompter/command/NoPromptCommand.ts +3 -6
  137. package/src/service/prompter/prompt/promptText.ts +2 -2
  138. package/src/service/spawn/DefaultSpawnService.ts +6 -6
  139. package/src/service/upgrade/DefaultUpgradeService.ts +66 -65
  140. package/src/service/upgrade/UpgradeServiceProvider.ts +13 -9
  141. package/src/service/upgrade/command/UpgradeSubCommand.ts +4 -7
  142. package/src/util/envVarHelper.ts +23 -26
  143. package/src/util/helpHelper.ts +28 -36
@@ -1,11 +1,11 @@
1
1
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
2
2
  import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import {
4
- type ArgumentSingleValueType,
5
- ArgumentValueTypeName,
6
- type PopulatedArgumentSingleValueType,
7
- type PopulatedArgumentValues,
8
- type PopulatedArgumentValueType,
4
+ type SingleValueType,
5
+ ValueTypeName,
6
+ type PopulatedSingleValueType,
7
+ type PopulatedValues,
8
+ type PopulatedValueType,
9
9
  } from "@flowscripter/dynamic-cli-framework-api";
10
10
  import getLogger from "../../util/logger.ts";
11
11
  import argumentValueMerge from "./argumentValueMerge.ts";
@@ -58,7 +58,7 @@ class ParseContext {
58
58
  /**
59
59
  * The current populated values for the sub-command.
60
60
  */
61
- populatedArgumentValues: PopulatedArgumentValues;
61
+ populatedArgumentValues: PopulatedValues;
62
62
 
63
63
  /**
64
64
  * Current parse state.
@@ -163,9 +163,9 @@ class ParseContext {
163
163
  const complexAndArrayPathElements: Array<string | number> = [];
164
164
  let option: Option | ComplexOption | undefined = undefined;
165
165
  let currentValue:
166
- | PopulatedArgumentValues
167
- | Array<PopulatedArgumentValues | PopulatedArgumentValueType>
168
- | PopulatedArgumentValueType
166
+ | PopulatedValues
167
+ | Array<PopulatedValues | PopulatedValueType>
168
+ | PopulatedValueType
169
169
  | undefined = this.populatedArgumentValues;
170
170
 
171
171
  for (let i = 0; i < complexPathElements.length; i++) {
@@ -277,10 +277,10 @@ class ParseContext {
277
277
  return false;
278
278
  }
279
279
 
280
- if ((currentValue as PopulatedArgumentValues)[complexPathElement] === undefined) {
280
+ if ((currentValue as PopulatedValues)[complexPathElement] === undefined) {
281
281
  // ensure we have a placeholder value
282
282
  if (option.isArray) {
283
- currentValue = (currentValue as PopulatedArgumentValues)[complexPathElement] = [];
283
+ currentValue = (currentValue as PopulatedValues)[complexPathElement] = [];
284
284
 
285
285
  if (isComplexOption(option)) {
286
286
  // if we are retrieving a property by name only use the last entry in the array by default
@@ -292,12 +292,10 @@ class ParseContext {
292
292
  currentValue = currentValue[index] = {};
293
293
  }
294
294
  } else if (isComplexOption(option)) {
295
- currentValue = (currentValue as PopulatedArgumentValues)[complexPathElement] = {};
295
+ currentValue = (currentValue as PopulatedValues)[complexPathElement] = {};
296
296
  }
297
297
  } else {
298
- currentValue = (currentValue as PopulatedArgumentValues)[
299
- complexPathElement
300
- ] as PopulatedArgumentValues;
298
+ currentValue = (currentValue as PopulatedValues)[complexPathElement] as PopulatedValues;
301
299
  if (Array.isArray(currentValue)) {
302
300
  // if we are retrieving a property by name only use the last entry in the array by default
303
301
  // (this is the scenario when array indices are implicit)
@@ -354,11 +352,9 @@ class ParseContext {
354
352
  * @return `false` if there is a problem populating the value, in which case the {@link state} will be set to
355
353
  * {@link ParseState.ERROR} and {@link invalidArgument} will be populated.
356
354
  */
357
- setOptionValue(value: ArgumentSingleValueType): boolean {
358
- let optionValue:
359
- | Array<PopulatedArgumentValues>
360
- | PopulatedArgumentValues
361
- | PopulatedArgumentValueType = this.populatedArgumentValues;
355
+ setOptionValue(value: SingleValueType): boolean {
356
+ let optionValue: Array<PopulatedValues> | PopulatedValues | PopulatedValueType =
357
+ this.populatedArgumentValues;
362
358
  const optionPath = this.currentOptionPath as Array<string | number>;
363
359
 
364
360
  // traverse the current populated values using the validated option path elements
@@ -368,11 +364,11 @@ class ParseContext {
368
364
  // if on last path element, set the value
369
365
  if (i === optionPath.length - 1) {
370
366
  if (typeof pathElement === "string") {
371
- const currentValue = (optionValue as PopulatedArgumentValues)[pathElement as string];
367
+ const currentValue = (optionValue as PopulatedValues)[pathElement as string];
372
368
 
373
369
  // if we haven't populated the argument value before...
374
370
  if (currentValue === undefined) {
375
- (optionValue as PopulatedArgumentValues)[pathElement as string] = value;
371
+ (optionValue as PopulatedValues)[pathElement as string] = value;
376
372
  } // if we have already populated the argument value as an array...
377
373
  else if (Array.isArray(currentValue)) {
378
374
  if (currentValue.length === MAXIMUM_ARGUMENT_ARRAY_SIZE) {
@@ -385,7 +381,7 @@ class ParseContext {
385
381
  return false;
386
382
  }
387
383
  // push the new value
388
- (currentValue as Array<PopulatedArgumentSingleValueType>).push(value);
384
+ (currentValue as Array<PopulatedSingleValueType>).push(value);
389
385
  } // else the value to add would make an array where it is not allowed
390
386
  else {
391
387
  this.invalidArgument = {
@@ -398,30 +394,29 @@ class ParseContext {
398
394
  }
399
395
  } else {
400
396
  // set the new value on the array
401
- (optionValue as Array<PopulatedArgumentValueType | PopulatedArgumentValues>)[
402
- pathElement as number
403
- ] = value;
397
+ (optionValue as Array<PopulatedValueType | PopulatedValues>)[pathElement as number] =
398
+ value;
404
399
  }
405
400
  } // otherwise continue to navigate the path
406
401
  else {
407
402
  if (typeof pathElement === "string") {
408
403
  if (Array.isArray(optionValue)) {
409
- optionValue = (optionValue as Array<PopulatedArgumentValues>)[
410
- (optionValue as Array<PopulatedArgumentValues>).length - 1
404
+ optionValue = (optionValue as Array<PopulatedValues>)[
405
+ (optionValue as Array<PopulatedValues>).length - 1
411
406
  ]![pathElement as string] as
412
- | Array<PopulatedArgumentValues>
413
- | PopulatedArgumentValues
414
- | PopulatedArgumentValueType;
407
+ | Array<PopulatedValues>
408
+ | PopulatedValues
409
+ | PopulatedValueType;
415
410
  } else {
416
- optionValue = (optionValue as PopulatedArgumentValues)[pathElement as string] as
417
- | Array<PopulatedArgumentValues>
418
- | PopulatedArgumentValues
419
- | PopulatedArgumentValueType;
411
+ optionValue = (optionValue as PopulatedValues)[pathElement as string] as
412
+ | Array<PopulatedValues>
413
+ | PopulatedValues
414
+ | PopulatedValueType;
420
415
  }
421
416
  } else {
422
- optionValue = (
423
- optionValue as Array<PopulatedArgumentSingleValueType | PopulatedArgumentValues>
424
- )[pathElement as number];
417
+ optionValue = (optionValue as Array<PopulatedSingleValueType | PopulatedValues>)[
418
+ pathElement as number
419
+ ];
425
420
  }
426
421
  }
427
422
  }
@@ -441,7 +436,7 @@ class ParseContext {
441
436
  *
442
437
  * @param value the value to attempt to set.
443
438
  */
444
- setPositionalValue(value: ArgumentSingleValueType): boolean {
439
+ setPositionalValue(value: SingleValueType): boolean {
445
440
  const positional = this.subCommand.positionals[this.currentPositionalIndex]!;
446
441
  const currentValue = this.populatedArgumentValues[positional.name];
447
442
 
@@ -465,9 +460,9 @@ class ParseContext {
465
460
  return false;
466
461
  }
467
462
  this.populatedArgumentValues[positional.name] = [
468
- ...(currentValue as Array<PopulatedArgumentSingleValueType>),
463
+ ...(currentValue as Array<PopulatedSingleValueType>),
469
464
  value,
470
- ] as Array<PopulatedArgumentSingleValueType>;
465
+ ] as Array<PopulatedSingleValueType>;
471
466
  }
472
467
 
473
468
  // Update the state
@@ -493,7 +488,7 @@ class ParseContext {
493
488
  if (
494
489
  potentialArg !== "true" &&
495
490
  potentialArg !== "false" &&
496
- this.currentOption!.type === ArgumentValueTypeName.BOOLEAN
491
+ this.currentOption!.type === ValueTypeName.BOOLEAN
497
492
  ) {
498
493
  // Set the value to implicit value of true and return ony error.
499
494
  if (!this.setOptionValue("true")) {
@@ -582,16 +577,16 @@ class ParseContext {
582
577
  }
583
578
 
584
579
  /**
585
- * Populate {@link PopulatedArgumentValues} for the provided {@link SubCommand} using the provided potential args.
580
+ * Populate {@link PopulatedValues} for the provided {@link SubCommand} using the provided potential args.
586
581
  *
587
- * @param subCommand the {@link SubCommand} for which {@link PopulatedArgumentValues} values should be populated.
582
+ * @param subCommand the {@link SubCommand} for which {@link PopulatedValues} values should be populated.
588
583
  * @param potentialArgs the potential args to use for population.
589
- * @param defaultValues optional default {@link ArgumentValues} to use for population before parsing the provided arguments.
584
+ * @param defaultValues optional default {@link Values} to use for population before parsing the provided arguments.
590
585
  */
591
586
  export default function populateSubCommandValues(
592
587
  subCommand: SubCommand,
593
588
  potentialArgs: ReadonlyArray<string>,
594
- defaultValues: PopulatedArgumentValues | undefined,
589
+ defaultValues: PopulatedValues | undefined,
595
590
  ): SubCommandValuePopulationResult {
596
591
  logger.debug(() => {
597
592
  const message = `Populating values for sub-command: '${subCommand.name}' using potential args: ${potentialArgs.join(
@@ -629,7 +624,7 @@ export default function populateSubCommandValues(
629
624
  // Check if the last arg specified an option but no value
630
625
  if (parseContext.state === ParseState.OPTION_VALUE_EXPECTED) {
631
626
  // special case if the last arg was for a boolean option where the value was implicitly `true`
632
- if (parseContext.currentOption!.type === ArgumentValueTypeName.BOOLEAN) {
627
+ if (parseContext.currentOption!.type === ValueTypeName.BOOLEAN) {
633
628
  parseContext.setOptionValue("true");
634
629
  } else {
635
630
  parseContext.invalidArgument = {
@@ -9,11 +9,11 @@ import {
9
9
  import { InvalidArgumentReason } from "@flowscripter/dynamic-cli-framework-api";
10
10
  import type { InvalidArgument } from "@flowscripter/dynamic-cli-framework-api";
11
11
  import {
12
- type ArgumentSingleValueType,
13
- ArgumentValueTypeName,
12
+ type SingleValueType,
13
+ ValueTypeName,
14
14
  ComplexValueTypeName,
15
- type PopulatedArgumentSingleValueType,
16
- type PopulatedArgumentValues,
15
+ type PopulatedSingleValueType,
16
+ type PopulatedValues,
17
17
  } from "@flowscripter/dynamic-cli-framework-api";
18
18
  import type { Argument } from "@flowscripter/dynamic-cli-framework-api";
19
19
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
@@ -76,14 +76,14 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
76
76
  );
77
77
  const result = await this.#prompterService.prompt(prompt);
78
78
  const value = DefaultArgumentPrompterService.#coerceValue(
79
- result.value as ArgumentSingleValueType,
79
+ result.value as SingleValueType,
80
80
  command.argument.type,
81
81
  );
82
82
 
83
83
  return {
84
84
  command: parseResult.command,
85
85
  groupCommand: parseResult.groupCommand,
86
- populatedArgumentValues: value as PopulatedArgumentSingleValueType,
86
+ populatedArgumentValues: value as PopulatedSingleValueType,
87
87
  invalidArguments: [],
88
88
  unusedArgs: parseResult.unusedArgs,
89
89
  };
@@ -91,8 +91,8 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
91
91
 
92
92
  async #promptForSubCommand(parseResult: ParseResult): Promise<ParseResult> {
93
93
  const command = parseResult.command as SubCommand;
94
- const existingValues = (parseResult.populatedArgumentValues ?? {}) as PopulatedArgumentValues;
95
- const newValues: Record<string, PopulatedArgumentValues[string]> = {
94
+ const existingValues = (parseResult.populatedArgumentValues ?? {}) as PopulatedValues;
95
+ const newValues: Record<string, PopulatedValues[string]> = {
96
96
  ...existingValues,
97
97
  };
98
98
  const remainingInvalid: InvalidArgument[] = [];
@@ -129,7 +129,7 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
129
129
  );
130
130
  const result = await this.#prompterService.prompt(prompt);
131
131
  newValues[invalid.name] = DefaultArgumentPrompterService.#coerceValue(
132
- result.value as ArgumentSingleValueType,
132
+ result.value as SingleValueType,
133
133
  (arg as Argument).type,
134
134
  );
135
135
  }
@@ -138,7 +138,7 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
138
138
  return {
139
139
  command: parseResult.command,
140
140
  groupCommand: parseResult.groupCommand,
141
- populatedArgumentValues: newValues as PopulatedArgumentValues,
141
+ populatedArgumentValues: newValues as PopulatedValues,
142
142
  invalidArguments: remainingInvalid,
143
143
  unusedArgs: parseResult.unusedArgs,
144
144
  };
@@ -147,8 +147,8 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
147
147
  async #promptForComplexOption(
148
148
  name: string,
149
149
  complexOption: ComplexOption,
150
- ): Promise<PopulatedArgumentValues> {
151
- const values: Record<string, PopulatedArgumentValues[string]> = {};
150
+ ): Promise<PopulatedValues> {
151
+ const values: Record<string, PopulatedValues[string]> = {};
152
152
 
153
153
  for (const prop of complexOption.properties) {
154
154
  if ("type" in prop && (prop as ComplexOption).type === ComplexValueTypeName.COMPLEX) {
@@ -168,20 +168,20 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
168
168
  );
169
169
  const result = await this.#prompterService.prompt(prompt);
170
170
  values[option.name] = DefaultArgumentPrompterService.#coerceValue(
171
- result.value as ArgumentSingleValueType,
171
+ result.value as SingleValueType,
172
172
  option.type,
173
173
  );
174
174
  }
175
175
  }
176
176
 
177
- return values as PopulatedArgumentValues;
177
+ return values as PopulatedValues;
178
178
  }
179
179
 
180
180
  async #promptForArrayArgument(
181
181
  name: string,
182
182
  arg: Option | Positional,
183
- ): Promise<Array<ArgumentSingleValueType>> {
184
- const values: ArgumentSingleValueType[] = [];
183
+ ): Promise<Array<SingleValueType>> {
184
+ const values: SingleValueType[] = [];
185
185
 
186
186
  while (true) {
187
187
  const prompt = DefaultArgumentPrompterService.#argumentToPrompt(
@@ -192,7 +192,7 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
192
192
  const result = await this.#prompterService.prompt(prompt);
193
193
  values.push(
194
194
  DefaultArgumentPrompterService.#coerceValue(
195
- result.value as ArgumentSingleValueType,
195
+ result.value as SingleValueType,
196
196
  (arg as Argument).type,
197
197
  ),
198
198
  );
@@ -213,7 +213,7 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
213
213
  }
214
214
 
215
215
  static #argumentToPrompt(name: string, description: string, arg: Argument): Prompt {
216
- if (arg.type === ArgumentValueTypeName.BOOLEAN) {
216
+ if (arg.type === ValueTypeName.BOOLEAN) {
217
217
  return {
218
218
  name,
219
219
  promptText: description,
@@ -236,7 +236,7 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
236
236
  }
237
237
 
238
238
  const validationOption: PromptOption = {
239
- displayValue: arg.type === ArgumentValueTypeName.SECRET ? "__SECRET__" : name,
239
+ displayValue: arg.type === ValueTypeName.SECRET ? "__SECRET__" : name,
240
240
  returnedValue: "",
241
241
  min: arg.minValueInclusive,
242
242
  max: arg.maxValueInclusive,
@@ -251,17 +251,14 @@ export default class DefaultArgumentPrompterService implements ArgumentPrompterS
251
251
  };
252
252
  }
253
253
 
254
- static #coerceValue(
255
- value: ArgumentSingleValueType,
256
- type: ArgumentValueTypeName,
257
- ): ArgumentSingleValueType {
254
+ static #coerceValue(value: SingleValueType, type: ValueTypeName): SingleValueType {
258
255
  if (typeof value === "string") {
259
256
  switch (type) {
260
- case ArgumentValueTypeName.INTEGER:
257
+ case ValueTypeName.INTEGER:
261
258
  return parseInt(value, 10);
262
- case ArgumentValueTypeName.NUMBER:
259
+ case ValueTypeName.NUMBER:
263
260
  return parseFloat(value);
264
- case ArgumentValueTypeName.BOOLEAN:
261
+ case ValueTypeName.BOOLEAN:
265
262
  return value.toLowerCase() === "true";
266
263
  }
267
264
  }
@@ -1,8 +1,5 @@
1
1
  import type { GlobalModifierCommand } from "@flowscripter/dynamic-cli-framework-api";
2
- import {
3
- type ArgumentSingleValueType,
4
- ArgumentValueTypeName,
5
- } from "@flowscripter/dynamic-cli-framework-api";
2
+ import { type SingleValueType, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
6
3
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
7
4
  import type { GlobalCommandArgument } from "@flowscripter/dynamic-cli-framework-api";
8
5
  import type BannerServiceProvider from "../BannerServiceProvider.ts";
@@ -15,7 +12,7 @@ export default class NoBannerCommand implements GlobalModifierCommand {
15
12
  readonly description = "Disable output of banner";
16
13
  readonly enableConfiguration = true;
17
14
  readonly argument: GlobalCommandArgument = {
18
- type: ArgumentValueTypeName.BOOLEAN,
15
+ type: ValueTypeName.BOOLEAN,
19
16
  defaultValue: true,
20
17
  configurationKey: "NO_BANNER",
21
18
  };
@@ -28,7 +25,7 @@ export default class NoBannerCommand implements GlobalModifierCommand {
28
25
  this.executePriority = executePriority;
29
26
  }
30
27
 
31
- public execute(_context: Context, argumentValue: ArgumentSingleValueType): Promise<void> {
28
+ public execute(_context: Context, argumentValue: SingleValueType): Promise<void> {
32
29
  this.#bannerServiceProvider.printBanner = !(argumentValue as boolean);
33
30
 
34
31
  return Promise.resolve();
@@ -2,10 +2,7 @@ import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
2
2
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { Positional } from "@flowscripter/dynamic-cli-framework-api";
4
4
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
5
- import {
6
- type ArgumentValues,
7
- ArgumentValueTypeName,
8
- } from "@flowscripter/dynamic-cli-framework-api";
5
+ import { type Values, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
9
6
  import { COMPLETION_SERVICE_ID, ShellType } from "@flowscripter/dynamic-cli-framework-api";
10
7
  import type DefaultCompletionService from "../DefaultCompletionService.ts";
11
8
  import { PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
@@ -22,20 +19,20 @@ export class CompletionCompleteSubCommand implements SubCommand {
22
19
  readonly positionals: ReadonlyArray<Positional> = [
23
20
  {
24
21
  name: "shell",
25
- type: ArgumentValueTypeName.STRING,
22
+ type: ValueTypeName.STRING,
26
23
  allowableValues: Object.values(ShellType),
27
24
  description: "Shell type",
28
25
  },
29
26
  {
30
27
  name: "args",
31
- type: ArgumentValueTypeName.STRING,
28
+ type: ValueTypeName.STRING,
32
29
  isVarargMultiple: true,
33
30
  isVarargOptional: true,
34
31
  description: "Shell-specific completion context arguments",
35
32
  },
36
33
  ];
37
34
 
38
- async execute(context: Context, argumentValues: ArgumentValues): Promise<void> {
35
+ async execute(context: Context, argumentValues: Values): Promise<void> {
39
36
  const completionService = context.getServiceById(
40
37
  COMPLETION_SERVICE_ID,
41
38
  ) as DefaultCompletionService;
@@ -3,10 +3,7 @@ import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
4
4
  import type { Positional } from "@flowscripter/dynamic-cli-framework-api";
5
5
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
6
- import {
7
- type ArgumentValues,
8
- ArgumentValueTypeName,
9
- } from "@flowscripter/dynamic-cli-framework-api";
6
+ import { type Values, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
10
7
  import { COMPLETION_SERVICE_ID, ShellType } from "@flowscripter/dynamic-cli-framework-api";
11
8
  import type DefaultCompletionService from "../DefaultCompletionService.ts";
12
9
  import { Icon, PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
@@ -20,7 +17,7 @@ export class CompletionIntegrationSubCommand implements SubCommand {
20
17
  readonly options: ReadonlyArray<Option> = [
21
18
  {
22
19
  name: "config-path",
23
- type: ArgumentValueTypeName.STRING,
20
+ type: ValueTypeName.STRING,
24
21
  isOptional: true,
25
22
  description: "Path to shell configuration file",
26
23
  },
@@ -29,13 +26,13 @@ export class CompletionIntegrationSubCommand implements SubCommand {
29
26
  readonly positionals: ReadonlyArray<Positional> = [
30
27
  {
31
28
  name: "shell",
32
- type: ArgumentValueTypeName.STRING,
29
+ type: ValueTypeName.STRING,
33
30
  allowableValues: Object.values(ShellType),
34
31
  description: "Shell type to configure",
35
32
  },
36
33
  ];
37
34
 
38
- async execute(context: Context, argumentValues: ArgumentValues): Promise<void> {
35
+ async execute(context: Context, argumentValues: Values): Promise<void> {
39
36
  const completionService = context.getServiceById(
40
37
  COMPLETION_SERVICE_ID,
41
38
  ) as DefaultCompletionService;
@@ -5,10 +5,10 @@ import { Stats } from "node:fs";
5
5
  import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-framework-api";
6
6
  import ConfigCommand from "./command/ConfigCommand.ts";
7
7
  import type {
8
- ArgumentSingleValueType,
9
- ArgumentValues,
10
- PopulatedArgumentValues,
11
- PopulatedArgumentValueType,
8
+ SingleValueType,
9
+ Values,
10
+ PopulatedValues,
11
+ PopulatedValueType,
12
12
  } from "@flowscripter/dynamic-cli-framework-api";
13
13
  import getLogger from "../../util/logger.ts";
14
14
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
@@ -42,16 +42,16 @@ const logger = getLogger("ConfigurationServiceProvider");
42
42
  *
43
43
  * **Default Command Arguments**
44
44
  *
45
- * Configuration of default {@link ArgumentValues} for {@link Command} instances is supported if they
45
+ * Configuration of default {@link Values} for {@link Command} instances is supported if they
46
46
  * have defined {@link Command.enableConfiguration} as `true`.
47
47
  *
48
48
  * Two sources of configuration are supported and both are expected to be manually managed by the user of the CLI.
49
49
  *
50
50
  * *Configuration File*
51
51
  *
52
- * A JSON file where the structure matches {@link ArgumentValues} and the defaults are stored
52
+ * A JSON file where the structure matches {@link Values} and the defaults are stored
53
53
  * under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
54
- * and the contained values are treated as command {@link ArgumentValues}. As an example:
54
+ * and the contained values are treated as command {@link Values}. As an example:
55
55
  *
56
56
  * ```
57
57
  * {
@@ -178,9 +178,9 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
178
178
  public configLocation: string | undefined;
179
179
 
180
180
  // the configuration data to be used by the CLI runner implementation when setting command defaults.
181
- // ArgumentSingleValueType is for GlobalCommandArgument values, ArgumentValues is for
181
+ // SingleValueType is for GlobalCommandArgument values, Values is for
182
182
  // SubCommandArgument values.
183
- public defaultsData: Map<string, ArgumentValues | ArgumentSingleValueType> = new Map();
183
+ public defaultsData: Map<string, Values | SingleValueType> = new Map();
184
184
 
185
185
  // the configuration data to be used by the CLI runner implementation
186
186
  // when updating command scoped access to key-value data via the key-value service.
@@ -264,7 +264,7 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
264
264
  public async getDefaultArgumentValues(
265
265
  cliConfig: CLIConfig,
266
266
  command: Command,
267
- ): Promise<PopulatedArgumentValues | PopulatedArgumentValueType | undefined> {
267
+ ): Promise<PopulatedValues | PopulatedValueType | undefined> {
268
268
  if (!this.configEnabled) {
269
269
  logger.debug("configuration of default values is not enabled");
270
270
  return undefined;
@@ -277,17 +277,17 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
277
277
  return undefined;
278
278
  }
279
279
 
280
- let result: PopulatedArgumentValues | PopulatedArgumentValueType | undefined;
280
+ let result: PopulatedValues | PopulatedValueType | undefined;
281
281
 
282
282
  if (isGlobalModifierCommand(command) || isGlobalCommand(command)) {
283
- const configuredValue = this.defaultsData.get(command.name) as ArgumentSingleValueType;
283
+ const configuredValue = this.defaultsData.get(command.name) as SingleValueType;
284
284
  const envVarValue = this.envVarsEnabled
285
285
  ? getGlobalCommandValueFromEnvVars(cliConfig, command)
286
286
  : undefined;
287
287
  // default to environment variable value
288
288
  result = envVarValue !== undefined ? envVarValue : configuredValue;
289
289
  } else if (isSubCommand(command)) {
290
- const configuredValues = this.defaultsData.get(command.name) as ArgumentValues;
290
+ const configuredValues = this.defaultsData.get(command.name) as Values;
291
291
  const envVarValues = this.envVarsEnabled
292
292
  ? getSubCommandValuesFromEnvVars(cliConfig, command)
293
293
  : undefined;
@@ -296,7 +296,7 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
296
296
  } else if (configuredValues === undefined) {
297
297
  result = envVarValues;
298
298
  } else {
299
- result = argumentValueMerge(envVarValues, configuredValues) as PopulatedArgumentValues;
299
+ result = argumentValueMerge(envVarValues, configuredValues) as PopulatedValues;
300
300
  }
301
301
  }
302
302
 
@@ -308,8 +308,8 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
308
308
  }
309
309
 
310
310
  async #resolveSecrets(
311
- value: PopulatedArgumentValues | PopulatedArgumentValueType,
312
- ): Promise<PopulatedArgumentValues | PopulatedArgumentValueType> {
311
+ value: PopulatedValues | PopulatedValueType,
312
+ ): Promise<PopulatedValues | PopulatedValueType> {
313
313
  if (typeof value === "string" && value.startsWith(SECRET_SENTINEL_PREFIX)) {
314
314
  const bunSecretName = value.slice(SECRET_SENTINEL_PREFIX.length);
315
315
  const secretValue = await this.#defaultSecretService!.getSecret(bunSecretName);
@@ -324,13 +324,13 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
324
324
  for (const item of value) {
325
325
  resolved.push(await this.#resolveSecrets(item));
326
326
  }
327
- return resolved as unknown as PopulatedArgumentValues;
327
+ return resolved as unknown as PopulatedValues;
328
328
  }
329
329
  const resolved: Record<string, unknown> = {};
330
330
  for (const [key, val] of Object.entries(value)) {
331
- resolved[key] = await this.#resolveSecrets(val as PopulatedArgumentValueType);
331
+ resolved[key] = await this.#resolveSecrets(val as PopulatedValueType);
332
332
  }
333
- return resolved as unknown as PopulatedArgumentValues;
333
+ return resolved as unknown as PopulatedValues;
334
334
  }
335
335
  return value;
336
336
  }
@@ -496,7 +496,7 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
496
496
  if (config.defaults !== undefined) {
497
497
  const defaults = config.defaults;
498
498
  Object.keys(defaults).forEach((commandName) => {
499
- this.defaultsData.set(commandName, defaults[commandName] as ArgumentValues);
499
+ this.defaultsData.set(commandName, defaults[commandName] as Values);
500
500
  logger.debug("Set default argument values for command name: %s", commandName);
501
501
  });
502
502
  }
@@ -540,7 +540,7 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
540
540
 
541
541
  public getConfigString(): string {
542
542
  const config: {
543
- defaults?: Record<string, ArgumentValues | ArgumentSingleValueType>;
543
+ defaults?: Record<string, Values | SingleValueType>;
544
544
  "key-values"?: {
545
545
  commands?: Record<string, Record<string, string>>;
546
546
  services?: Record<string, Record<string, string>>;
@@ -1,9 +1,6 @@
1
1
  import type { GlobalModifierCommand } from "@flowscripter/dynamic-cli-framework-api";
2
2
  import type { GlobalCommandArgument } from "@flowscripter/dynamic-cli-framework-api";
3
- import {
4
- type ArgumentSingleValueType,
5
- ArgumentValueTypeName,
6
- } from "@flowscripter/dynamic-cli-framework-api";
3
+ import { type SingleValueType, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
7
4
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
8
5
  import type ConfigurationServiceProvider from "../ConfigurationServiceProvider.ts";
9
6
 
@@ -15,7 +12,7 @@ export default class ConfigCommand implements GlobalModifierCommand {
15
12
  readonly description = "Set the configuration file location";
16
13
  readonly enableConfiguration = true;
17
14
  readonly argument: GlobalCommandArgument = {
18
- type: ArgumentValueTypeName.STRING,
15
+ type: ValueTypeName.STRING,
19
16
  configurationKey: "CONFIG",
20
17
  };
21
18
  readonly executePriority: number;
@@ -30,7 +27,7 @@ export default class ConfigCommand implements GlobalModifierCommand {
30
27
  this.executePriority = executePriority;
31
28
  }
32
29
 
33
- public execute(_context: Context, argumentValue: ArgumentSingleValueType): Promise<void> {
30
+ public execute(_context: Context, argumentValue: SingleValueType): Promise<void> {
34
31
  const configLocation = argumentValue as string;
35
32
 
36
33
  this.#configurationServiceProvider.setConfigLocation(configLocation);
@@ -0,0 +1,55 @@
1
+ import type {
2
+ FetchOptions,
3
+ FetchService,
4
+ ShutdownService,
5
+ } from "@flowscripter/dynamic-cli-framework-api";
6
+ import getLogger from "../../util/logger.ts";
7
+
8
+ const logger = getLogger("DefaultFetchService");
9
+
10
+ export default class DefaultFetchService implements FetchService {
11
+ #shutdownService: ShutdownService | undefined;
12
+
13
+ public setDependencies(shutdownService: ShutdownService): void {
14
+ this.#shutdownService = shutdownService;
15
+ }
16
+
17
+ public async fetch(input: string | URL, options: FetchOptions = {}): Promise<Response> {
18
+ if (this.#shutdownService === undefined) {
19
+ throw new Error("DefaultFetchService.fetch() called before setDependencies()");
20
+ }
21
+ const shutdownService = this.#shutdownService;
22
+ const { timeoutMs, longRunning = false, signal: callerSignal, ...requestInit } = options;
23
+
24
+ const controller = new AbortController();
25
+ const signals: AbortSignal[] = [controller.signal];
26
+ if (callerSignal) {
27
+ signals.push(callerSignal);
28
+ }
29
+ if (timeoutMs !== undefined) {
30
+ signals.push(AbortSignal.timeout(timeoutMs));
31
+ }
32
+ const signal = signals.length === 1 ? signals[0]! : AbortSignal.any(signals);
33
+
34
+ let settled = false;
35
+ if (longRunning) {
36
+ shutdownService.enterLongRunningMode();
37
+ shutdownService.addShutdownListener(async () => {
38
+ if (settled) {
39
+ return;
40
+ }
41
+ logger.debug(() => `Aborting fetch of '${input.toString()}' due to shutdown`);
42
+ controller.abort();
43
+ });
44
+ }
45
+
46
+ try {
47
+ return await fetch(input, { ...requestInit, signal });
48
+ } finally {
49
+ settled = true;
50
+ if (longRunning) {
51
+ shutdownService.leaveLongRunningMode();
52
+ }
53
+ }
54
+ }
55
+ }