all files / pnr-common/lib/node/ configReader.js

50% Statements 26/52
13.04% Branches 3/23
66.67% Functions 6/9
50% Lines 26/52
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                            22× 22×                                                           22×       22×     184×                                                                                                          
'use strict';
 
var fs = require('fs');
var ini = require('ini');
var merge = require('recursive-merge');
var _ = require('lodash');
 
/**
 * @private
 * @function readConfig
 *
 * @description Reads file and parses ini
 *
 * @param {string} filename
 * @param {boolean} mustExist throws exception on missing
 *
 * @returns {object}
 */
function readConfig(filename, mustExist) {
   try {
      return ini.parse(fs.readFileSync(filename, 'utf8'));
   } catch(e) {
      Iif (mustExist) {
         throw e;
      }
      return {};
   }
}
 
/**
 * @public
 * @function configReader
 *
 * @description Reads and merge multiple configuration files
 *              Files passed in first take the highest presidence.
 *
 * @example: configReader(['a.ini', 'b.ini'])
 *           if a.ini and b.ini have same config var, a.ini is used
 *
 * if mustPass is true and no files exist, returns empty object {}
 *
 * @param {array|string} filenames
 * @param {boolean} mustExist raises error if filename is missing
 *
 * @returns {object}
 */
const ConfigReader = function(filenames, mustExist) {
   const _this = this;
   Iif (!filenames) {
      throw new Error('no config filenames specified');
   }
 
   Iif (!_.isArray(filenames)) {
      filenames = [filenames];
   }
 
   var configs = _(filenames).map(function(filename) {
      return readConfig(filename, mustExist);
   }).value();
 
   var configData = {};
 
   _.each(configs, function(c) {
      merge(configData, c);
   });
 
   _.each(configData, function(values, key) {
      _this[key] = values;
   });
 
   return _this;
};
 
ConfigReader.prototype.getString = function (section, option, def_val) {
   const _this = this;
   try {
      const sec = _this[section];
      if (sec === undefined) {
         throw new Error('no section: [' + section + '] for: '  + option);
      }
      const val = sec[option];
      if (val === undefined) {
         throw new Error('config not found: [' + section + '].' + option);
      }
      return String(val).trim();
   } catch(e) {
      if (typeof def_val === 'undefined') {
         throw e;
      }
      return def_val;
   }
};
 
ConfigReader.prototype.getNumber = function (section, option, def_val) {
   const _this = this;
   const val = _this.getString(section, option, def_val);
   if (isNaN(val)) {
      throw new Error('config [' + section + '].' + option + ' NaN: ' + val);
   }
   return Number(val);
};
 
ConfigReader.prototype.getBoolean = function (section, option, def_val) {
   const _this = this;
   const val = _this.getString(section, option, def_val);
 
   switch (String(val).toLowerCase()) {
   case 'true':
   case 'yes':
   case 'on':
   case '1':
      return true;
   case 'false':
   case 'no':
   case 'off':
   case '0':
      return false;
   default:
      throw new Error('config [' + section + '].' + option + ' not bool: ' + val);
   }
};
 
module.exports = function(filenames, mustExist) {
   return new ConfigReader(filenames, mustExist);
};