@flowscripter/dynamic-cli-framework 2.5.0 → 3.0.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.
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/src/command/MultiCommandCliHelpCommand.d.ts +4 -4
- package/dist/src/command/MultiCommandCliHelpCommand.d.ts.map +1 -1
- package/dist/src/command/MultiCommandCliHelpCommand.js +3 -3
- package/dist/src/runtime/command/CommandValidator.d.ts.map +1 -1
- package/dist/src/runtime/command/CommandValidator.js +14 -16
- package/dist/src/runtime/parser.d.ts +5 -5
- package/dist/src/runtime/parser.d.ts.map +1 -1
- package/dist/src/runtime/parser.js +2 -2
- package/dist/src/runtime/runner.d.ts.map +1 -1
- package/dist/src/runtime/values/ValuePopulationResult.d.ts +3 -3
- package/dist/src/runtime/values/ValuePopulationResult.d.ts.map +1 -1
- package/dist/src/runtime/values/argumentValueMerge.d.ts +2 -2
- package/dist/src/runtime/values/argumentValueMerge.d.ts.map +1 -1
- package/dist/src/runtime/values/argumentValueValidation.d.ts +4 -4
- package/dist/src/runtime/values/argumentValueValidation.d.ts.map +1 -1
- package/dist/src/runtime/values/argumentValueValidation.js +6 -6
- package/dist/src/runtime/values/globalCommandValuePopulation.d.ts +4 -4
- package/dist/src/runtime/values/globalCommandValuePopulation.d.ts.map +1 -1
- package/dist/src/runtime/values/globalCommandValuePopulation.js +5 -5
- package/dist/src/runtime/values/subCommandValuePopulation.d.ts +5 -5
- package/dist/src/runtime/values/subCommandValuePopulation.d.ts.map +1 -1
- package/dist/src/runtime/values/subCommandValuePopulation.js +8 -7
- package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.d.ts.map +1 -1
- package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.js +6 -6
- package/dist/src/service/banner/command/NoBannerCommand.d.ts +2 -2
- package/dist/src/service/banner/command/NoBannerCommand.d.ts.map +1 -1
- package/dist/src/service/banner/command/NoBannerCommand.js +2 -2
- package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts +2 -2
- package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts.map +1 -1
- package/dist/src/service/completion/command/CompletionCompleteSubCommand.js +3 -3
- package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts +2 -2
- package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts.map +1 -1
- package/dist/src/service/completion/command/CompletionIntegrationSubCommand.js +3 -3
- package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts +6 -6
- package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts.map +1 -1
- package/dist/src/service/configuration/ConfigurationServiceProvider.js +4 -4
- package/dist/src/service/configuration/command/ConfigCommand.d.ts +2 -2
- package/dist/src/service/configuration/command/ConfigCommand.d.ts.map +1 -1
- package/dist/src/service/configuration/command/ConfigCommand.js +2 -2
- package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts +4 -4
- package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginAddSubCommand.js +2 -2
- package/dist/src/service/plugin/command/PluginListSubCommand.d.ts +2 -2
- package/dist/src/service/plugin/command/PluginListSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts +4 -4
- package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginRemoveSubCommand.js +2 -2
- package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts +4 -4
- package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginSearchSubCommand.js +2 -2
- package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts +2 -2
- package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts.map +1 -1
- package/dist/src/service/printer/command/DarkModeCommand.d.ts +2 -2
- package/dist/src/service/printer/command/DarkModeCommand.d.ts.map +1 -1
- package/dist/src/service/printer/command/DarkModeCommand.js +2 -2
- package/dist/src/service/printer/command/LogLevelCommand.d.ts +2 -2
- package/dist/src/service/printer/command/LogLevelCommand.d.ts.map +1 -1
- package/dist/src/service/printer/command/LogLevelCommand.js +2 -2
- package/dist/src/service/printer/command/NoColorCommand.d.ts +2 -2
- package/dist/src/service/printer/command/NoColorCommand.d.ts.map +1 -1
- package/dist/src/service/printer/command/NoColorCommand.js +2 -2
- package/dist/src/service/printer/command/NoHyperlinksCommand.d.ts +2 -2
- package/dist/src/service/printer/command/NoHyperlinksCommand.d.ts.map +1 -1
- package/dist/src/service/printer/command/NoHyperlinksCommand.js +2 -2
- package/dist/src/service/prompter/command/NoPromptCommand.d.ts +2 -2
- package/dist/src/service/prompter/command/NoPromptCommand.d.ts.map +1 -1
- package/dist/src/service/prompter/command/NoPromptCommand.js +2 -2
- package/dist/src/service/upgrade/DefaultUpgradeService.d.ts.map +1 -1
- package/dist/src/service/upgrade/DefaultUpgradeService.js +11 -1
- package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts +2 -2
- package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts.map +1 -1
- package/dist/src/service/upgrade/command/UpgradeSubCommand.js +3 -3
- package/dist/src/util/envVarHelper.d.ts +3 -3
- package/dist/src/util/envVarHelper.d.ts.map +1 -1
- package/dist/src/util/envVarHelper.js +9 -12
- package/dist/src/util/helpHelper.d.ts.map +1 -1
- package/dist/src/util/helpHelper.js +27 -28
- package/index.ts +7 -10
- package/package.json +2 -2
- package/src/command/MultiCommandCliHelpCommand.ts +7 -7
- package/src/runtime/command/CommandValidator.ts +17 -26
- package/src/runtime/parser.ts +8 -8
- package/src/runtime/runner.ts +16 -19
- package/src/runtime/values/ValuePopulationResult.ts +4 -4
- package/src/runtime/values/argumentValueMerge.ts +33 -50
- package/src/runtime/values/argumentValueValidation.ts +38 -52
- package/src/runtime/values/globalCommandValuePopulation.ts +7 -7
- package/src/runtime/values/subCommandValuePopulation.ts +42 -47
- package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +23 -26
- package/src/service/banner/command/NoBannerCommand.ts +3 -6
- package/src/service/completion/command/CompletionCompleteSubCommand.ts +4 -7
- package/src/service/completion/command/CompletionIntegrationSubCommand.ts +4 -7
- package/src/service/configuration/ConfigurationServiceProvider.ts +21 -21
- package/src/service/configuration/command/ConfigCommand.ts +3 -6
- package/src/service/plugin/command/PluginAddSubCommand.ts +4 -4
- package/src/service/plugin/command/PluginListSubCommand.ts +2 -2
- package/src/service/plugin/command/PluginRemoveSubCommand.ts +4 -4
- package/src/service/plugin/command/PluginSearchSubCommand.ts +4 -4
- package/src/service/plugin/command/PluginUpgradeSubCommand.ts +2 -2
- package/src/service/printer/command/DarkModeCommand.ts +3 -6
- package/src/service/printer/command/LogLevelCommand.ts +3 -6
- package/src/service/printer/command/NoColorCommand.ts +3 -6
- package/src/service/printer/command/NoHyperlinksCommand.ts +3 -6
- package/src/service/prompter/command/NoPromptCommand.ts +3 -6
- package/src/service/prompter/prompt/promptText.ts +2 -2
- package/src/service/upgrade/DefaultUpgradeService.ts +11 -1
- package/src/service/upgrade/command/UpgradeSubCommand.ts +4 -7
- package/src/util/envVarHelper.ts +23 -26
- 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
|
|
5
|
-
|
|
6
|
-
type
|
|
7
|
-
type
|
|
8
|
-
type
|
|
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:
|
|
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
|
-
|
|
|
167
|
-
| Array<
|
|
168
|
-
|
|
|
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
|
|
280
|
+
if ((currentValue as PopulatedValues)[complexPathElement] === undefined) {
|
|
281
281
|
// ensure we have a placeholder value
|
|
282
282
|
if (option.isArray) {
|
|
283
|
-
currentValue = (currentValue as
|
|
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
|
|
295
|
+
currentValue = (currentValue as PopulatedValues)[complexPathElement] = {};
|
|
296
296
|
}
|
|
297
297
|
} else {
|
|
298
|
-
currentValue = (currentValue as
|
|
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:
|
|
358
|
-
let optionValue:
|
|
359
|
-
|
|
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
|
|
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
|
|
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<
|
|
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<
|
|
402
|
-
|
|
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<
|
|
410
|
-
(optionValue as Array<
|
|
404
|
+
optionValue = (optionValue as Array<PopulatedValues>)[
|
|
405
|
+
(optionValue as Array<PopulatedValues>).length - 1
|
|
411
406
|
]![pathElement as string] as
|
|
412
|
-
| Array<
|
|
413
|
-
|
|
|
414
|
-
|
|
|
407
|
+
| Array<PopulatedValues>
|
|
408
|
+
| PopulatedValues
|
|
409
|
+
| PopulatedValueType;
|
|
415
410
|
} else {
|
|
416
|
-
optionValue = (optionValue as
|
|
417
|
-
| Array<
|
|
418
|
-
|
|
|
419
|
-
|
|
|
411
|
+
optionValue = (optionValue as PopulatedValues)[pathElement as string] as
|
|
412
|
+
| Array<PopulatedValues>
|
|
413
|
+
| PopulatedValues
|
|
414
|
+
| PopulatedValueType;
|
|
420
415
|
}
|
|
421
416
|
} else {
|
|
422
|
-
optionValue = (
|
|
423
|
-
|
|
424
|
-
|
|
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:
|
|
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<
|
|
463
|
+
...(currentValue as Array<PopulatedSingleValueType>),
|
|
469
464
|
value,
|
|
470
|
-
] as Array<
|
|
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 ===
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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 ===
|
|
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
|
|
13
|
-
|
|
12
|
+
type SingleValueType,
|
|
13
|
+
ValueTypeName,
|
|
14
14
|
ComplexValueTypeName,
|
|
15
|
-
type
|
|
16
|
-
type
|
|
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
|
|
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
|
|
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
|
|
95
|
-
const newValues: Record<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
|
|
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
|
|
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<
|
|
151
|
-
const values: Record<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
|
|
171
|
+
result.value as SingleValueType,
|
|
172
172
|
option.type,
|
|
173
173
|
);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
return values as
|
|
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<
|
|
184
|
-
const values:
|
|
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
|
|
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 ===
|
|
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 ===
|
|
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
|
|
257
|
+
case ValueTypeName.INTEGER:
|
|
261
258
|
return parseInt(value, 10);
|
|
262
|
-
case
|
|
259
|
+
case ValueTypeName.NUMBER:
|
|
263
260
|
return parseFloat(value);
|
|
264
|
-
case
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
//
|
|
181
|
+
// SingleValueType is for GlobalCommandArgument values, Values is for
|
|
182
182
|
// SubCommandArgument values.
|
|
183
|
-
public defaultsData: Map<string,
|
|
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<
|
|
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:
|
|
280
|
+
let result: PopulatedValues | PopulatedValueType | undefined;
|
|
281
281
|
|
|
282
282
|
if (isGlobalModifierCommand(command) || isGlobalCommand(command)) {
|
|
283
|
-
const configuredValue = this.defaultsData.get(command.name) as
|
|
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
|
|
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
|
|
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:
|
|
312
|
-
): Promise<
|
|
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
|
|
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
|
|
331
|
+
resolved[key] = await this.#resolveSecrets(val as PopulatedValueType);
|
|
332
332
|
}
|
|
333
|
-
return resolved as unknown as
|
|
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
|
|
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,
|
|
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:
|
|
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:
|
|
30
|
+
public execute(_context: Context, argumentValue: SingleValueType): Promise<void> {
|
|
34
31
|
const configLocation = argumentValue as string;
|
|
35
32
|
|
|
36
33
|
this.#configurationServiceProvider.setConfigLocation(configLocation);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
3
|
+
import type { Values } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
|
+
import { ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
5
|
import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
6
|
import { Icon, PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
7
7
|
import { PLUGIN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -18,11 +18,11 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
18
18
|
{
|
|
19
19
|
name: "pluginId",
|
|
20
20
|
description: "Plugin ID to install (e.g. @scope/name)",
|
|
21
|
-
type:
|
|
21
|
+
type: ValueTypeName.STRING,
|
|
22
22
|
},
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
-
async execute(context: Context, argumentValues:
|
|
25
|
+
async execute(context: Context, argumentValues: Values): Promise<void> {
|
|
26
26
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
27
27
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID) as PluginService;
|
|
28
28
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Values } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
4
|
import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
5
|
import { PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
6
|
import { PLUGIN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -14,7 +14,7 @@ export class PluginListSubCommand implements SubCommand {
|
|
|
14
14
|
readonly options = [];
|
|
15
15
|
readonly positionals = [];
|
|
16
16
|
|
|
17
|
-
async execute(context: Context, _argumentValues:
|
|
17
|
+
async execute(context: Context, _argumentValues: Values): Promise<void> {
|
|
18
18
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
19
19
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID) as PluginService;
|
|
20
20
|
|