Configurator API
Overview
The Configurator class fills a coordination role, and leverages several other classes to
compose its functionality.
-
The
ConfigurationSchemadefines the configurable fields. -
A
TypeRegistryholds type resolvers -
A
ValidatorRegistryregistry holds field validators. -
A list of
ConfigurationSourceimplementations are used to discover user settings, and convert them to field path assignments to be processed and validated by the schema. -
The
Configuratoris primarily concerned with choreographing the data flow through this pipeline.
Constructor
new Configurator(options)
| Param | Type | Description |
|---|---|---|
[options] | object | Optional settings (described below) |
[options.schema] | ConfigurationSchema | User-provided schema; a new empty schema will be used if undefined |
[options.types] | TypeRegistry | override for default type resolver registry |
[options.validators] | ValidatorRegistry | override for default validator registry |
[options.sources] | Array<ConfigurationSource> | * User-provided source list; omit to use defaults |
[options.configEnabled] | boolean | * Whether to enable configuration file parsing and use the options below (default: true) |
[options.configField] | string | * Defaults to "config"; if defined, adds this field name to hold a config file path |
[options.configFlag] | string | * Flag hint for CommandLineSource; Defaults to "C"; used only if configEnabled |
[options.configDescription] | string | * Help text for configField ("configuration file to load") |
[options.configValueDescription] | string | * Help text describing configField value type ("path") |
(*) advanced extension; not commonly needed
You can add fields to the default schema created by the Configurator constructor, or you can pass in
a schema you have already set up.
If you want to provide an additional ConfigurationSource, you can either register it individually,
or you can provide a complete list of all sources to use. Note that the order of sources does not matter;
the internal sequence property is used to sort their relative priority.
If configEnabled is true (which it is, by default), an additional field is added to the root schema that will hold the pathname to a config file.
The default is to have a field name of config, settable by --config <path> or -C <path> on the command line, or APPNAME_CONFIG=path as an environment variable.
If these defaults conflict, you can change the field.
Methods
async configure(context: object, strict = true) : Promise<object>
returns object (a validated configuration object)
This call runs the complete configuration pipeline:
- Obtain field assignment requests from all registered sources.
- Merge the field assignment requests by source priority.
- Resolve each field assignment value by type, and build a configuration object.
- Validate and return the configuration object.
The context parameter is an object used to pass information to the ConfigurationSource implementations;
since the Configurator doesn't have any special knowledge of individual sources, the "contract" of what
goes in the context is defined per-source. (In general, each source has a default context field name it
uses. See the individual source documentation for details.)
The context may also be mutated by the sources, allowing them to pass information downstream.
| Param | Type | Description |
|---|---|---|
context | object | Context passed to each ConfigurationSource |
[context.appName] | string | Name of your app; technically optional, but highly recommended. |
[context.overrides] | object | Used by a high-priority instance of ObjectSource to override all other sources |
[context.argv] | array | * Private to CommandLineSource; overrides default use of process.argv. |
[context.env] | object | * Private to EnvironmentVariableSource; overrides default use of process.env |
[context.defaults] | object | * Used by a low-priority instance of ObjectSource to hold application defaults (only use to replace schema defaults) |
[context.config] | string | * Mid-configuration field used by JsonFileSource, but generally only set when discovered by sources earlier in the sequence |
[context.____] | * | * The context object is an open object subject to interpretation by the sources |
[strict] | boolean | If false, unknown configuration settings are ignored; if true (the default), they will throw an error |
(*) Not generally needed. Note that all built-in ConfigurationSource implementations provide a means to change the default context field they read.
(Some notable default context fields are appName for your application name, env to override environment variables, argv to override command line options,
and config which sources can use to pass a config file path that was discovered mid-pipeline.
registerConfigurationSource(source: ConfigurationSource)
Add a ConfigurationSource to the list used by this Configurator. Sources are checked that they implement the base class that provides a name and sequence number.
| Param | Type | Description |
|---|---|---|
| source | ConfigurationSource | Source to register |
async processAssignments(fpaList, options:object):object
Process field-path assignment maps generated from sequence of ConfigurationSource implementations.
Generates a candidate configuration object, then calls validate on it.
Returns the validated object, or throws if there are errors.
This method is public, but not generally used unless you are extending Configurator.
| Param | Type | Description |
|---|---|---|
fpaList | Array<Map<string,any>> | list of field-path assignment maps, in source sequence order |
[options] | object | assignment options |
[options.strict] | boolean | strict validation (default: true) |
[options.configuration] | object | initial configuration object |
async validate(inputConfig:object, options:object):object
Validate a candidate configuration object against the schema.
Returns the validated object, or throws if there are errors.
| Param | Type | Description |
|---|---|---|
inputConfig | object | object to validate against the schema |
[options] | object | validation options, described below |
[options.typecheck] | boolean | whether to also typecheck during validation (defaults to true) |
[options.strict] | boolean | enable strict validation (defaults to false) |
[options.populateDefaults] | boolean | enable fallback defaults mode (defaults to false) |
You can skip typechecking if you have already typechecked the assignments .
The strict option will throw an error if unknown fields exist in the
object, or if any types are unknown.
The populateDefaults option provides a fallback method to setting fields in implementations where the DefaultsSource was not used.
This method is public, but not generally used unless you are extending Configurator.
Accessors
| Accessor | Type | Description |
|---|---|---|
schema | ConfigurationSchema | Schema in use by this Configurator |
sources | Array<ConfigurationSource> | List of sources registered |
types | TypeRegistry | Types used by this Configurator |
validators | ValidatorRegistry | Validators used by this Configurator |
You can use the schema accessor to add your fields after the Configurator is constructed, e.g.
these are functionally equivalent:
const types = new TypeRegistry();
types.defineType('BigInt', (value) => BigInt(value))
const validators = new ValidatorRegistry();
validators.register()
const schema = new ConfigurationSchema();
schema.field('verbose', {type: 'boolean'})
const config = new Configurator({schema}).configure();
and
const configurator = new Configurator();
configurator.schema.field('verbose', {type: 'boolean'});
const config = await configurator.configure();
However, the former pattern lends itself to potential reuse of schemas.
Similarly, types and validators can be updated any time before calling configure.