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' }]);
{ // 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}
// Constructor with the Deferrable Interface and the method `read`Functionclass Foo { config: any async read (){ // do any reads and calcs, after that resolve the source this.config = await loadConfig(); }}