appcfg
v0.5.4
Published
Application Configuration Library for Node.js
Downloads
10,167
Readme
Application Configuration Library for Node.js and Browser
About
Load and Combine Configuration from many sources:
- Files
- JavaScript Module
- JSON
- Yaml
- ENV +
.env
- S3 Storage
- Directory (combine files)
- MongoDB
Additional features:
When combining objects from many sources, deep copy is used:
// a
{ sub: { foo: 'foo' }, arr: [ 'foo' ] }
// b
{ sub: { bar: 'bar' }, arr: [ 'bar' ] }
// combined (a + b)
{
sub: { foo: 'foo', bar: 'bar'},
arr: ['foo', 'bar']
}
// E.g you want completely to overwrite `arr` property, then prefix the key's name with `!`
// a
{ sub: { foo: 'foo' }, arr: [ 'foo' ] }
// b
{ sub: { bar: 'bar' }, '!arr': [ 'bar' ] }
// combined (a + b)
{
sub: { foo: 'foo', bar: 'bar'},
arr: ['bar']
}
Example:
import AppCfg from 'appcfg'
const config = await AppCfg.fetch([
// from file. (with Special Folder format syntax support)
{
path: '%APPDATA%/.appName/config.yml',
// set this source as writable for configuration persistance
writable: true
},
// ENV + .env
{
dotenv: true,
// per default CWD is checked, can be overriden
path: './foo/bar/'
},
// directory
{
path: 'defaults/**.yml'
},
// mongodb
{
mongo: 'barSettings'
},
// from file, but use only nested property
{
path: 'package.json',
getterProperty: 'atma'
}
]);
Command Line overrides
Command line arguments are parsed and also set to the configuration object.
$ node app --foo.bar barValue --debug
let config = await Config.fetch(someSources);
assert.has(config, {
foo: {
bar: 'barValue'
},
debug: true
})
Conditions
Yaml conditions example. (same is also for json format)
# conditional root configuration example
'#if debug':
name: Foo
host: dev.example.com
'#if test':
name: Baz
host: localhost
# conditional property example
port:
'#if debug': 5000
'#if test': 5030
'default': 8080
# conditional array item example
scipts:
- lib.js
- '#if debug || test'
- lib.debug-extension.js
Arguments lookup:
- in configuration object
- in cli overrides
- in
process.env
- compare value as string from
process.env.ENV
# from cli example
$ node app --debug
# from environment
$ set ENV=DEBUG
$ node app
{
name: 'Foo',
host: 'localhost',
port: 5000,
scripts: [
"lib.js",
"lib.debug-extension.js"
]
}
Special Folder
Use special folders for loading/writing configurations, like %APPDATA%
or %HOME%
.
Is system agnostic and is parsed from the environment variables.
Config.fetch({
path: '%APPDATA%/.myApplication/global.yml',
writable: true
});
Interpolations
Sometimes to not repeat the configuration it is convenient to use interpolations. It will embed configuration from itself.
# someConfig.yml
name: 'Foo'
A:
lorem: '#[name]'
B:
ipsum: '#[A.lorem]'
let config = await Config.fetch({
path: 'someConfig.yml'
});
assert.has(config, {
name: 'Foo',
A: { lorem: 'Foo' },
B: { ipsum: 'Foo' }
});
API
Config
static
.fetch(Array<Source>)
=> Config Instance
Start loading the configuration from specified sources, returns new deferrable configuration instance
methods
<Constructor> (Array<Source>)
.$read(?Mix)
Mix
:String
: File/Directory/Glob pathSource
: Source objectArray<Source>
@default
- Array taken from constructor
@return
:self
. Is deferrable, so you can attachdone
callbacks to it.
Load configuration from sources
.$write(config:Object [, ?deepExtend:Boolean, ?setterPath:String):Deferred
Update and save the configuration. Use first matched writable source.
deepExtend
: complex objects and arrays are mergedsetterPath
: define nested object in current configuration
.$get(property:String)
property
: Dot delimited accessorconfig.$get('foo.bar.quux')
// is the same as you if you would write null-check expressions yourself: var quuxVal = config.foo && config.foo.bar && config.foo.bar.quux;
@return
: null or value
.$is(name:String):Boolean
Check conditional environment variable, e.g.:
config.$is('debug')
Ways to define the variables. (Example defines DEBUG and TEST flags)
- directly in the configuration
// foo.yml debug: true test: true
- from the command line:
> node index --debug --test
- using environment configuration(comma delimited)
$ set ENV=DEBUG,TEST # also $ set NODE_ENV=DEBUG,TEST $ node index
- directly in the configuration
.toJSON():Object
Returns clean json configuration object.
.done(callback)
Fire the callback when the configuration is loaded
Source
Common properties for all source types
{
// Define specific property to extract SUB-JSON from the loaded configuration
// @default: null
getterProperty: String
// Define specific property in the root configuration,
// where the loaded configuration should be inserted into
// @default: null
setterProperty: String
// Specify if this source can be used for persistence
// @default: false
writable: Boolean
// Fires before source $read function is called
// (e.g. change this.path property or any other things)
beforeRead: Function<Source, RootConfig>
// Fires after source completes reading
// (e.g. access config object in `Source.config`)
afterRead: Function<Source, RootConfig>
// If true, do not log any warning if the source returns 404
// @default: false
optional: true
// If true, then waits until all previous sources are loaded
// @default: false
sync: true
}
FileSource
{
// File path
path: String
}
DirectorySource
It will be mapped to multiple FileSources
{
// Directory path with GLOB look-up, e.g. 'configs/**.json'
path: String
}
MongoDBSource
Depends on ClassJS
{
// Collection name
mongo: String,
// if source is writable
// @default: true
writable: Boolean
// MongoDB Connection Settings
// It can be also specified in previous configuration source, under `mongodb` property
// @default: null -
settings: {
// connection string
connection: String
// or
// Port, default 27017
port: Number,
// IP, default '127.0.0.1'
ip: String,
// Database name, no default
db: String
}
}
CustomSource
This source type can suit any needs.
// Constructor with the Deferrable Interface and the method `read`
Function
class Foo {
config: any
async read (){
// do any reads and calcs, after that resolve the source
this.config = await loadConfig();
}
}
Embedded
Include config direct into the source
{
config: Object
}
Test
$ npm install
$ npm test
(c) 2014-2022 MIT License