var parser = function(val) {
var parsedVal;
try {
parsedVal = JSON.parse(val);
if (typeof val === typeof parsedVal) {
val = parsedVal;
}
else if (val === parsedVal.toString()) {
val = parsedVal;
}
else if (Array.isArray(parsedVal)) {
val = parsedVal;
}
else if (typeof parsedVal === 'object') {
val = parsedVal;
}
}
catch (error) {
//ignored error
}
return val;
};
const OVERRIDES = {
MONGODB: {
REPLSETSERVERS: 'replSetServers',
REPLICANAME: 'replicaName',
MAX_POOL_SIZE: 'max_pool_size',
DBOPTIONS: 'dbOptions',
SERVEROPTIONS: 'serverOptions'
},
API: {
MAX_SOCKETS: 'max_sockets',
},
WEB: {
USE_INTERCOM: 'use_intercom',
SECURE_COOKIES: 'secure_cookies'
},
IGNOREPROXIES: 'ignoreProxies',
FILESTORAGE: 'fileStorage',
RELOADCONFIGAFTER: 'reloadConfigAfter'
};
/**
* Digs one level down in config document
*
* @param {object} config - config to traverse
* @param {object} over - override object
* @param {string} name - name of config to override
* @param {varies} value - value to set to config
* @return {object} recursive config modification
*/
function dig(config, over, name, value) {
let comps = name.split('_');
for (let i = comps.length; i > 0; i--) {
let n = comps.slice(0, i).join('_');
if (n in over) {
let sub;
if (typeof over[n] === 'string') {
sub = over[n];
over[n] = {};
}
else {
sub = Object.keys(config).filter(k => k.toUpperCase() === n)[0];
}
name = comps.slice(i).join('_');
if (!name || comps.length === 1) {
config[sub] = value;
return true;
}
if (typeof config[sub] === 'object') {
return dig(config[sub], over[n], name, value);
}
else if (sub) {
config[sub] = {};
return dig(config[sub], over[n], name, value);
}
else {
config[n] = {};
return dig(config[n], over[n], name, value);
}
}
else if (n === over) {
name = over;
config[name] = value;
return true;
}
}
for (let i = 1; i <= comps.length; i++) {
let n = comps.slice(0, i).join('_'),
sub = Object.keys(config).filter(k => k.toUpperCase() === n)[0],
name2 = comps.slice(i).join('_');
if (sub) {
if (comps.length === 1) {
config[sub] = value;
return true;
}
else {
config[sub] = typeof config[sub] === 'object' ? config[sub] : {};
return dig(config[sub], {}, name2, value);
}
}
}
comps.forEach((c, i) => {
if (i === comps.length - 1) {
config[c.toLowerCase()] = value;
}
else {
config = config[c.toLowerCase()] = {};
}
});
return true;
}
module.exports = function(mode, config, opts, over) {
// back compatibility
if (typeof mode === 'object') {
config = mode;
mode = 'API';
opts = process.env;
}
if (['API', 'FRONTEND'].indexOf(mode) === -1 && mode.indexOf('PLUGIN') !== 0) {
throw new Error('Invalid config mode ' + mode);
}
config = JSON.parse(JSON.stringify(config));
Object.keys(opts).filter(n => n.indexOf(`COUNTLY_CONFIG_${mode}_`) === 0 || n.indexOf(`COUNTLY_CONFIG__`) === 0).forEach(n => {
let comps = n.split('_').slice(3);
dig(config, Object.assign(JSON.parse(JSON.stringify(OVERRIDES)), over || {}), comps.join('_'), parser(opts[n]));
});
return config;
};