Skip to main content

Configuration

The Stricli framework was designed to give applications the maximum amount of flexibility within the predefined constraints. When building an application, you can specify additional configurations to control the application behavior in different ways.

Version Information

One common requirement of CLI applications is to display their own current version. This is possible with the versionInfo configuration object.

If this object is specified, it will expect either a static currentVersion string or a function getCurrentVersion which asynchronously returns the current version. If versionInfo is provided with this value/function, then Stricli will automatically expose --version/-v flags to the application root. When --version is called, Stricli will print this current version to stdout.

Another related requirement is to warn users when their version is outdated and there is an updated version available. In the versionInfo object you can also specify a getLatestVersion function which optionally accepts currentVersion and returns the latest version of the application, if it is available. Stricli will then compare the current version against the latest version and print a warning to stderr. Optionally a command can be provided (upgradeCommand) if there is a simple way for end users to upgrade to the latest version.

The text of this warning can be controlled by the localization but will only happen when getLatestVersion is provided and the current version does not match the latest version.

Scanner

The scanner is the internal system in Stricli that processes user inputs from the command line and determines which route/command to run and the arguments to run it with. Configuration for this system is controlled by the scanner property in the application configuration.

Argument Escape Sequence

Stricli scans the user input to determine how to parse that input into flags and positional arguments. Due to the fact that every input string with a leading - is treated as a potential flag, it can be useful to bypass this behavior in some circumstances. The user can specify -- which indicates to the scanner that any following inputs should be treated as positional arguments. This feature is controlled by the allowArgumentEscapeSequence property, which defaults to false.

The following is an example command that prints flags and args to stdout.

With allowArgumentEscapeSequence=false

run --foo -- --bar
{ foo: true, bar: true }, ["--"]

With allowArgumentEscapeSequence=true

run --foo -- --bar
{ foo: true }, ["--bar"]

Distance Calculation

When input scanning fails to find a route/command or flag, Stricli will include suggested alternatives in the error message ("did you mean ___?"). Stricli calculates the Damerau-Levenshtein distance of all potential alternatives and returns only those that have a distance below a certain threshold. By default, this distance threshold is 7 with specific weights for certain operations (insertion=1, deletion=2, substitution=2, transposition=0). However, it can be customized to any value by editing the distanceOptions property.

Scanner Case Style

As route, command, and flag names are all defined in the specification as object properties, it is likely that stylistic preferences will force these properties to adhere to camelCase styling. However, many CLI applications also support or require kebab-case style for naming at runtime. The caseStyle configuration allows you to adjust what to accept as input.

The default value for this configuration is original, which requires that any input match the defined name exactly. The other option is allow-kebab-for-camel, which augments the scanner and additionally allows the kebab-case style version of any camelCase style name. The conversion relies on converting upper case letters to lower case with a preceding -.

Documentation Formatting

The configuration in documentation controls how values and names in the application are included in documentation and help text. For information about how to customize the text itself, check out localization.

Always Show --helpAll Flag

Stricli provides a built-in --help flag that prints out the help text for a command/route. This help text will never include hidden flags, but those can be visualized with the --helpAll built-in flag. It will print all flags/routes, but is not listed as a flag in the normal help text. This built-in is always available, but if you want to make it visible to users at all times you can set alwaysShowHelpAllFlag to true.

Use Alias in Usage Line

The usage lines for commands are automatically generated from the parameters. If the flag and argument names are overly long, the usage line can become particularly unwieldy. The configuration option useAliasInUsageLine defaults to false, but if enabled will use any aliases in place of flag names in the usage line.

Only Required in Usage Line

By default, Stricli will render all flags and arguments in the sample usage line for the help text. If there are many optional flags or arguments, this can often grow too verbose. The configuration option onlyRequiredInUsageLine will filter out any runtime-optional flags and arguments from the automatically-generated usage line. This will include required flags that have a default specified. Note that custom usage lines can be provided manually per-command to allow for more specific control.

Display Case Style

The caseStyle configuration here is the documentation-side equivalent of the scanner case style. It controls which case style is used when displaying route and flag names. It defaults to the value that matches the corresponding scanner.caseStyle value. If the scanner has allow-kebab-for-camel then the documentation case style will be convert-camel-to-kebab which converts the case style of any camelCase names to kebab-case when they are included in documentation.

danger

It is invalid to set documentation.caseStyle to convert-camel-to-kebab when scanner.caseStyle is original as this results in documentation that includes names that will not be supported at runtime.

