all files / app/ index.js

97.22% Statements 70/72
82.14% Branches 23/28
100% Functions 11/11
97.22% Lines 70/72
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                                                                                                            
var path = require('path')
var async = require('async')
var _ = require('lodash')
var cev = require('config-cev-generator')
var debug = require('debug')('yaktor:config')
 
var globals
var servers
var yaktor = {
  start: function (configuration, startDone) {
    Iif (typeof configuration === 'function') {
      startDone = configuration
      configuration = {}
    }
    // now override from given configuration parameter
    debug('supplied configuration object:')
    debug(JSON.stringify(configuration, 0, 2))
    _.merge(yaktor, configuration)
 
    // configuration overriding is done
    debug('resolved yaktor configuration:')
    debug(JSON.stringify(yaktor, 0, 2))
 
    async.series([
      async.apply(globals.init, yaktor), // call global initializers
      function (serversDone) { // initialize all the servers
        yaktor.serverContexts = {}
        async.eachSeries(Object.keys(yaktor.servers), function (serverName, nextServer) {
          var server = yaktor.servers[ serverName ]
          var ctx = _.cloneDeep(server)
          // this allows a server to get at other servers' contexts via require('yaktor').serverContexts['...']....
          yaktor.serverContexts[ serverName ] = ctx
          ctx.serverName = serverName
          Object.keys(yaktor).forEach(function (setting) {
            switch (setting) {
              case 'start': // the function you're currently in
              case 'servers': // settings for all servers
              case 'serverContexts': // yaktor's bucket for all server contexts
                return // skip because these aren't appropriate for the current server context
 
              default: // merge copy of global context into server context with server context winning any conflicts
                ctx[ setting ] = _.merge(_.cloneDeep(yaktor[ setting ]), ctx[ setting ] || {})
                return
            }
          })
          servers[ serverName ].init(ctx, nextServer)
        }, serversDone)
      },
      function (engineDone) {
        require('./engine')([ path.resolve('conversations', 'js') ], engineDone)
      }
    ], startDone)
  }
}
 
var getConfigDefaults = function (opts) {
  opts = opts || { global: true, servers: true }
  var defaults = {}
  Eif (opts && opts.global) {
    Object.keys(globals.settings).forEach(function (key) {
      defaults[ key ] = globals.settings[ key ]
    })
  }
  Eif (opts && opts.servers) {
    defaults.servers = {}
    Object.keys(servers).forEach(function (serverName) {
      defaults.servers[ serverName ] = servers[ serverName ].settings
    })
  }
  return defaults
}
 
var getConfigEnvironmentVariables = function (object) {
  var mappings = cev.generate(object || {}, {
    noPrefix: true
  })
  debug('environment variable mappings:')
  debug(JSON.stringify(mappings, 0, 2))
 
  var walkMappings = function (mappings, configPrefix) {
    configPrefix = configPrefix || []
 
    Object.keys(mappings).forEach(function (key) {
      switch (typeof mappings[ key ]) {
        case 'string':
          var envarName = mappings[ key ]
          var envarValue = process.env[ envarName ]
          if (envarValue) {
            mappings[ key ] = envarValue
            debug('replaced configuration setting "' + configPrefix.concat(key).join('.') + '" with value "' + envarValue + '" from environment variable "' + envarName + '"')
          } else {
            delete mappings[ key ]
            debug('no value found in environment variable "' + envarName + '" for configuration setting "' + configPrefix.concat(key).join('.') + '"')
          }
          break
        case 'object':
          mappings[ key ] = walkMappings(mappings[ key ], configPrefix.concat(key))
          Eif (Object.keys(mappings[ key ]).length === 0) {
            delete mappings[ key ]
          }
          break
      }
    })
    return mappings
  }
  return walkMappings(mappings)
}
 
// this is all static so load it now and make available early
globals = require(path.resolve('config', 'global'))
servers = require(path.resolve('config', 'servers'))
 
// get default configuration values and put them on yaktor
_.merge(yaktor, getConfigDefaults())
debug('configuration defaults:')
debug(JSON.stringify(yaktor, 0, 2))
 
// now override from environment variables
_.merge(yaktor, getConfigEnvironmentVariables(yaktor))
debug('configuration after overriding from environment variables:')
debug(JSON.stringify(yaktor, 0, 2))
 
module.exports = yaktor