expresser
Version:
A ready to use Node.js web app wrapper, built on top of Express.
107 lines (86 loc) • 4.32 kB
text/coffeescript
# EXPRESSER
# -----------------------------------------------------------------------------
# A platform for Node.js web apps, built on top of Express.
# If you need help check the project page at http://github.com/igoramadas/expresser.
class Expresser
fs = require "fs"
path = require "path"
# Set application root path.
rootPath: path.dirname require.main.filename
# Preload the main modules. App must be the last module to be set.
settings: require "./lib/settings.coffee"
utils: require "./lib/utils.coffee"
events: require "./lib/events.coffee"
logger: require "./lib/logger.coffee"
database: require "./lib/database.coffee"
app: require "./lib/app.coffee"
# Expose 3rd party modules.
libs:
async: require "async"
lodash: require "lodash"
moment: require "moment"
# Helper to load default modules. Basically everything inside the lib folder.
initDefaultModules = (self, options) ->
for id, m of self
if id isnt "app" and m?.init? and self.settings[id]?.enabled
self[id].init? options?[id]
# Helper to load plugins. This will look first inside a /plugins
# folder for local development setups, or directly under /node_modules
# for plugins installed via NPM (most production scenarios).
loadPlugins = (self, options) ->
if fs.existsSync "#{__dirname}/plugins"
pluginsFolder = true
plugins = fs.readdirSync "#{__dirname}/plugins"
else
pluginsFolder = false
plugins = fs.readdirSync "#{self.rootPath}/node_modules"
plugins.sort()
# Iterate plugins and get it's ID by removing the "expresser-" prefix.
for p in plugins
pluginId = p.substring(p.lastIndexOf("/") + 1)
if pluginsFolder or pluginId.substring(0, 10) is "expresser-"
pluginName = pluginId.replace "expresser-", ""
# Check if plugin was already attached.
if not self[pluginName]?
if pluginsFolder
self[pluginName] = require "./plugins/#{pluginId}"
pluginSettingsPath = "#{__dirname}/plugins/#{p}/settings.default.json"
else
self[pluginName] = require pluginId
pluginSettingsPath = "#{self.rootPath}/node_modules/#{pluginId}/settings.default.json"
# Attach itself to the plugin.
self[pluginName].expresser = self
# Check if there are default settings to be loaded for the plugin.
if fs.existsSync pluginSettingsPath
self.settings.loadFromJson pluginSettingsPath, true
options = self.libs.lodash.defaults options, self.settings
# Get options accordingly to plugin name. For example the expresser-database-mongo
# should have its options set under settings.database.mongo.
pluginArr = pluginName.split "-"
optionsRef = options
i = 0
while i < pluginArr.length
optionsRef = optionsRef?[pluginArr[i]]
i++
# Init plugin only if enabled is not set to false on its settings.
if optionsRef?.enabled
self[pluginName].init? optionsRef
# Helper to init all modules. Load settings first, then Logger, then general
# modules, and finally the App. The `options` can have properties to be
# passed to the `init` of each module.
# @param [Object] options Options to be passed to each init module.
init: (options) =>
options = {} if not options?
initDefaultModules this, options
loadPlugins this, options
# App must be the last thing to be started!
# The Firewall and Sockets modules are initiated inside the App
# depending on their settings.
@app.expresser = this
@app.init options?.app
# Singleton implementation
# --------------------------------------------------------------------------
Expresser.getInstance = ->
@instance = new Expresser() if not @instance?
return @instance
module.exports = exports = Expresser.getInstance()