@flowscripter/dynamic-cli-framework 9.1.3 → 10.1.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.
- package/dist/src/command/MultiCommandCliHelpCommand.d.ts.map +1 -1
- package/dist/src/command/MultiCommandCliHelpCommand.js +1 -1
- package/dist/src/runtime/command/CommandValidator.d.ts.map +1 -1
- package/dist/src/runtime/command/CommandValidator.js +9 -2
- package/dist/src/runtime/parser.d.ts +8 -2
- package/dist/src/runtime/parser.d.ts.map +1 -1
- package/dist/src/runtime/parser.js +11 -6
- package/dist/src/runtime/runner.d.ts.map +1 -1
- package/dist/src/runtime/runner.js +5 -2
- package/dist/src/runtime/values/ValuePopulationResult.d.ts +4 -0
- package/dist/src/runtime/values/ValuePopulationResult.d.ts.map +1 -1
- package/dist/src/runtime/values/globalCommandValuePopulation.d.ts.map +1 -1
- package/dist/src/runtime/values/globalCommandValuePopulation.js +11 -3
- package/dist/src/runtime/values/subCommandValuePopulation.d.ts.map +1 -1
- package/dist/src/runtime/values/subCommandValuePopulation.js +39 -9
- package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts +12 -3
- package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts.map +1 -1
- package/dist/src/service/configuration/ConfigurationServiceProvider.js +16 -7
- package/dist/src/util/configHelper.d.ts +4 -1
- package/dist/src/util/configHelper.d.ts.map +1 -1
- package/dist/src/util/configHelper.js +6 -1
- package/dist/src/util/envVarHelper.d.ts +4 -1
- package/dist/src/util/envVarHelper.d.ts.map +1 -1
- package/dist/src/util/envVarHelper.js +8 -5
- package/dist/src/util/helpHelper.d.ts +1 -1
- package/dist/src/util/helpHelper.d.ts.map +1 -1
- package/dist/src/util/helpHelper.js +8 -16
- package/dist/src/util/runnerHelper.d.ts +2 -0
- package/dist/src/util/runnerHelper.d.ts.map +1 -1
- package/dist/src/util/runnerHelper.js +10 -0
- package/dist/src/util/secretRedaction.d.ts +11 -0
- package/dist/src/util/secretRedaction.d.ts.map +1 -0
- package/dist/src/util/secretRedaction.js +45 -0
- package/package.json +1 -1
- package/src/command/MultiCommandCliHelpCommand.ts +7 -1
- package/src/runtime/command/CommandValidator.ts +8 -1
- package/src/runtime/parser.ts +22 -16
- package/src/runtime/runner.ts +5 -0
- package/src/runtime/values/ValuePopulationResult.ts +5 -0
- package/src/runtime/values/globalCommandValuePopulation.ts +12 -5
- package/src/runtime/values/subCommandValuePopulation.ts +47 -12
- package/src/service/configuration/ConfigurationServiceProvider.ts +18 -6
- package/src/util/configHelper.ts +7 -0
- package/src/util/envVarHelper.ts +19 -3
- package/src/util/helpHelper.ts +34 -13
- package/src/util/runnerHelper.ts +18 -0
- package/src/util/secretRedaction.ts +81 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiCommandCliHelpCommand.d.ts","sourceRoot":"","sources":["../../../src/command/MultiCommandCliHelpCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,aAAa,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAYvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAM/E;;GAEG;AACH,uBAAe,kCAAkC;;IAC/C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,8BAA8B;IAIlD,YAAY,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAGpE;IA8HD,UAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ChE;IAED,UAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"MultiCommandCliHelpCommand.d.ts","sourceRoot":"","sources":["../../../src/command/MultiCommandCliHelpCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,aAAa,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAYvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAM/E;;GAEG;AACH,uBAAe,kCAAkC;;IAC/C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,8BAA8B;IAIlD,YAAY,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAGpE;IA8HD,UAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ChE;IAED,UAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFnF;CACF;AAED;;GAEG;AACH,qBAAa,gCACX,SAAQ,kCACR,YAAW,aAAa;IAExB,QAAQ,CAAC,UAAU,OAAO;IAE1B,QAAQ,CAAC,QAAQ;;;;MAIf;IAEW,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAOrF;CACF;AAED;;GAEG;AACH,qBAAa,6BACX,SAAQ,kCACR,YAAW,UAAU;IAErB,SAAgB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM;IAEpD,SAAgB,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAOpD;IAEW,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5E;CACF"}
|
|
@@ -188,7 +188,7 @@ class MultiCommandCliAbstractHelpCommand {
|
|
|
188
188
|
},
|
|
189
189
|
],
|
|
190
190
|
});
|
|
191
|
-
helpSections.push(...getCommandArgsHelpSections(context.cliConfig, this.#includeEnvVars, subCommand, false));
|
|
191
|
+
helpSections.push(...getCommandArgsHelpSections(context.cliConfig, this.#includeEnvVars, subCommand, false, groupCommand));
|
|
192
192
|
helpSections.push(...getCommandExamplesHelpSections(printerService, context, subCommand));
|
|
193
193
|
await printHelpSections(printerService, tableGeneratorService, helpSections);
|
|
194
194
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandValidator.d.ts","sourceRoot":"","sources":["../../../../src/runtime/command/CommandValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAiBvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmJzE,MAAM,CAAC,OAAO,OAAO,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"CommandValidator.d.ts","sourceRoot":"","sources":["../../../../src/runtime/command/CommandValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAiBvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmJzE,MAAM,CAAC,OAAO,OAAO,gBAAgB;;IAKnC,YAAmB,SAAS,EAAE,SAAS,EAEtC;IAED;;;;;;OAMG;IACI,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUtC;CAsWF"}
|
|
@@ -97,6 +97,7 @@ function validateSubCommandArgument(subCommandArgument) {
|
|
|
97
97
|
export default class CommandValidator {
|
|
98
98
|
#cliConfig;
|
|
99
99
|
#configurationKeys = [];
|
|
100
|
+
#currentGroupCommand;
|
|
100
101
|
constructor(cliConfig) {
|
|
101
102
|
this.#cliConfig = cliConfig;
|
|
102
103
|
}
|
|
@@ -184,7 +185,13 @@ export default class CommandValidator {
|
|
|
184
185
|
throw new Error(`Group command: '${groupCommand.name}' contains member sub-command with the same name`);
|
|
185
186
|
}
|
|
186
187
|
subCommandNames.push(subCommand.name);
|
|
187
|
-
this.#
|
|
188
|
+
this.#currentGroupCommand = groupCommand;
|
|
189
|
+
try {
|
|
190
|
+
this.#validateSubCommand(subCommand);
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
this.#currentGroupCommand = undefined;
|
|
194
|
+
}
|
|
188
195
|
});
|
|
189
196
|
}
|
|
190
197
|
/**
|
|
@@ -254,7 +261,7 @@ export default class CommandValidator {
|
|
|
254
261
|
!isConfigurationKeyLegal(argument.configurationKey)) {
|
|
255
262
|
throw new Error(`Illegal configuration key: '${argument.configurationKey}'`);
|
|
256
263
|
}
|
|
257
|
-
const configurationKey = getSubCommandArgumentConfigurationKey(this.#cliConfig, command, argumentAncestry);
|
|
264
|
+
const configurationKey = getSubCommandArgumentConfigurationKey(this.#cliConfig, command, argumentAncestry, this.#currentGroupCommand);
|
|
258
265
|
if (configurationKey !== undefined) {
|
|
259
266
|
if (this.#configurationKeys.includes(configurationKey)) {
|
|
260
267
|
throw new Error(`Command: '${command.name}' contains arguments with the same configuration key: '${configurationKey}'`);
|
|
@@ -2,18 +2,24 @@ import type { PopulatedSingleValueType, PopulatedValues } from "@flowscripter/dy
|
|
|
2
2
|
import type { ParseResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import type { CommandClause } from "./scanner.ts";
|
|
4
4
|
export type { ParseResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
|
+
/**
|
|
6
|
+
* A {@link ParseResult} which also reports any SECRET arguments supplied as plain command line arguments.
|
|
7
|
+
*/
|
|
8
|
+
export type SecretAwareParseResult = ParseResult & {
|
|
9
|
+
readonly secretArgumentNames?: ReadonlyArray<string>;
|
|
10
|
+
};
|
|
5
11
|
/**
|
|
6
12
|
* Parse the arguments for the specified {@link CommandClause} assuming it contains a {@link SubCommand}.
|
|
7
13
|
*
|
|
8
14
|
* @param commandClause the clause to parse.
|
|
9
15
|
* @param defaultValues optional default {@link PopulatedValues} to use for population before parsing the provided arguments.
|
|
10
16
|
*/
|
|
11
|
-
export declare function parseSubCommandClause(commandClause: CommandClause, defaultValues?: PopulatedValues):
|
|
17
|
+
export declare function parseSubCommandClause(commandClause: CommandClause, defaultValues?: PopulatedValues): SecretAwareParseResult;
|
|
12
18
|
/**
|
|
13
19
|
* Parse the arguments for the specified {@link CommandClause} assuming it contains a {@link GlobalCommand} or {@link GlobalModifierCommand}.
|
|
14
20
|
*
|
|
15
21
|
* @param commandClause the clause to parse.
|
|
16
22
|
* @param defaultValue optional default {@link PopulatedSingleValueType} to use for population before parsing the provided arguments.
|
|
17
23
|
*/
|
|
18
|
-
export declare function parseGlobalCommandClause(commandClause: CommandClause, defaultValue?: PopulatedSingleValueType):
|
|
24
|
+
export declare function parseGlobalCommandClause(commandClause: CommandClause, defaultValue?: PopulatedSingleValueType): SecretAwareParseResult;
|
|
19
25
|
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/runtime/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,eAAe,EAChB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/runtime/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,eAAe,EAChB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAelD,YAAY,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,WAAW,GAAG;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACtD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,aAAa,EAC5B,aAAa,CAAC,EAAE,eAAe,GAC9B,sBAAsB,CAiFxB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,wBAAwB,GACtC,sBAAsB,CAwDxB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import populateGlobalCommandValue from "./values/globalCommandValuePopulation.js";
|
|
2
2
|
import { validateGlobalCommandArgumentValue, validateOptionValue, validatePositionalValue, } from "./values/argumentValueValidation.js";
|
|
3
3
|
import getLogger from "../util/logger.js";
|
|
4
|
+
import { redactGlobalCommandValue, redactSubCommandValues } from "../util/secretRedaction.js";
|
|
4
5
|
import populateSubCommandValues from "./values/subCommandValuePopulation.js";
|
|
5
6
|
const logger = getLogger("parser");
|
|
6
7
|
/**
|
|
@@ -24,7 +25,7 @@ export function parseSubCommandClause(commandClause, defaultValues) {
|
|
|
24
25
|
unusedArgs: potentialArgs,
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
|
-
const { populatedArgumentValues, unusedArgs, invalidArgument } = populateSubCommandValues(command, potentialArgs, defaultValues);
|
|
28
|
+
const { populatedArgumentValues, unusedArgs, invalidArgument, secretArgumentNames } = populateSubCommandValues(command, potentialArgs, defaultValues);
|
|
28
29
|
if (invalidArgument) {
|
|
29
30
|
invalidArguments.push(invalidArgument);
|
|
30
31
|
}
|
|
@@ -36,7 +37,7 @@ export function parseSubCommandClause(commandClause, defaultValues) {
|
|
|
36
37
|
populatedArgumentValues[option.name] = validatedValue;
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
|
-
logger.debug("Command arguments after options validated: %O with invalid args: %O", populatedArgumentValues, invalidArguments);
|
|
40
|
+
logger.debug("Command arguments after options validated: %O with invalid args: %O", redactSubCommandValues(command, populatedArgumentValues), invalidArguments);
|
|
40
41
|
if (invalidArguments.length === 0) {
|
|
41
42
|
// validate the positional values
|
|
42
43
|
command.positionals.forEach((positional) => {
|
|
@@ -45,9 +46,10 @@ export function parseSubCommandClause(commandClause, defaultValues) {
|
|
|
45
46
|
populatedArgumentValues[positional.name] = validatedValue;
|
|
46
47
|
}
|
|
47
48
|
});
|
|
48
|
-
logger.debug("Command arguments after positionals validated: %O with invalid args: %O", populatedArgumentValues, invalidArguments);
|
|
49
|
+
logger.debug("Command arguments after positionals validated: %O with invalid args: %O", redactSubCommandValues(command, populatedArgumentValues), invalidArguments);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
52
|
+
const secrets = secretArgumentNames ? { secretArgumentNames } : {};
|
|
51
53
|
if (groupCommand) {
|
|
52
54
|
return {
|
|
53
55
|
command,
|
|
@@ -55,6 +57,7 @@ export function parseSubCommandClause(commandClause, defaultValues) {
|
|
|
55
57
|
groupCommand,
|
|
56
58
|
invalidArguments,
|
|
57
59
|
unusedArgs,
|
|
60
|
+
...secrets,
|
|
58
61
|
};
|
|
59
62
|
}
|
|
60
63
|
return {
|
|
@@ -62,6 +65,7 @@ export function parseSubCommandClause(commandClause, defaultValues) {
|
|
|
62
65
|
populatedArgumentValues,
|
|
63
66
|
invalidArguments,
|
|
64
67
|
unusedArgs: unusedArgs,
|
|
68
|
+
...secrets,
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
/**
|
|
@@ -83,11 +87,11 @@ export function parseGlobalCommandClause(commandClause, defaultValue) {
|
|
|
83
87
|
unusedArgs: potentialArgs,
|
|
84
88
|
};
|
|
85
89
|
}
|
|
86
|
-
let { populatedArgumentValue, unusedArgs, invalidArgument } = populateGlobalCommandValue(command, potentialArgs, defaultValue);
|
|
90
|
+
let { populatedArgumentValue, unusedArgs, invalidArgument, secretArgumentNames } = populateGlobalCommandValue(command, potentialArgs, defaultValue);
|
|
87
91
|
if (invalidArgument) {
|
|
88
92
|
invalidArguments.push(invalidArgument);
|
|
89
93
|
}
|
|
90
|
-
logger.debug("Command arguments for command: %s after value population: %O with invalid args: %O and unused args: %O", command.name, populatedArgumentValue, invalidArguments, unusedArgs);
|
|
94
|
+
logger.debug("Command arguments for command: %s after value population: %O with invalid args: %O and unused args: %O", command.name, redactGlobalCommandValue(command, populatedArgumentValue), invalidArguments, unusedArgs);
|
|
91
95
|
// don't validate the value if the argument is already invalid
|
|
92
96
|
if (invalidArguments.length === 0) {
|
|
93
97
|
const validatedValue = validateGlobalCommandArgumentValue(command, populatedArgumentValue, invalidArguments);
|
|
@@ -95,11 +99,12 @@ export function parseGlobalCommandClause(commandClause, defaultValue) {
|
|
|
95
99
|
populatedArgumentValue = validatedValue;
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
|
-
logger.debug("Command arguments for command: %s after value validation: %O with invalid args: %O", command.name, populatedArgumentValue, invalidArguments);
|
|
102
|
+
logger.debug("Command arguments for command: %s after value validation: %O with invalid args: %O", command.name, redactGlobalCommandValue(command, populatedArgumentValue), invalidArguments);
|
|
99
103
|
return {
|
|
100
104
|
command,
|
|
101
105
|
populatedArgumentValues: populatedArgumentValue,
|
|
102
106
|
invalidArguments,
|
|
103
107
|
unusedArgs,
|
|
108
|
+
...(secretArgumentNames && { secretArgumentNames }),
|
|
104
109
|
};
|
|
105
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/runtime/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/runtime/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAkB/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAEvF,OAAO,KAAK,4BAA4B,MAAM,0DAA0D,CAAC;AACzG,OAAO,KAAK,uBAAuB,MAAM,qDAAqD,CAAC;AAK/F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAKvE,OAAO,qBAAqB,MAAM,6CAA6C,CAAC;AAMhF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAsfzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,wBAAsB,GAAG,CACvB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,eAAe,EAAE,eAAe,EAChC,uBAAuB,EAAE,uBAAuB,EAChD,4BAA4B,EAAE,4BAA4B,GAAG,SAAS,EACtE,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,EAC5D,OAAO,EAAE,OAAO,EAChB,cAAc,CAAC,EAAE,OAAO,EACxB,cAAc,CAAC,EAAE,qBAAqB,GACrC,OAAO,CAAC,YAAY,CAAC,CAkKvB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RunState } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { isGlobalCommand, isSubCommand } from "./command/CommandTypeGuards.js";
|
|
3
3
|
import getLogger from "../util/logger.js";
|
|
4
|
-
import { printCommandExecutionError, printNoCommandRecognisedError, printNoCommandSpecifiedError, printParseResultError, printUnusedArgsWarning, } from "../util/runnerHelper.js";
|
|
4
|
+
import { printCommandExecutionError, printNoCommandRecognisedError, printNoCommandSpecifiedError, printParseResultError, printSecretArgsWarning, printUnusedArgsWarning, } from "../util/runnerHelper.js";
|
|
5
5
|
import { scanForGlobalModifierCommandClauses, scanForNonModifierCommandClause } from "./scanner.js";
|
|
6
6
|
import { parseGlobalCommandClause, parseSubCommandClause } from "./parser.js";
|
|
7
7
|
import { ARGUMENT_PROMPTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -113,6 +113,7 @@ async function findAndExecuteGlobalModifierCommands(availableArgSequences, unuse
|
|
|
113
113
|
? await configurationServiceProvider.getDefaultArgumentValues(context.cliConfig, globalModifierCommandClause.command)
|
|
114
114
|
: undefined;
|
|
115
115
|
const parseResult = parseGlobalCommandClause(globalModifierCommandClause, defaultArgumentValues);
|
|
116
|
+
await printSecretArgsWarning(context, parseResult);
|
|
116
117
|
if (parseResult.invalidArguments.length > 0) {
|
|
117
118
|
await printParseResultError(context, parseResult);
|
|
118
119
|
return {
|
|
@@ -186,7 +187,7 @@ async function findAndExecuteNonModifierCommand(availableArgs, unusedArgs, nonMo
|
|
|
186
187
|
unusedArgs.push(...scanResult.unusedArgSequences);
|
|
187
188
|
if (scanResult.nonModifierCommandClause) {
|
|
188
189
|
const defaultArgumentValues = configurationServiceProvider
|
|
189
|
-
? await configurationServiceProvider.getDefaultArgumentValues(context.cliConfig, scanResult.nonModifierCommandClause.command)
|
|
190
|
+
? await configurationServiceProvider.getDefaultArgumentValues(context.cliConfig, scanResult.nonModifierCommandClause.command, scanResult.nonModifierCommandClause.groupCommand)
|
|
190
191
|
: undefined;
|
|
191
192
|
if (isGlobalCommand(scanResult.nonModifierCommandClause.command)) {
|
|
192
193
|
parseResult = parseGlobalCommandClause(scanResult.nonModifierCommandClause, defaultArgumentValues);
|
|
@@ -194,6 +195,7 @@ async function findAndExecuteNonModifierCommand(availableArgs, unusedArgs, nonMo
|
|
|
194
195
|
else {
|
|
195
196
|
parseResult = parseSubCommandClause(scanResult.nonModifierCommandClause, defaultArgumentValues);
|
|
196
197
|
}
|
|
198
|
+
await printSecretArgsWarning(context, parseResult);
|
|
197
199
|
if (parseResult.invalidArguments.length > 0) {
|
|
198
200
|
const prompted = await attemptPromptForMissingArguments(parseResult, context);
|
|
199
201
|
if (prompted) {
|
|
@@ -298,6 +300,7 @@ async function findAndExecuteDefaultNonModifierCommand(availableArgs, unusedArgs
|
|
|
298
300
|
potentialArgs: [...argSequence],
|
|
299
301
|
}, defaultArgumentValues);
|
|
300
302
|
}
|
|
303
|
+
await printSecretArgsWarning(context, parseResult);
|
|
301
304
|
// add any unused args back to the list of still unused args
|
|
302
305
|
if (parseResult.unusedArgs.length > 0) {
|
|
303
306
|
unusedArgs.push(parseResult.unusedArgs);
|
|
@@ -12,6 +12,10 @@ export interface ValuePopulationResult {
|
|
|
12
12
|
* Any invalid argument discovered while populating values.
|
|
13
13
|
*/
|
|
14
14
|
readonly invalidArgument?: InvalidArgument;
|
|
15
|
+
/**
|
|
16
|
+
* Names of any SECRET arguments whose values were supplied as plain command line arguments.
|
|
17
|
+
*/
|
|
18
|
+
readonly secretArgumentNames?: ReadonlyArray<string>;
|
|
15
19
|
}
|
|
16
20
|
/**
|
|
17
21
|
* A container holding the result of argument values population for a {@link SubCommand}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValuePopulationResult.d.ts","sourceRoot":"","sources":["../../../../src/runtime/values/ValuePopulationResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,eAAe,EAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ValuePopulationResult.d.ts","sourceRoot":"","sources":["../../../../src/runtime/values/ValuePopulationResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,eAAe,EAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,+BAAgC,SAAQ,qBAAqB;IAC5E;;OAEG;IACH,QAAQ,CAAC,uBAAuB,EAAE,eAAe,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,kCAAmC,SAAQ,qBAAqB;IAC/E;;OAEG;IACH,QAAQ,CAAC,sBAAsB,EAAE,wBAAwB,CAAC;CAC3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"globalCommandValuePopulation.d.ts","sourceRoot":"","sources":["../../../../src/runtime/values/globalCommandValuePopulation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAErF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"globalCommandValuePopulation.d.ts","sourceRoot":"","sources":["../../../../src/runtime/values/globalCommandValuePopulation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAErF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAOxF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EACpC,YAAY,EAAE,wBAAwB,GACrC,kCAAkC,CAwEpC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import getLogger from "../../util/logger.js";
|
|
3
|
+
import { REDACTED } from "../../util/secretRedaction.js";
|
|
3
4
|
import { InvalidArgumentReason } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
5
|
const logger = getLogger("globalCommandValuePopulation");
|
|
5
6
|
/**
|
|
@@ -10,14 +11,20 @@ const logger = getLogger("globalCommandValuePopulation");
|
|
|
10
11
|
* @param defaultValue optional default value to use for population before parsing the provided arguments.
|
|
11
12
|
*/
|
|
12
13
|
export default function populateGlobalCommandValue(globalCommand, potentialArgs, defaultValue) {
|
|
14
|
+
const argument = globalCommand.argument;
|
|
15
|
+
const isSecret = argument.type === ValueTypeName.SECRET;
|
|
13
16
|
logger.debug(() => {
|
|
14
|
-
const message = `Populating value for global command: '${globalCommand.name}' using potential args: ${
|
|
17
|
+
const message = `Populating value for global command: '${globalCommand.name}' using potential args: ${(isSecret
|
|
18
|
+
? potentialArgs
|
|
19
|
+
.slice(0, 1)
|
|
20
|
+
.map(() => REDACTED)
|
|
21
|
+
.concat(potentialArgs.slice(1))
|
|
22
|
+
: potentialArgs).join(" ")}`;
|
|
15
23
|
if (defaultValue !== undefined) {
|
|
16
|
-
return `${message} and configured value: '${defaultValue}'`;
|
|
24
|
+
return `${message} and configured value: '${isSecret ? REDACTED : defaultValue}'`;
|
|
17
25
|
}
|
|
18
26
|
return message;
|
|
19
27
|
});
|
|
20
|
-
const argument = globalCommand.argument;
|
|
21
28
|
// default to defined argument default value
|
|
22
29
|
let populatedArgumentValue = argument.defaultValue;
|
|
23
30
|
// override with provided configured value
|
|
@@ -63,5 +70,6 @@ export default function populateGlobalCommandValue(globalCommand, potentialArgs,
|
|
|
63
70
|
return {
|
|
64
71
|
populatedArgumentValue,
|
|
65
72
|
unusedArgs,
|
|
73
|
+
...(isSecret && potentialArgs.length > 0 && { secretArgumentNames: [globalCommand.name] }),
|
|
66
74
|
};
|
|
67
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subCommandValuePopulation.d.ts","sourceRoot":"","sources":["../../../../src/runtime/values/subCommandValuePopulation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"subCommandValuePopulation.d.ts","sourceRoot":"","sources":["../../../../src/runtime/values/subCommandValuePopulation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,yCAAyC,CAAC;AAIjD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AA2kBlF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAC9C,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EACpC,aAAa,EAAE,eAAe,GAAG,SAAS,GACzC,+BAA+B,CA+EjC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ValueTypeName, } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import getLogger from "../../util/logger.js";
|
|
3
|
+
import { REDACTED, redactSubCommandValues } from "../../util/secretRedaction.js";
|
|
3
4
|
import argumentValueMerge from "./argumentValueMerge.js";
|
|
4
5
|
import { MAXIMUM_COMPLEX_OPTION_NESTING_DEPTH } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
6
|
import { isComplexOption } from "../argument/ArgumentTypeGuards.js";
|
|
@@ -62,6 +63,18 @@ class ParseContext {
|
|
|
62
63
|
* which will be populated with a positional value if found.
|
|
63
64
|
*/
|
|
64
65
|
currentPositionalIndex;
|
|
66
|
+
/**
|
|
67
|
+
* Set when the most recent argument supplied a value for a SECRET option or positional.
|
|
68
|
+
*/
|
|
69
|
+
secretArgument;
|
|
70
|
+
/**
|
|
71
|
+
* Return and clear the {@link secretArgument} recorded by the most recent {@link parse}.
|
|
72
|
+
*/
|
|
73
|
+
takeSecretArgument() {
|
|
74
|
+
const secretArgument = this.secretArgument;
|
|
75
|
+
this.secretArgument = undefined;
|
|
76
|
+
return secretArgument;
|
|
77
|
+
}
|
|
65
78
|
/**
|
|
66
79
|
* Use to store lazily created map of option paths e.g. --alpha.b.g and -a.b.gamma for {@link ComplexOption} or {@link Option} instances.
|
|
67
80
|
*/
|
|
@@ -294,7 +307,10 @@ class ParseContext {
|
|
|
294
307
|
* @return `false` if there is a problem populating the value, in which case the {@link state} will be set to
|
|
295
308
|
* {@link ParseState.ERROR} and {@link invalidArgument} will be populated.
|
|
296
309
|
*/
|
|
297
|
-
setOptionValue(value) {
|
|
310
|
+
setOptionValue(value, inline = false) {
|
|
311
|
+
if (this.currentOption.type === ValueTypeName.SECRET) {
|
|
312
|
+
this.secretArgument = { name: this.currentOption.name, inline };
|
|
313
|
+
}
|
|
298
314
|
let optionValue = this.populatedArgumentValues;
|
|
299
315
|
const optionPath = this.currentOptionPath;
|
|
300
316
|
// traverse the current populated values using the validated option path elements
|
|
@@ -367,6 +383,9 @@ class ParseContext {
|
|
|
367
383
|
setPositionalValue(value) {
|
|
368
384
|
const positional = this.subCommand.positionals[this.currentPositionalIndex];
|
|
369
385
|
const currentValue = this.populatedArgumentValues[positional.name];
|
|
386
|
+
if (positional.type === ValueTypeName.SECRET) {
|
|
387
|
+
this.secretArgument = { name: positional.name, inline: false };
|
|
388
|
+
}
|
|
370
389
|
// if we haven't populated the argument value before...
|
|
371
390
|
if (currentValue === undefined) {
|
|
372
391
|
if (positional.isVarargMultiple) {
|
|
@@ -460,7 +479,7 @@ class ParseContext {
|
|
|
460
479
|
// try to set the value if we have one
|
|
461
480
|
if (potentialOptionValue !== undefined) {
|
|
462
481
|
// set the value
|
|
463
|
-
this.setOptionValue(potentialOptionValue);
|
|
482
|
+
this.setOptionValue(potentialOptionValue, true);
|
|
464
483
|
// return regardless
|
|
465
484
|
return;
|
|
466
485
|
}
|
|
@@ -491,19 +510,21 @@ class ParseContext {
|
|
|
491
510
|
* @param defaultValues optional default {@link Values} to use for population before parsing the provided arguments.
|
|
492
511
|
*/
|
|
493
512
|
export default function populateSubCommandValues(subCommand, potentialArgs, defaultValues) {
|
|
494
|
-
logger.debug(() => {
|
|
495
|
-
const message = `Populating values for sub-command: '${subCommand.name}' using potential args: ${potentialArgs.join(" ")}`;
|
|
496
|
-
if (defaultValues !== undefined) {
|
|
497
|
-
return `${message} and configured values: ${JSON.stringify(defaultValues)}`;
|
|
498
|
-
}
|
|
499
|
-
return message;
|
|
500
|
-
});
|
|
501
513
|
const parseContext = new ParseContext(subCommand);
|
|
502
514
|
const unusedArgs = [];
|
|
515
|
+
const loggedArgs = [...potentialArgs];
|
|
516
|
+
const secretArgumentNames = new Set();
|
|
503
517
|
for (let i = 0; i < potentialArgs.length; i++) {
|
|
504
518
|
const potentialArg = potentialArgs[i];
|
|
505
519
|
// parse the next arg
|
|
506
520
|
parseContext.parse(potentialArg);
|
|
521
|
+
const secretArgument = parseContext.takeSecretArgument();
|
|
522
|
+
if (secretArgument) {
|
|
523
|
+
secretArgumentNames.add(secretArgument.name);
|
|
524
|
+
loggedArgs[i] = secretArgument.inline
|
|
525
|
+
? `${potentialArg.slice(0, potentialArg.indexOf("=") + 1)}${REDACTED}`
|
|
526
|
+
: REDACTED;
|
|
527
|
+
}
|
|
507
528
|
// check if we had a parsing error, record the error, flush the remaining args and stop parsing
|
|
508
529
|
if (parseContext.state === ParseState.ERROR) {
|
|
509
530
|
if (i + 1 < potentialArgs.length) {
|
|
@@ -517,6 +538,13 @@ export default function populateSubCommandValues(subCommand, potentialArgs, defa
|
|
|
517
538
|
parseContext.state = ParseState.EMPTY;
|
|
518
539
|
}
|
|
519
540
|
}
|
|
541
|
+
logger.debug(() => {
|
|
542
|
+
const message = `Populated values for sub-command: '${subCommand.name}' using potential args: ${loggedArgs.join(" ")}`;
|
|
543
|
+
if (defaultValues !== undefined) {
|
|
544
|
+
return `${message} and configured values: ${JSON.stringify(redactSubCommandValues(subCommand, defaultValues))}`;
|
|
545
|
+
}
|
|
546
|
+
return message;
|
|
547
|
+
});
|
|
520
548
|
// Check if the last arg specified an option but no value
|
|
521
549
|
if (parseContext.state === ParseState.OPTION_VALUE_EXPECTED) {
|
|
522
550
|
// special case if the last arg was for a boolean option where the value was implicitly `true`
|
|
@@ -536,6 +564,7 @@ export default function populateSubCommandValues(subCommand, potentialArgs, defa
|
|
|
536
564
|
populatedArgumentValues: parseContext.populatedArgumentValues,
|
|
537
565
|
unusedArgs: unusedArgs,
|
|
538
566
|
invalidArgument: parseContext.invalidArgument,
|
|
567
|
+
...(secretArgumentNames.size > 0 && { secretArgumentNames: [...secretArgumentNames] }),
|
|
539
568
|
};
|
|
540
569
|
}
|
|
541
570
|
// merge the configured values with the parsed values
|
|
@@ -546,5 +575,6 @@ export default function populateSubCommandValues(subCommand, potentialArgs, defa
|
|
|
546
575
|
return {
|
|
547
576
|
populatedArgumentValues,
|
|
548
577
|
unusedArgs: unusedArgs,
|
|
578
|
+
...(secretArgumentNames.size > 0 && { secretArgumentNames: [...secretArgumentNames] }),
|
|
549
579
|
};
|
|
550
580
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { SingleValueType, Values, ValueNode, PopulatedValues, PopulatedValueType } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
|
+
import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
5
|
import type { Command } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
6
|
import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
7
|
export type KeyValueServiceScopeType = "command" | "service";
|
|
@@ -27,7 +28,8 @@ export type KeyValueServiceScopeType = "command" | "service";
|
|
|
27
28
|
*
|
|
28
29
|
* A JSON file where the structure matches {@link Values} and the defaults are stored
|
|
29
30
|
* under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
|
|
30
|
-
*
|
|
31
|
+
* (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
|
|
32
|
+
* command {@link Values}. As an example:
|
|
31
33
|
*
|
|
32
34
|
* ```
|
|
33
35
|
* {
|
|
@@ -44,6 +46,9 @@ export type KeyValueServiceScopeType = "command" | "service";
|
|
|
44
46
|
* "command2": {
|
|
45
47
|
* "arg4": true
|
|
46
48
|
* },
|
|
49
|
+
* "group1:member1": {
|
|
50
|
+
* "arg5": "bar"
|
|
51
|
+
* },
|
|
47
52
|
* "globalCommand": "globalArgumentValue"
|
|
48
53
|
* },
|
|
49
54
|
* "key-values": {
|
|
@@ -74,13 +79,15 @@ export type KeyValueServiceScopeType = "command" | "service";
|
|
|
74
79
|
* Argument configuration keys are concatenated with a `_` separator.
|
|
75
80
|
* Any arguments which support array values must by suffixed with `_` and an explicit array index.
|
|
76
81
|
* If the root argument in the path does not use a custom {@link Argument.configurationKey} then the key path
|
|
77
|
-
* is additionally
|
|
82
|
+
* is additionally prefixed with the {@link CLIConfig.name}, the {@link GroupCommand.name} (if the command is a group
|
|
83
|
+
* member) and the {@link Command.name} with `_` separators.
|
|
78
84
|
* This is best explained with examples...
|
|
79
85
|
*
|
|
80
86
|
* No custom configuration key examples:
|
|
81
87
|
*
|
|
82
88
|
* * executable: `MyCLI`, command: `globalCommand1`, global command argument => environment variable: `MYCLI_GLOBALCOMMAND1`
|
|
83
89
|
* * executable: `MyCLI`, command: `command1`, simple root argument: `arg1` => environment variable: `MYCLI_COMMAND1_ARG1`
|
|
90
|
+
* * executable: `MyCLI`, group: `group1`, member command: `member1`, simple root argument: `arg1` => environment variable: `MYCLI_GROUP1_MEMBER1_ARG1`
|
|
84
91
|
* * executable: `MyCLI`, command: `command1`, array root argument, 1st element: `arg2[0]` => environment variable: `MYCLI_COMMAND1_ARG2_0`
|
|
85
92
|
* * executable: `MyCLI`, command: `command1`, argument is a digit so it is by default suffixed with `_`: `3` => environment variable: `MYCLI_COMMAND1__3`
|
|
86
93
|
* * executable: `MyCLI`, command: `command1`, nested sub-argument: `arg1.arg2` => environment variable: `MYCLI_COMMAND1_ARG1_ARG2`
|
|
@@ -127,8 +134,10 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
127
134
|
*
|
|
128
135
|
* @param cliConfig the {@link CLIConfig} to use for retrieving configuration keys.
|
|
129
136
|
* @param command the {@link Command} instance to retrieve default argument values for.
|
|
137
|
+
* @param groupCommand the {@link GroupCommand} if the command is a group member. The configuration file key
|
|
138
|
+
* is then `<group name>:<command name>` and the env var names include the group name.
|
|
130
139
|
*/
|
|
131
|
-
getDefaultArgumentValues(cliConfig: CLIConfig, command: Command): Promise<PopulatedValues | PopulatedValueType | undefined>;
|
|
140
|
+
getDefaultArgumentValues(cliConfig: CLIConfig, command: Command, groupCommand?: GroupCommand): Promise<PopulatedValues | PopulatedValueType | undefined>;
|
|
132
141
|
/**
|
|
133
142
|
* Get-or-create the underlying, raw {@link ValueNode} `Map` for the given scope - for
|
|
134
143
|
* {@link KeyValueServiceProvider}'s exclusive use, via its direct reference to this provider.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigurationServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/configuration/ConfigurationServiceProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,eAAe,EACf,kBAAkB,EACnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConfigurationServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/configuration/ConfigurationServiceProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,eAAe,EACf,kBAAkB,EACnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAS5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAOvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,CAAC;AAkB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoGG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA6B,YAAW,eAAe;;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAA4B;IACtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,SAAgB,cAAc,EAAE,OAAO,CAAC;IACxC,SAAgB,aAAa,EAAE,OAAO,CAAC;IACvC,SAAgB,oBAAoB,EAAE,OAAO,CAAC;IAGvC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAKnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,CAAa;IAqBvE;;;;;;;;OAQG;IACH,YACE,eAAe,EAAE,MAAM,EACvB,cAAc,UAAQ,EACtB,aAAa,UAAQ,EACrB,oBAAoB,UAAQ,EAW7B;IAEM,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAehE;IAEM,iBAAiB,CAAC,cAAc,EAAE,MAAM,QAE9C;IAED;;;;;;;;;OASG;IACU,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAC,CAsD3D;IAED;;;;;;OAMG;IACI,eAAe,CACpB,SAAS,EAAE,wBAAwB,EACnC,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAOxB;IAED;;;;;;OAMG;IACU,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzD;IAEY,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CxD;IA4DM,eAAe,IAAI,MAAM,CAgC/B;CACF"}
|
|
@@ -47,7 +47,8 @@ class ConfigurationServiceImpl {
|
|
|
47
47
|
*
|
|
48
48
|
* A JSON file where the structure matches {@link Values} and the defaults are stored
|
|
49
49
|
* under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
|
|
50
|
-
*
|
|
50
|
+
* (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
|
|
51
|
+
* command {@link Values}. As an example:
|
|
51
52
|
*
|
|
52
53
|
* ```
|
|
53
54
|
* {
|
|
@@ -64,6 +65,9 @@ class ConfigurationServiceImpl {
|
|
|
64
65
|
* "command2": {
|
|
65
66
|
* "arg4": true
|
|
66
67
|
* },
|
|
68
|
+
* "group1:member1": {
|
|
69
|
+
* "arg5": "bar"
|
|
70
|
+
* },
|
|
67
71
|
* "globalCommand": "globalArgumentValue"
|
|
68
72
|
* },
|
|
69
73
|
* "key-values": {
|
|
@@ -94,13 +98,15 @@ class ConfigurationServiceImpl {
|
|
|
94
98
|
* Argument configuration keys are concatenated with a `_` separator.
|
|
95
99
|
* Any arguments which support array values must by suffixed with `_` and an explicit array index.
|
|
96
100
|
* If the root argument in the path does not use a custom {@link Argument.configurationKey} then the key path
|
|
97
|
-
* is additionally
|
|
101
|
+
* is additionally prefixed with the {@link CLIConfig.name}, the {@link GroupCommand.name} (if the command is a group
|
|
102
|
+
* member) and the {@link Command.name} with `_` separators.
|
|
98
103
|
* This is best explained with examples...
|
|
99
104
|
*
|
|
100
105
|
* No custom configuration key examples:
|
|
101
106
|
*
|
|
102
107
|
* * executable: `MyCLI`, command: `globalCommand1`, global command argument => environment variable: `MYCLI_GLOBALCOMMAND1`
|
|
103
108
|
* * executable: `MyCLI`, command: `command1`, simple root argument: `arg1` => environment variable: `MYCLI_COMMAND1_ARG1`
|
|
109
|
+
* * executable: `MyCLI`, group: `group1`, member command: `member1`, simple root argument: `arg1` => environment variable: `MYCLI_GROUP1_MEMBER1_ARG1`
|
|
104
110
|
* * executable: `MyCLI`, command: `command1`, array root argument, 1st element: `arg2[0]` => environment variable: `MYCLI_COMMAND1_ARG2_0`
|
|
105
111
|
* * executable: `MyCLI`, command: `command1`, argument is a digit so it is by default suffixed with `_`: `3` => environment variable: `MYCLI_COMMAND1__3`
|
|
106
112
|
* * executable: `MyCLI`, command: `command1`, nested sub-argument: `arg1.arg2` => environment variable: `MYCLI_COMMAND1_ARG1_ARG2`
|
|
@@ -191,20 +197,23 @@ export default class ConfigurationServiceProvider {
|
|
|
191
197
|
*
|
|
192
198
|
* @param cliConfig the {@link CLIConfig} to use for retrieving configuration keys.
|
|
193
199
|
* @param command the {@link Command} instance to retrieve default argument values for.
|
|
200
|
+
* @param groupCommand the {@link GroupCommand} if the command is a group member. The configuration file key
|
|
201
|
+
* is then `<group name>:<command name>` and the env var names include the group name.
|
|
194
202
|
*/
|
|
195
|
-
async getDefaultArgumentValues(cliConfig, command) {
|
|
203
|
+
async getDefaultArgumentValues(cliConfig, command, groupCommand) {
|
|
196
204
|
if (!this.configEnabled) {
|
|
197
205
|
logger.debug("configuration of default values is not enabled");
|
|
198
206
|
return undefined;
|
|
199
207
|
}
|
|
200
|
-
|
|
208
|
+
const commandKey = groupCommand ? `${groupCommand.name}:${command.name}` : command.name;
|
|
209
|
+
logger.debug("getting default argument values for command: %s", commandKey);
|
|
201
210
|
if (command.enableConfiguration === undefined || command.enableConfiguration !== true) {
|
|
202
211
|
logger.debug("enableConfiguration for command: %s is not true", command.name);
|
|
203
212
|
return undefined;
|
|
204
213
|
}
|
|
205
214
|
let result;
|
|
206
215
|
if (isGlobalModifierCommand(command) || isGlobalCommand(command)) {
|
|
207
|
-
const configuredValue = this.defaultsData.get(
|
|
216
|
+
const configuredValue = this.defaultsData.get(commandKey);
|
|
208
217
|
const envVarValue = this.envVarsEnabled
|
|
209
218
|
? getGlobalCommandValueFromEnvVars(cliConfig, command)
|
|
210
219
|
: undefined;
|
|
@@ -212,9 +221,9 @@ export default class ConfigurationServiceProvider {
|
|
|
212
221
|
result = envVarValue !== undefined ? envVarValue : configuredValue;
|
|
213
222
|
}
|
|
214
223
|
else if (isSubCommand(command)) {
|
|
215
|
-
const configuredValues = this.defaultsData.get(
|
|
224
|
+
const configuredValues = this.defaultsData.get(commandKey);
|
|
216
225
|
const envVarValues = this.envVarsEnabled
|
|
217
|
-
? getSubCommandValuesFromEnvVars(cliConfig, command)
|
|
226
|
+
? getSubCommandValuesFromEnvVars(cliConfig, command, groupCommand)
|
|
218
227
|
: undefined;
|
|
219
228
|
if (envVarValues === undefined) {
|
|
220
229
|
result = configuredValues;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
2
|
import type { Command } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
3
|
import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
4
|
import type { SubCommandArgument } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -9,8 +10,10 @@ import type { GlobalCommandArgument } from "@flowscripter/dynamic-cli-framework-
|
|
|
9
10
|
* @param command the {@link Command} to use for determining the default configuration key.
|
|
10
11
|
* @param argumentAncestry a list of {@link SubCommandArgument} instances from the root command arguments to a leaf argument.
|
|
11
12
|
* Apart from {@link ComplexOption} instances this will always only have a single entry.
|
|
13
|
+
* @param groupCommand the {@link GroupCommand} if the command is a member of a group, in which case the group name
|
|
14
|
+
* is an additional key segment.
|
|
12
15
|
*/
|
|
13
|
-
export declare function getSubCommandArgumentConfigurationKey(cliConfig: CLIConfig, command: Command, argumentAncestry: Array<SubCommandArgument
|
|
16
|
+
export declare function getSubCommandArgumentConfigurationKey(cliConfig: CLIConfig, command: Command, argumentAncestry: Array<SubCommandArgument>, groupCommand?: GroupCommand): string | undefined;
|
|
14
17
|
/**
|
|
15
18
|
* Determine the configuration key for the specified {@link GlobalCommandArgument}.
|
|
16
19
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configHelper.d.ts","sourceRoot":"","sources":["../../../src/util/configHelper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAgBrF
|
|
1
|
+
{"version":3,"file":"configHelper.d.ts","sourceRoot":"","sources":["../../../src/util/configHelper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAgBrF;;;;;;;;;GASG;AACH,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,CAAC,EAC3C,YAAY,CAAC,EAAE,YAAY,GAC1B,MAAM,GAAG,SAAS,CA8BpB;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,qBAAqB,EAAE,qBAAqB,GAC3C,MAAM,GAAG,SAAS,CAcpB"}
|
|
@@ -18,8 +18,10 @@ function getKeySegment(segment, isCustom = false, isArray = false) {
|
|
|
18
18
|
* @param command the {@link Command} to use for determining the default configuration key.
|
|
19
19
|
* @param argumentAncestry a list of {@link SubCommandArgument} instances from the root command arguments to a leaf argument.
|
|
20
20
|
* Apart from {@link ComplexOption} instances this will always only have a single entry.
|
|
21
|
+
* @param groupCommand the {@link GroupCommand} if the command is a member of a group, in which case the group name
|
|
22
|
+
* is an additional key segment.
|
|
21
23
|
*/
|
|
22
|
-
export function getSubCommandArgumentConfigurationKey(cliConfig, command, argumentAncestry) {
|
|
24
|
+
export function getSubCommandArgumentConfigurationKey(cliConfig, command, argumentAncestry, groupCommand) {
|
|
23
25
|
if (command.enableConfiguration === undefined || command.enableConfiguration !== true) {
|
|
24
26
|
return undefined;
|
|
25
27
|
}
|
|
@@ -30,6 +32,9 @@ export function getSubCommandArgumentConfigurationKey(cliConfig, command, argume
|
|
|
30
32
|
const firstArgument = argumentAncestry[0];
|
|
31
33
|
if (firstArgument.configurationKey === undefined) {
|
|
32
34
|
keySegments.push(getKeySegment(cliConfig.name));
|
|
35
|
+
if (groupCommand) {
|
|
36
|
+
keySegments.push(getKeySegment(groupCommand.name));
|
|
37
|
+
}
|
|
33
38
|
keySegments.push(getKeySegment(command.name));
|
|
34
39
|
}
|
|
35
40
|
argumentAncestry.forEach((argument) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { type PopulatedSingleValueType, type PopulatedValues } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import type { GlobalCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
|
+
import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
5
|
import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
6
|
/**
|
|
6
7
|
* Get configured argument value for the specified {@link GlobalCommandArgument} from environment variables.
|
|
@@ -16,6 +17,8 @@ export declare function getGlobalCommandValueFromEnvVars(cliConfig: CLIConfig, c
|
|
|
16
17
|
* @param cliConfig the {@link CLIConfig} to use for determining the default configuration key.
|
|
17
18
|
* @param command the {@link SubCommand} to use for determining the default configuration key and containing
|
|
18
19
|
* {@link Positional} and {@link Option} instances to populate values for.
|
|
20
|
+
* @param groupCommand the {@link GroupCommand} if the command is a group member, in which case the group name
|
|
21
|
+
* is an additional env var name segment.
|
|
19
22
|
*/
|
|
20
|
-
export declare function getSubCommandValuesFromEnvVars(cliConfig: CLIConfig, command: SubCommand): PopulatedValues | undefined;
|
|
23
|
+
export declare function getSubCommandValuesFromEnvVars(cliConfig: CLIConfig, command: SubCommand, groupCommand?: GroupCommand): PopulatedValues | undefined;
|
|
21
24
|
//# sourceMappingURL=envVarHelper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envVarHelper.d.ts","sourceRoot":"","sources":["../../../src/util/envVarHelper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACrB,MAAM,yCAAyC,CAAC;AAOjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"envVarHelper.d.ts","sourceRoot":"","sources":["../../../src/util/envVarHelper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACrB,MAAM,yCAAyC,CAAC;AAOjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAqC1E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,aAAa,GACrB,wBAAwB,CAa1B;AAwID;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,UAAU,EACnB,YAAY,CAAC,EAAE,YAAY,GAC1B,eAAe,GAAG,SAAS,CAsF7B"}
|