multiconf
Version:
Work with JSON configs
154 lines (132 loc) • 4.76 kB
JavaScript
// Import.
const fs = require('fs');
const path = require('path');
const JSONCParser = require('./lib/jsonc-parser');
// Constants.
const DEFAULT_CONF_FILES_DIRECTORY = './conf';
const CONF_ENCODING = 'utf8';
const JSONC_CONF_FILES_EXTENSION = '.jsonc';
const CONF_FILES_EXTENSION = '.json';
const DEFAULT_CONF_FILES_EXTENSION = '.json.default';
/**
* Config.
*/
class Config {
/**
* Get.
* @param {string} [configDir] Config directory.
* @param {string} [envConfigPrefix] Environment config prefix.
* @returns {object} Config object.
*/
static get(configDir = DEFAULT_CONF_FILES_DIRECTORY, envConfigPrefix) {
// Define config object container.
const configObject = {};
// Append file configs if need it.
FileConfigs.append(configObject, configDir);
// Append environment configs if need it.
EnvConfigs.append(configObject, envConfigPrefix);
// Return config object.
return configObject;
}
static getDefault(configDir = DEFAULT_CONF_FILES_DIRECTORY) {
// Define config object container.
const configObject = {};
// Append file configs if need it.
FileConfigs.append(configObject, configDir, true);
// Return config object.
return configObject;
}
}
/**
* File configs.
*/
class FileConfigs {
/**
* Append configs from files.
* @param {object} configObject Config object to handle.
* @param {string} confDir Config directory.
* @returns {object} Config object.
*/
static append(configObject, confDir, defaultOnly = false) {
// Get files from config directory.
const files = fs.readdirSync(confDir, CONF_ENCODING);
// Handle config files.
for (let i = 0; i < files.length; i++) {
// File name.
const file = files[i];
// If user-defined JSONC config.
if (file.endsWith(JSONC_CONF_FILES_EXTENSION) && !defaultOnly) {
const jsonConf = fs.readFileSync(path.join(confDir, file), CONF_ENCODING);
const confName = file.substring(0, file.length - JSONC_CONF_FILES_EXTENSION.length);
try {
configObject[confName] = JSONCParser.parse(jsonConf);
} catch (error) {
throw new Error(`Can't parse user-defined config "${confName}".\n${error}`);
}
}
// If user-defined JSON config.
if (file.endsWith(CONF_FILES_EXTENSION) && !defaultOnly) {
const jsonConf = fs.readFileSync(path.join(confDir, file), CONF_ENCODING);
const confName = file.substring(0, file.length - CONF_FILES_EXTENSION.length);
if (configObject[confName] === undefined) {
try {
configObject[confName] = JSON.parse(jsonConf);
} catch (error) {
throw new Error(`Can't parse user-defined config "${confName}".\n${error}`);
}
}
}
// If default config.
if (file.endsWith(DEFAULT_CONF_FILES_EXTENSION)) {
const jsonConf = fs.readFileSync(path.join(confDir, file), CONF_ENCODING);
const confName = file.substring(0, file.length - DEFAULT_CONF_FILES_EXTENSION.length);
if (configObject[confName] === undefined) {
try {
configObject[confName] = JSON.parse(jsonConf);
} catch (error) {
throw new Error(`Can't parse default config "${confName}".\n${error}`);
}
}
}
}
// Return object with appends.
return configObject;
}
}
/**
* Environment configs.
*/
class EnvConfigs {
/**
* Append configs from environment by prefix.
* @param {object} configObject Config object to handle.
* @param {string} [envConfigPrefix] Environment config prefix.
* @returns {object} Config object.
*/
static append(configObject, envConfigPrefix) {
// Check.
if (typeof configObject !== 'object' || typeof envConfigPrefix !== 'string') { return; }
// Get environment params.
for (const envParamKey in process.env) {
// Do not handle if without needed prefix.
if (!envParamKey.startsWith(envConfigPrefix)) { continue; }
// Define config key.
const configKey = envParamKey.substring(envConfigPrefix.length);
const lowerCaseConfigKey = configKey.toLowerCase();
// Define config value.
const configValue = process.env[envParamKey];
// Try to parse and append config value. Keep original string if can not parse.
try {
const configValueObject = JSON.parse(configValue);
configObject[configKey] = configValueObject;
configObject[lowerCaseConfigKey] = configValueObject;
} catch (error) {
throw new Error(`Can't parse env config "${envParamKey}".\n${error}`);
}
}
// Return object with appends.
return configObject;
}
}
// Export.
module.exports = Config;