@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.
Files changed (47) hide show
  1. package/dist/src/command/MultiCommandCliHelpCommand.d.ts.map +1 -1
  2. package/dist/src/command/MultiCommandCliHelpCommand.js +1 -1
  3. package/dist/src/runtime/command/CommandValidator.d.ts.map +1 -1
  4. package/dist/src/runtime/command/CommandValidator.js +9 -2
  5. package/dist/src/runtime/parser.d.ts +8 -2
  6. package/dist/src/runtime/parser.d.ts.map +1 -1
  7. package/dist/src/runtime/parser.js +11 -6
  8. package/dist/src/runtime/runner.d.ts.map +1 -1
  9. package/dist/src/runtime/runner.js +5 -2
  10. package/dist/src/runtime/values/ValuePopulationResult.d.ts +4 -0
  11. package/dist/src/runtime/values/ValuePopulationResult.d.ts.map +1 -1
  12. package/dist/src/runtime/values/globalCommandValuePopulation.d.ts.map +1 -1
  13. package/dist/src/runtime/values/globalCommandValuePopulation.js +11 -3
  14. package/dist/src/runtime/values/subCommandValuePopulation.d.ts.map +1 -1
  15. package/dist/src/runtime/values/subCommandValuePopulation.js +39 -9
  16. package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts +12 -3
  17. package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts.map +1 -1
  18. package/dist/src/service/configuration/ConfigurationServiceProvider.js +16 -7
  19. package/dist/src/util/configHelper.d.ts +4 -1
  20. package/dist/src/util/configHelper.d.ts.map +1 -1
  21. package/dist/src/util/configHelper.js +6 -1
  22. package/dist/src/util/envVarHelper.d.ts +4 -1
  23. package/dist/src/util/envVarHelper.d.ts.map +1 -1
  24. package/dist/src/util/envVarHelper.js +8 -5
  25. package/dist/src/util/helpHelper.d.ts +1 -1
  26. package/dist/src/util/helpHelper.d.ts.map +1 -1
  27. package/dist/src/util/helpHelper.js +8 -16
  28. package/dist/src/util/runnerHelper.d.ts +2 -0
  29. package/dist/src/util/runnerHelper.d.ts.map +1 -1
  30. package/dist/src/util/runnerHelper.js +10 -0
  31. package/dist/src/util/secretRedaction.d.ts +11 -0
  32. package/dist/src/util/secretRedaction.d.ts.map +1 -0
  33. package/dist/src/util/secretRedaction.js +45 -0
  34. package/package.json +1 -1
  35. package/src/command/MultiCommandCliHelpCommand.ts +7 -1
  36. package/src/runtime/command/CommandValidator.ts +8 -1
  37. package/src/runtime/parser.ts +22 -16
  38. package/src/runtime/runner.ts +5 -0
  39. package/src/runtime/values/ValuePopulationResult.ts +5 -0
  40. package/src/runtime/values/globalCommandValuePopulation.ts +12 -5
  41. package/src/runtime/values/subCommandValuePopulation.ts +47 -12
  42. package/src/service/configuration/ConfigurationServiceProvider.ts +18 -6
  43. package/src/util/configHelper.ts +7 -0
  44. package/src/util/envVarHelper.ts +19 -3
  45. package/src/util/helpHelper.ts +34 -13
  46. package/src/util/runnerHelper.ts +18 -0
  47. 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,CAmFnF;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"}
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;;IAInC,YAAmB,SAAS,EAAE,SAAS,EAEtC;IAED;;;;;;OAMG;IACI,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUtC;CAgWF"}
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.#validateSubCommand(subCommand);
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): ParseResult;
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): ParseResult;
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;AAclD,YAAY,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,aAAa,EAC5B,aAAa,CAAC,EAAE,eAAe,GAC9B,WAAW,CAiFb;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,wBAAwB,GACtC,WAAW,CA0Db"}
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;AAiB/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;AAkfzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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
+ {"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;CAC5C;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
+ {"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;AAMxF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EACpC,YAAY,EAAE,wBAAwB,GACrC,kCAAkC,CAkEpC"}
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: ${potentialArgs.join(" ")}`;
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;AAGjD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAsjBlF;;;;;;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,CAkEjC"}
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
- * and the contained values are treated as command {@link Values}. As an example:
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 suffixed with the {@link CLIConfig.name} and the {@link Command.name} with `_` separators.
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;AASvE,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8FG;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;;;;;;;OAOG;IACU,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAC,CAoD3D;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"}
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
- * and the contained values are treated as command {@link Values}. As an example:
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 suffixed with the {@link CLIConfig.name} and the {@link Command.name} with `_` separators.
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
- logger.debug("getting default argument values for command: %s", command.name);
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(command.name);
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(command.name);
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>): string | undefined;
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;;;;;;;GAOG;AACH,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,CAAC,GAC1C,MAAM,GAAG,SAAS,CA2BpB;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,qBAAqB,EAAE,qBAAqB,GAC3C,MAAM,GAAG,SAAS,CAcpB"}
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;AAmC1E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,aAAa,GACrB,wBAAwB,CAa1B;AAwID;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,UAAU,GAClB,eAAe,GAAG,SAAS,CA4E7B"}
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"}