Config

Creates a configuration API.
Installation
$ npm install app-etc-config
Usage
var etc = require( 'app-etc-config' );
etc( [options] )
Creates a configuration API.
var config = etc();
The constructor accepts the following options
:
To specify options
,
var config = etc({
'sep': '|',
'create': false,
'schema': require( '/path/to/schema.json' ),
'formats': {
'only-a': /^a+$/
},
'extSchemas': {
'ref_schema1': require( '/path/to/ref_schema1.json' ),
'ref_schema2': require( '/path/to/ref_schema2.json' )
}
});
===
config.set( keypath, value[, options] )
Sets a configuration value at a specified keypath
.
var bool = config.set( 'foo.bar', 'beep' );
The method accepts the following options
:
- sep: keypath separator used when setting configuration values. See utils-deep-set.
- create:
boolean
indicating whether to create a keypath if it does not exist. See utils-deep-set.
Specifying method options
will override the default options
provided during config
creation.
===
config.merge( [keypath,] config[, options] )
Merges a configuration object
or another config
instance.
var bool = config.merge({
'beep': 'boop'
});
If provided a keypath
, the method merges a configuration object with a sub-configuration.
var config2 = etc();
config2.set( 'hello', 'world' );
var bool = config.merge( 'foo', config2 );
If a keypath
does not correspond to an object
, the method returns false
and set()
should be used instead.
var bool = config.merge( 'abcdefg', config2 );
bool = config.set( 'abcdefg', config2 );
The method accepts the following options
:
- sep: keypath separator used when merging nested configuration values. See utils-deep-set.
Specifying method options
will override the default options
provided during config
creation.
===
config.get( [ keypath[, options] ] )
Returns a copy of the raw configuration store.
var obj = config.get();
If provided a keypath
, the method returns a copy of the corresponding configuration value.
var val = config.get( 'foo.hello' );
If a keypath
does not exist, the method returns undefined
.
var val = config.get( 'non.existent.path' );
The method accepts the following options
:
- sep: keypath separator used when getting configuration values. See utils-deep-get.
Specifying method options
will override the default options
provided during config
creation.
===
config.clone( [keypath[, options] ] )
Clones a config
instance.
var config2 = config.clone();
console.log( config2.get() );
console.log( config === config2 );
If provided a keypath
, the method clones a sub-configuration value as a new config
instance.
var config2;
config2 = config.clone( 'foo' );
config2 = config.clone( 'beep' );
If a keypath
does not exist, the method returns undefined
.
var config3 = config.clone( 'non.existent.path' );
The method accepts the following options
:
- sep: keypath separator used when getting configuration values. See utils-deep-get.
Specifying method options
will override the default options
provided during config
creation.
===
config.load( filename )
Convenience method which loads and merges a configuration file.
config.load( '/path/to/config/file.<ext>' );
Note: this method does not directly support loading a configuration file into a sub-configuration. To achieve this, use app-etc-load and then merge
at a specified keypath
.
var load = require( 'app-etc-load' );
var obj = load( '/path/to/config/file.<ext>' );
config.merge( 'foo', obj );
===
config.validate( [validator] )
Validates a configuration.
var out = config.validate();
If a configuration is invalid, the method returns an array
containing validation errors.
out = config.validate();
The method accepts a validator
function, which can be useful for validating against multiple schemas or when a schema
was not provided during initialization. The validator
should accept as its first argument the configuration object
to be validated. The method returns validation results without modification.
var validator = require( 'jsen' );
var schema = require( '/path/to/schema.json' );
var validate = validator( schema, {
'greedy': true
});
var out = config.validate( validate );
console.log( out );
console.log( validate.errors );
If a schema
option was not provided during initialization and a validator
is not provided at runtime, the method always returns true
.
var config = etc();
config.set( 'port', 80 );
var out = config.validate();
===
etc.exts()
Returns a list of supported filename extensions.
var exts = etc.exts();
For more details, see app-etc-load.
etc.parser( extname[, parser] )
Returns a parser for the specified extension.
var parser = etc.parser( '.json' );
Including the .
when specifying an extension is optional.
var parser = etc.parser( 'json' );
To support additional file formats or to override a parser, provide a parser
function for an associated extension.
var parser = require( 'my-special-fmt-parser' );
etc.parser( '<my-ext>', parser );
Once a parser is set, all config
instances will parse provided files accordingly.
config.load( './file.<my-ext>' );
For more details, see app-etc-load.
Notes
-
This module uses jsen for validating an internal configuration object
against a JSON schema. One compelling feature of jsen is the ability to extend a schema definition by specifying custom error messages. For example, given the following schema,
{
"type": "object",
"definitions": {
"port": {
"description": "schema for a port",
"type": "integer",
"minimum": 1024,
"maximum": 65536,
"requiredMessage": "port is required",
"messages": {
"type": "invalid type. Must be an integer.",
"minimum": "invalid value. Must be an integer greater than or equal to 1024.",
"maximum": "invalid value. Must be an integer less than or equal to 65536."
}
}
},
"properties": {
"port": {
"$ref": "#/definitions/port"
}
},
"required": [
"port"
],
"messages": {
"type": "invalid data type where an object is expected"
}
}
validation will return more informative error messages based on keywords.
var validator = require( 'jsen' );
var validate = validator( schema );
var bool = validate({
'port': 80
})
console.dir( validate.errors );
Examples
var etc = require( 'app-etc-config' );
var config = etc();
config.load( './.travis.yml' );
console.dir( config.get() );
config.load( './package.json' );
console.dir( config.get() );
config.merge( 'author', {
'beep': 'boop'
});
console.dir( config.get( 'author' ) );
console.log( config.get( 'license' ) );
console.log( config.get( 'author.name' ) );
config.set( 'hello', false );
console.log( config.get( 'hello' ) );
config.set( 'foo.bar.bip', 'bap', {
'create': true
});
console.log( config.get( 'foo.bar.bip' ) );
var clone = config.clone();
console.log( config === clone );
To run the example code from the top-level application directory,
$ node ./examples/index.js
Tests
Unit
Unit tests use the Mocha test framework with Chai assertions. To run the tests, execute the following command in the top-level application directory:
$ make test
All new feature development should have corresponding unit tests to validate correct functionality.
Test Coverage
This repository uses Istanbul as its code coverage tool. To generate a test coverage report, execute the following command in the top-level application directory:
$ make test-cov
Istanbul creates a ./reports/coverage
directory. To access an HTML version of the report,
$ make view-cov
License
MIT license.
Copyright
Copyright © 2015. Athan Reines.