strapi/lib/private/loadHooks.js

169 lines
4.5 KiB
JavaScript
Raw Normal View History

2015-10-01 00:30:16 +02:00
'use strict';
/**
* Module dependencies
*/
// Public node modules.
const _ = require('lodash');
const async = require('async');
const cluster = require('cluster');
2015-10-01 00:30:16 +02:00
// Local dependencies.
const __hooks = require('../configuration/hooks');
/**
* Resolve the hook definitions and then finish loading them
*
* @api private
*/
module.exports = function (strapi) {
const Hook = __hooks(strapi);
return function initializeHooks(hooks, cb) {
function prepareHook(id) {
let hookPrototype = hooks[id];
// Allow disabling of hooks by setting them to `false`.
if (strapi.config.hooks[hookPrototype] === false) {
delete hooks[id];
return;
}
// Do not load the `studio` hook if the
// cluster is not the master.
if (!cluster.isMaster) {
delete hooks.studio;
}
2015-12-02 14:57:00 +01:00
// Remove undesired hooks when this is a `dry` application.
if (strapi.config.dry) {
delete hooks.grant;
delete hooks.studio;
}
// Handle folder-defined modules (default to `./lib/index.js`)
2015-10-01 00:30:16 +02:00
// Since a hook definition must be a function.
if (_.isObject(hookPrototype) && !_.isArray(hookPrototype) && !_.isFunction(hookPrototype)) {
hookPrototype = hookPrototype.index;
}
if (!_.isFunction(hookPrototype)) {
strapi.log.error('Malformed (`' + id + '`) hook!');
strapi.log.error('Hooks should be a function with one argument (`strapi`)');
strapi.stop();
}
// Instantiate the hook.
const def = hookPrototype(strapi);
// Mix in an `identity` property to hook definition.
def.identity = id.toLowerCase();
// If a config key was defined for this hook when it was loaded
// (probably because a user is overridding the default config key),
// set it on the hook definition.
def.configKey = hookPrototype.configKey || def.identity;
// New up an actual Hook instance.
hooks[id] = new Hook(def);
}
// Function to apply a hook's `defaults` object or function.
function applyDefaults(hook) {
// Get the hook defaults.
const defaults = (_.isFunction(hook.defaults) ? hook.defaults(strapi.config) : hook.defaults) || {};
_.defaults(strapi.config, defaults);
}
// Load a hook and initialize it.
function loadHook(id, cb) {
hooks[id].load(function (err) {
if (err) {
2015-11-02 15:56:56 +01:00
strapi.log.error('The hook `' + id + '` failed to load!');
2015-10-01 00:30:16 +02:00
strapi.emit('hook:' + id + ':error');
return cb(err);
}
strapi.emit('hook:' + id + ':loaded');
// Defer to next tick to allow other stuff to happen.
process.nextTick(cb);
});
}
async.series({
// Load the user config dictionary.
_config: function loadConfigHook(cb) {
if (!hooks._config) {
return cb();
}
prepareHook('_config');
applyDefaults(hooks._config);
loadHook('_config', cb);
},
// Load the user APIs dictionary.
_api: function loadApiHook(cb) {
if (!hooks._api) {
return cb();
}
prepareHook('_api');
applyDefaults(hooks._api);
loadHook('_api', cb);
},
// Load the studio hook.
studio: function loadStudioHook(cb) {
if (!hooks.studio) {
return cb();
}
prepareHook('studio');
applyDefaults(hooks.studio);
loadHook('studio', cb);
},
2015-10-01 00:30:16 +02:00
// Prepare all other hooks.
prepare: function prepareHooks(cb) {
2016-01-11 14:32:29 +01:00
async.each(_.without(_.keys(hooks), '_config', '_api', 'studio', 'router'), function (id, cb) {
2015-10-01 00:30:16 +02:00
prepareHook(id);
process.nextTick(cb);
}, cb);
},
// Apply the default config for all other hooks.
defaults: function defaultConfigHooks(cb) {
2016-01-11 14:32:29 +01:00
async.each(_.without(_.keys(hooks), '_config', '_api', 'studio', 'router'), function (id, cb) {
2015-10-01 00:30:16 +02:00
const hook = hooks[id];
applyDefaults(hook);
process.nextTick(cb);
}, cb);
},
// Load all other hooks.
load: function loadOtherHooks(cb) {
2016-01-11 14:32:29 +01:00
async.each(_.without(_.keys(hooks), '_config', '_api', 'studio', 'router'), function (id, cb) {
2015-10-01 00:30:16 +02:00
loadHook(id, cb);
}, cb);
2015-11-18 18:29:44 +01:00
},
// Load the router hook.
router: function loadRouterHook(cb) {
if (!hooks.router) {
return cb();
}
prepareHook('router');
applyDefaults(hooks.router);
loadHook('router', cb);
2015-10-01 00:30:16 +02:00
}
},
function hooksReady(err) {
return cb(err);
});
};
};