This repository has been archived on 2018-10-12. You can view files and clone it, but cannot push or open issues or pull requests.
ProgBlog/app/base/Config.js
2016-02-19 12:58:16 -05:00

181 lines
3.7 KiB
JavaScript

'use strict';
const container = require('../Container');
const path = container.get('path');
// Load environment file
require('dotenv').config({
path: path.resolve(__dirname, '../../.env'),
});
const fs = require('fs');
const glob = require('glob');
const configSslPath = path.resolve(__dirname, '../config/ssl');
const configPath = path.resolve(__dirname, '../config');
const defaultConfig = new Map([
['host', 'localhost'],
['http', true],
['http-port', 80],
['https', false],
['https-port', 443],
['node-env', 'development'],
]);
const configFiles = glob.sync(`${configPath}/**/*.js`);
/**
* Config management class
*
* Hierarchy of config options
* 1. Directly defined config options
* 2. Environment variables
* 3. Default values
*/
class Config {
constructor() {
let _configMap = new Map();
// Load files in config folder under their
// own respective namespaces
configFiles.forEach((fullPath) => {
let key = path.basename(fullPath, '.js');
_configMap.set(key, require(fullPath));
});
this._config = _configMap;
}
/**
* Returns the list of available configuration keys
*
* @return {array} - the list of configuration keys
*/
keys() {
let keys = [];
for (let key of this._config.keys()) {
keys.push(key);
}
return keys;
}
/**
* Determine if a config value exists
*
* @param {string|symbol} key - the config value key
* @return {boolean} - whether the config value exists
*/
has(key) {
return this._config.has(key);
}
/**
* Determine whether an environment variable is currently defined
*
* @param {string} key - the environment varaible to look for
* @return {boolean} - whether the environment variable is defined
*/
hasEnv(key) {
return process.env[this._envName(key)] != null;
}
/**
* Retrieve a config value
*
* @param {string|symbol} key - the name of the config value
* @return {*} - the configuration value
*/
get(key) {
if (! this.has(key)) {
// Fallback to environment variables
let envKey = key.toUpperCase().replace('-', '_');
if (this.hasEnv(envKey)) {
let envValue = this.getEnv(envKey);
this._config.set(key, envValue);
return envValue;
}
// Fallback to default values
if (defaultConfig.has(key)) {
let defaultValue = defaultConfig.get(key);
this._config.set(key, defaultValue);
return defaultValue;
}
}
return this._config.get(key);
}
/**
* Get the value of an environment variable
*
* @param {string} key - the environment variable to get
* @return {string|undefined} - the value of the environment variable
*/
getEnv(key) {
let raw = process.env[this._envName(key)];
return this._normalizeValue(raw);
}
/**
* Get equivalent environment variable for config key
*
* @private
* @param {string} key - the config key
* @return {string} - the environment variable name
*/
_envName(key) {
return key.toUpperCase().replace('-', '_');
}
/**
* Attempt to parse javascript types from strings
*
* @private
* @param {string} val - the string value
* @return {string|number|boolean} - the 'parsed' value
*/
_normalizeValue(val) {
let bool = /^true|false$/;
let integer = /^([0-9]+)$/;
if (String(val).search(integer) !== -1) {
return parseInt(val, 10);
}
if (String(val).search(bool) !== -1) {
switch (val) {
case 'true':
return true;
// return overrides break
case 'false':
return false;
// return overrides break
}
}
return val;
}
/**
* Set a config variable (mainly for testing)
*
* @private
* @param {mixed} key - the key to set
* @param {mixed} val - the value for the key
* @return {Config} - the config instance
*/
_set(key, val) {
this._config.set(key, val);
return this;
}
}
module.exports = new Config();