class ConfigurationServiceProvider
implements ServiceProvider

Provides:

  • Configuration of default command arguments using a configuration file and/or environment variables.
  • A generic key-value store for commands and services (KeyValueService).

Default Command Arguments

Configuration of default ArgumentValues for Command instances is supported if they have defined Command.enableConfiguration as true.

Two sources of configuration are supported and both are expected to be manually managed by the user of the CLI.

Configuration File

A JSON file where the structure matches ArgumentValues and the defaults are stored under a top level defaults property. The second level of properties is used to refer to Command.name and the contained values are treated as command ArgumentValues. As an example:

{
    "defaults": {
        "subCommand1": {
            "arg1": [
                1,
                2
            ],
            "arg2": {
                "arg3": "foo"
            }
        },
        "command2": {
            "arg4": true
        },
        "globalCommand": "globalArgumentValue"
    },
    "key-values": {
        ...
    }
}

The default location of the configuration file is $HOME/.<application_name>.json. If $HOME is not defined no default configuration will be used. The location of the configuration file can be modified via the ConfigCommand.

Environment Variables

Values are parsed using a key path defined by custom Argument.configurationKey values or using the default naming scheme defined within Argument.configurationKey.

NOTE: Any values set by environment variables will override those sourced from the configuration file.

The argument key path is derived for an argument (or nested argument) as follows:

Argument configuration keys are concatenated with a _ separator. Any arguments which support array values must by suffixed with _ and an explicit array index. If the root argument in the path does not use a custom Argument.configurationKey then the key path is additionally suffixed with the CLIConfig.name and the Command.name with _ separators. This is best explained with examples...

No custom configuration key examples:

  • executable: MyCLI, command: globalCommand1, global command argument => environment variable: MYCLI_GLOBALCOMMAND1
  • executable: MyCLI, command: command1, simple root argument: arg1 => environment variable: MYCLI_COMMAND1_ARG1
  • executable: MyCLI, command: command1, array root argument, 1st element: arg2[0] => environment variable: MYCLI_COMMAND1_ARG2_0
  • executable: MyCLI, command: command1, argument is a digit so it is by default suffixed with _: 3 => environment variable: MYCLI_COMMAND1__3
  • executable: MyCLI, command: command1, nested sub-argument: arg1.arg2 => environment variable: MYCLI_COMMAND1_ARG1_ARG2
  • executable: MyCLI, command: command1, nested sub-argument with both levels being arrays and referring to the 2nd element of each: arg1[1].arg2[1] => environment variable: MYCLI_COMMAND1_ARG1_1_ARG2_2

Custom configuration key at the root level (and therefore not prefixed with CLI and command names) examples:

  • executable: MyCLI, command: globalCommand1, global command argument, global command argument configuration key: FOO=> environment variable:FOO`
  • executable: MyCLI, command: command1, simple root argument: arg1, arg1 configuration key: FOO => environment variable: FOO
  • executable: MyCLI, command: command1, array root argument, 1st element: arg2[0], arg1 configuration key: BAR => environment variable: BAR_0

Custom configuration key not at the root level (and therefore prefixed with CLI and command names) examples:

  • executable: MyCLI, command: command1, nested sub-argument: arg1.arg2, arg2 configuration key: FOO => environment variable: MYCLI_COMMAND1_ARG1_FOO
  • executable: MyCLI, command: command1, nested sub-argument with both levels being arrays and referring to the 2nd element of each: arg1[1].arg2[1], arg2 configuration key: BAR => environment variable: MYCLI_COMMAND1_ARG1_1_BAR_2

NOTE: Any default values from the above configuration sources will be overridden by any arguments provided on the command line.

Generic Key-Value Service

The same configuration file above is used to provide storage for the provided KeyValueService. The values are stored under a top level key-values property. These are not expected to be modified by the user of the CLI.

The second and third level of properties is used to scope the key-values to specific command names (via Command.name values) and specific service IDs (via ServiceInfo.serviceId values). Both keys and values are string based.

As an example:

{
   "defaults": {
       ...
   },
   "key-values": {
       "commands": {
           "command1": {
              "foo1": "bar1",
              "foo2": "bar2"
           },
           "command2": {
               "foo1": "bar3"
           }
       },
       "services": {
           "service-id-1": {
               "foo1": "bar"
           }
       }
   }
}

Constructors

new
ConfigurationServiceProvider(
servicePriority: number,
envVarsEnabled?: boolean,
configEnabled?: boolean,
keyValueServiceEnabled?: boolean,
)

Create an instance of the service provider with the specified details.

Properties

readonly
configEnabled: boolean
configLocation: string | undefined
readonly
envVarsEnabled: boolean
readonly
keyValueServiceEnabled: boolean
readonly
serviceId: string
readonly
servicePriority: number

Methods

clearKeyValueScope(): Promise<void>

Indicate that the contained DefaultKeyValueService should have any current scope cleared.

If a scope is currently set and changes have been made to the key-value data, they will be written to the current configuration location.

Retrieve the defaults command argument values (if any) for the provided Command.

This will retrieve values both from the configuration location and environment variables.

initService(context: Context): Promise<void>
provide(_cliConfig: CLIConfig): Promise<ServiceInfo>
setCommandKeyValueScope(commandName: string): void

Indicate that the contained DefaultKeyValueService should be set to have a scope of the provided command name.

setConfigLocation(configLocation: string): void
setServiceKeyValueScope(serviceId: string): void

Indicate that the contained DefaultKeyValueService should be set to have a scope of the provided service ID.