UNPKG

@axway/api-builder-runtime

Version:

API Builder Runtime

105 lines (92 loc) 3.09 kB
const fs = require('fs'); const path = require('path'); const _ = require('lodash'); const requireUncached = require('require-uncached'); const envRegex = /^(.*\.)?(default|local)\.js$/; const envLoader = require('dotenv'); /** * Loads up the configuration files in to the global $config object. */ function Loader(logger, options = {}) { let { dirname } = options; const { defaultConfig, configOverrides } = options; const configFiles = []; // dirname is the configuration directory path dirname = dirname && fs.existsSync(dirname) && path.basename(dirname) === 'conf' ? dirname : path.join(dirname || process.cwd(), 'conf'); // Loads environment variables described in .env if the file exists const envFilePath = path.join(dirname, '.env'); if (fs.existsSync(envFilePath)) { envLoader.config({ path: envFilePath }); } // merge in defaultConfig let config = { dir: path.dirname(dirname) }; if (defaultConfig && _.isObject(defaultConfig)) { config = _.merge(defaultConfig, config); } // Process all the other config files found fs.existsSync(dirname) && fs.readdirSync(dirname) .filter(n => /\.js$/.test(n)) .forEach(fn => { // only local and default config files allowed if (envRegex.test(fn) && !fn.startsWith('.')) { const file = path.join(dirname, fn); configFiles.push(file); } else { const confStr = `conf${path.sep}`; logger.warn(`skipping ${confStr}${fn}. Use ${confStr}local.js or ${confStr}default.js`); } }); const orderedConfigs = sortConfig(configFiles); if (orderedConfigs.length === 0) { logger.debug('no configuration files loaded'); } else { logger.debug(`configuration applied in this order: ${orderedConfigs}`); } // now merge them in the right order orderedConfigs.forEach(file => { mix(config, requireUncached(file)); }); if (configOverrides) { mix(config, configOverrides); } return config; } const sortConfig = (configs) => { const configsMap = {}; configs.forEach(fn => { const name = path.basename(fn); const match = envRegex.exec(name); if (match) { const envName = match[2]; configsMap[envName] = (configsMap[envName] || []).concat(fn); } }); // Sort both default and local groups configsMap.default && configsMap.default.sort(); configsMap.local && configsMap.local.sort(); // now combine the config file lists, local will override any defaults const ordered = (configsMap.default || []) .concat(configsMap.local || []); return ordered; }; /** * Combines the src object into the dest object * AH: not sure why we are using _.merge and this in the same file. We should * look to remove this and replace it with _.merge. * @param {Object} dest - The destination object getting updated * @param {Object} src - The object to pull properties from */ const mix = (dest, src) => { Object.keys(src).forEach(function (p) { if (dest.hasOwnProperty(p) && Object.prototype.toString.call(dest[p]) === '[object Object]') { mix(dest[p], src[p]); } else { dest[p] = src[p]; } }); }; Loader.sortConfig = sortConfig; module.exports = Loader;