src/ConfigResolver.js
/**
* The Config Resolver is the central manager for configurations.
* It offers the functionality to resolve configuration entries based on the injected config path.
*
* @author Wolfgang Felbermeier (@f3lang)
*/
class ConfigResolver {
constructor(configs) {
this.configs = configs || {};
this.cache = {};
}
/**
* Adds a new configuration to the collection
* @param configuration The configuration object
* @param root The configuration root name
*/
addConfiguration(configuration, root) {
this.configs[root] = configuration;
}
/**
* Returns a configuration entry of the available configurations
* @param root The configuration root to look in
* @param path The path of the configuration to return
* @return {*}
*/
getConfig(root, path) {
if (root === '' && path === '') {
return this.configs;
}
if (this.cache[root + ":" + path]) {
return this.cache[root + ":" + path]
}
if (!this.configs[root]) {
throw new Error('Configuration root "' + root + '" does not exist');
}
if (path === "" || path === ".") {
return this.configs[root];
}
try {
let property = this._getProperty(this.configs[root], path.split('.'));
this.cache[root + ":" + path] = property;
return property;
} catch (e) {
throw new Error('Configuration path "' + path + '" does not exist in configuration root "' + root + '"');
}
}
/**
* Returns the next available property of obj.
* e.g.:
* Your obj:
* {
* banana: {
* fruit: {
* price: 1
* }
* }
* }
* and your path will be ['banana', 'fruit', 'price']
* Then this function will return 1
*
* @param obj
* @param propertyPathArray
* @private
*/
_getProperty(obj, propertyPathArray) {
if (propertyPathArray.length === 1) {
return obj[propertyPathArray[0]];
} else {
return this._getProperty(obj[propertyPathArray.shift()], propertyPathArray);
}
}
}
module.exports = ConfigResolver;
module.exports.inject = ['config::'];