Disable ANSI Color

Stricli has support for ANSI terminal styling codes, if it is supported by the current streams (with sufficient color depth). Color and styling can be temporarily disabled for each run by setting the NO_COLOR or FORCE_COLOR common environment variables, or the specific STRICLI_NO_COLOR variable which will only affect Stricli applications. The disableAnsiColor config value can also be used to forcibly disable ANSI color codes for all runs of an application, no matter what the environment variables are set to.

Localization

Every single string of text that is printed by a Stricli application can be customized and controlled by the localization configuration. The only exception to this is the internal errors that are thrown by buildApplication if the application configuration itself was invalid in some way.

The context object provided to the run command can optionally include a locale property that will be used to control what text is used by the application. For this section, locale roughly refers to IETF language tag, but since application owners provide both the locale and the text loader that interprets the locale, any locale scheme can be used.

Default Locale

This is the default locale that will be used if the context object does not define its own locale property. If a default locale is not explicitly set in the configuration, it will be en.

Text Loader

The loadText function is responsible for loading the application text object for the requested locale. It can return undefined but doing so will print an error message to stderr and the application will switch to the default locale. If this function returns undefined for the default locale, the application will fail with an internal error.

If this function is not specified, it defaults to a function that will return the default en application text for all en locales.

Application Text

The text for an application is composed of several static values and several dynamic functions for errors. The static values are primarily used for documentation, which includes the section headers (USAGE, COMMANDS, FLAGS, etc.), keywords (optional, default, etc.), and built-in briefs (Print this help information and exit, etc.).

The following are brief descriptions of all of the dynamic functions that accept some arguments and output a string to be printed to stderr. All of these have default implementations in the included en text.

  • currentVersionIsNotLatest

    • Default: Latest available version is {latestVersion} (currently running {currentVersion})
    • This function is called when version info is provided and the current version does not match the latest version. Ideally, this text should include details for how an end user would install that latest version.
  • noTextAvailableForLocale

    • Default: Application does not support "{requestedLocale}" locale, defaulting to "{defaultLocale}"
    • When the context specifies a custom locale and the text loader returned undefined, the application will switch to the default locale. This text (assumed to be in the default locale) will be printed to stderr to notify the user that the requested locale is not available.
  • noCommandRegisteredForInput

    • Default: No command registered for {input}, did you mean {corrections}?
    • This function is called if the scanner is consuming user input and failed to find a command with the provided name. Stricli will internally calculate possible corrections with a distance calculation and pass those as an input to this function.
  • exceptionWhileParsingArguments

    • Default: Unable to parse arguments, {formattedException}
    • This function is called if an exception is thrown while parsing arguments. This generally implies that one of the inputs was invalid. Exceptions intentionally thrown by Stricli while parsing arguments will extend from ArgumentScannerError. You can use formatMessageForArgumentScannerError to customize error messages for those errors.
  • exceptionWhileLoadingCommandModule

    • Default: Unable to load command module, {formattedException}
    • This function is called if an exception is thrown while loading the command module. This generally implies that there is something wrong with the application itself and how it was built/structured.
  • exceptionWhileLoadingCommandContext

    • Default: Unable to load command context, {formattedException}
    • This function is called if an exception is thrown while loading the command context. This will only happen if the context passed to run has a forCommand method to provide a custom command context. This generally implies that there is something wrong with the application itself and how it was built/structured.
  • exceptionWhileRunningCommand

    • Default: Command failed, {formattedException}
    • This function is called if an exception is thrown while the implementation function of a command was running. This could be literally anything depending on the implementation of your application and its commands.
  • commandErrorResult

    • Default: {err.message}
    • This function is called if the command function safely returned an Error instance. Note that if an Error is thrown, then Stricli will call exceptionWhileRunningCommand instead of this function. The Error must be returned from the command function and must satisfy instanceof Error.

Custom Exit Code

When a command's implementation function throws an exception, that triggers a failure which will force the application to return an exit code of 1. If you wish to customize this behavior, you can specify a determineExitCode function in the application config that reads the exception and returns the requested exit code.

Autocomplete

The auto-complete feature) can be customized with the completion configuration.

Alias Support

You can control whether or not aliases will be suggested as possible completions with the includeAliases configuration property. It defaults to match the value of useAliasInUsageLine.

Hidden Route Support

You can control whether or not aliases will be suggested as possible completions with the includeHiddenRoutes configuration property. It defaults to false, and will not expose any hidden route names.