choreo
Version:
A Robotics Framework
169 lines (122 loc) • 3.74 kB
JavaScript
/**
* Module dependencies.
*/
var _ = require('lodash');
var async = require('async');
module.exports = function (choreo) {
/**
* Expose hook constructor
*
* @api private
*/
return Hook;
function Hook(definition) {
/**
* Load the hook asynchronously
*
* @api private
*/
this.load = function (cb) {
var self = this;
var routeCallbacks = function (routes) {
_.each(routes, function (middleware, route) {
middleware._middlewareType =
self.identity.toUpperCase() + ' HOOK' +
(middleware.name ? (': ' + middleware.name) : '');
choreo.router.bind(route, middleware);
});
};
// Determine if this hook should load based on Choreo environment
// & hook config
if (this.config.envs &&
this.config.envs.length > 0 &&
this.config.envs.indexOf(choreo.config.environment) === -1) {
return cb();
}
// Convenience config to bind routes before any of the static app routes
choreo.on('router:before', function () {
routeCallbacks(self.routes.before);
});
// Convenience config to bind routes after the static app routes
choreo.on('router:after', function () {
routeCallbacks(self.routes.after);
});
// Run loadModules method if moduleloader is loaded
async.auto({
modules: function (cb) {
if (choreo.config.hooks.moduleloader) {
return self.loadModules(cb);
}
return cb();
}
}, function (err) {
if (err) return cb(err);
self.initialize(cb);
});
};
/**
* Default configuration for this hook
* (should be overiden by hook definition)
*
* @returns {}
*/
this.defaults = function (config) { // :TODO unused variable config
return {};
};
/**
* `configure`
*
* Normalize and validate configuration for this hook.
* Then fold modifications back into `choreo.config`
*
* Hooks may override this function.
*/
this.configure = function () {
return;
};
/**
* Hooks should override this function
*/
this.loadModules = function (cb) {
return cb();
};
/**
* Hooks may override this function
*/
this.initialize = function (cb) {
return cb();
};
/////// TODO: most of the following could be replaced by taking
// advantage of lodash "merge"
// Ensure that the hook definition has valid properties
_normalize(this);
definition = _normalize(definition);
// Merge default definition with overrides in the definition passed in
_.extend(definition.config, this.config, definition.config);
_.extend(definition.middleware, this.middleware, definition.middleware);
_.extend(definition.routes.before,
this.routes.before, definition.routes.before);
_.extend(definition.routes.after,
this.routes.after, definition.routes.after);
_.extend(this, definition);
// Bind context of new methods from definition
_.bindAll(this);
/**
* Ensure that a hook definition has the required properties
* @api private
*/
function _normalize(def) {
def = def || {};
// Default hook config
def.config = def.config || {};
// list of environments to run in, if empty defaults to all
def.config.envs = def.config.envs || [];
def.middleware = def.middleware || {};
// Default hook routes
def.routes = def.routes || {};
def.routes.before = def.routes.before || {};
def.routes.after = def.routes.after || {};
return def;
}
}
};