all files / app/ index.js

94.87% Statements 74/78
76.47% Branches 26/34
100% Functions 11/11
94.87% Lines 74/78
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 128 129 130                                                                                                                
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, opts) {
  var mappings = cev.generate(object || {}, opts || { 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
var opts = {}
Iif (yaktor.env && yaktor.env.prefix) {
  opts.prefix = yaktor.env.prefix
  debug('using environment variable prefix "' + opts.prefix + '"')
} else {
  opts.noPrefix = true
  debug('using no environment variable prefix')
}
_.merge(yaktor, getConfigEnvironmentVariables(yaktor, opts))
debug('configuration after overriding from environment variables:')
debug(JSON.stringify(yaktor, 0, 2))
 
module.exports = yaktor