mirror of
https://github.com/strapi/strapi.git
synced 2025-09-26 00:39:49 +00:00
Simplify and reduce codebase for loading hooks
This commit is contained in:
parent
f2f85037e4
commit
aaaec192a7
@ -6,84 +6,102 @@
|
|||||||
|
|
||||||
// Node.js core.
|
// Node.js core.
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
// Public node modules.
|
// Local utilities.
|
||||||
const _ = require('lodash');
|
const json = require('strapi-utils').json;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expose new instance of `Configuration`
|
* Expose new instance of `Configuration`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = strapi => {
|
module.exports = class Configuration {
|
||||||
return new Configuration();
|
|
||||||
|
|
||||||
function Configuration() {
|
constructor() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strapi default configuration
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
defaults(context, appPath) {
|
||||||
|
|
||||||
|
// If `appPath` not specified, unfortunately, this is a fatal error,
|
||||||
|
// since reasonable defaults cannot be assumed.
|
||||||
|
if (!appPath) {
|
||||||
|
throw new Error('Error: No `appPath` specified!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up config defaults.
|
||||||
|
return {
|
||||||
|
// Save `appPath` in implicit defaults.
|
||||||
|
// `appPath` is passed from above in case `start` was used.
|
||||||
|
// This is the directory where this Strapi process is being initiated from.
|
||||||
|
// Usually this means `process.cwd()`.
|
||||||
|
appPath: appPath,
|
||||||
|
|
||||||
|
// Core settings non provided by hooks.
|
||||||
|
host: process.env.HOST || process.env.HOSTNAME || context.config.host || 'localhost',
|
||||||
|
port: process.env.PORT || context.config.port || 1337,
|
||||||
|
|
||||||
|
// Make the environment in config match the server one.
|
||||||
|
environment: context.app.env || process.env.NODE_ENV,
|
||||||
|
|
||||||
|
// Default reload config.
|
||||||
|
reload: {
|
||||||
|
timeout: 1000,
|
||||||
|
workers: os.cpus().length
|
||||||
|
},
|
||||||
|
|
||||||
|
// Default paths.
|
||||||
|
paths: {
|
||||||
|
tmp: '.tmp',
|
||||||
|
config: 'config',
|
||||||
|
static: 'public',
|
||||||
|
views: 'views',
|
||||||
|
api: 'api',
|
||||||
|
controllers: 'controllers',
|
||||||
|
services: 'services',
|
||||||
|
policies: 'policies',
|
||||||
|
models: 'models'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Start off needed empty objects and strings.
|
||||||
|
routes: {},
|
||||||
|
collections: {},
|
||||||
|
frontendUrl: '',
|
||||||
|
hooks: {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the configuration modules
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
load(context, cb) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strapi default configuration
|
* Expose version/dependency info for the currently-running
|
||||||
*
|
* Strapi on the `strapi` object (from its `package.json`).
|
||||||
* @api private
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.defaults = appPath => {
|
const pathToThisVersionOfStrapi = path.join(__dirname, '..', '..');
|
||||||
|
|
||||||
// If `appPath` not specified, unfortunately, this is a fatal error,
|
json.getPackage(pathToThisVersionOfStrapi, (err, pkg) => {
|
||||||
// since reasonable defaults cannot be assumed.
|
if (err) {
|
||||||
if (!appPath) {
|
return cb(err);
|
||||||
throw new Error('Error: No `appPath` specified!');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up config defaults.
|
context.version = pkg.version;
|
||||||
return {
|
context.dependencies = pkg.dependencies;
|
||||||
// Save `appPath` in implicit defaults.
|
|
||||||
// `appPath` is passed from above in case `start` was used.
|
|
||||||
// This is the directory where this Strapi process is being initiated from.
|
|
||||||
// Usually this means `process.cwd()`.
|
|
||||||
appPath: appPath,
|
|
||||||
|
|
||||||
// Core settings non provided by hooks.
|
// Override the previous contents of `strapi.config` with the new, validated
|
||||||
host: process.env.HOST || process.env.HOSTNAME || strapi.config.host || 'localhost',
|
// config with defaults and overrides mixed in the appropriate order.
|
||||||
port: process.env.PORT || strapi.config.port || 1337,
|
context.config = this.defaults(context, context.config.appPath || process.cwd());
|
||||||
|
cb();
|
||||||
// Make the environment in config match the server one.
|
});
|
||||||
environment: strapi.app.env || process.env.NODE_ENV,
|
|
||||||
|
|
||||||
// Default reload config.
|
|
||||||
reload: {
|
|
||||||
timeout: 1000,
|
|
||||||
workers: os.cpus().length
|
|
||||||
},
|
|
||||||
|
|
||||||
// Default paths.
|
|
||||||
paths: {
|
|
||||||
tmp: '.tmp',
|
|
||||||
config: 'config',
|
|
||||||
static: 'public',
|
|
||||||
views: 'views',
|
|
||||||
api: 'api',
|
|
||||||
controllers: 'controllers',
|
|
||||||
services: 'services',
|
|
||||||
policies: 'policies',
|
|
||||||
models: 'models'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Start off needed empty objects and strings.
|
|
||||||
routes: {},
|
|
||||||
collections: {},
|
|
||||||
frontendUrl: '',
|
|
||||||
hooks: {}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the configuration modules
|
|
||||||
*
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
this.load = require('./load').apply(this, [strapi]);
|
|
||||||
|
|
||||||
// Bind the context of all instance methods.
|
|
||||||
_.bindAll(this);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module dependencies
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Node.js core.
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
// Public node modules.
|
|
||||||
const async = require('async');
|
|
||||||
|
|
||||||
// Local utilities.
|
|
||||||
const json = require('strapi-utils').json;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expose Configuration loader
|
|
||||||
*
|
|
||||||
* Load command-line overrides
|
|
||||||
*
|
|
||||||
* For reference, config priority is:
|
|
||||||
* -> implicit defaults
|
|
||||||
* -> environment variables
|
|
||||||
* -> user config files
|
|
||||||
* -> local config file
|
|
||||||
* -> configOverride (in call to `strapi.start()`)
|
|
||||||
* -> --cmdline args
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = function (strapi) {
|
|
||||||
return cb => {
|
|
||||||
|
|
||||||
// Commence with loading/validating/defaulting all the rest of the config.
|
|
||||||
async.auto({
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expose version/dependency info for the currently-running
|
|
||||||
* Strapi on the `strapi` object (from its `package.json`).
|
|
||||||
*/
|
|
||||||
|
|
||||||
versionAndDependencyInfo: cb => {
|
|
||||||
const pathToThisVersionOfStrapi = path.join(__dirname, '..', '..');
|
|
||||||
|
|
||||||
json.getPackage(pathToThisVersionOfStrapi, function (err, pkg) {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
strapi.version = pkg.version;
|
|
||||||
strapi.dependencies = pkg.dependencies;
|
|
||||||
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, err => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override the previous contents of `strapi.config` with the new, validated
|
|
||||||
// config with defaults and overrides mixed in the appropriate order.
|
|
||||||
strapi.config = this.defaults(strapi.config.appPath || process.cwd());
|
|
||||||
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
@ -13,9 +13,8 @@ const async = require('async');
|
|||||||
const herd = require('herd');
|
const herd = require('herd');
|
||||||
|
|
||||||
// Local dependencies.
|
// Local dependencies.
|
||||||
const Hook = require('./configuration/hooks');
|
const Configuration = require('./configuration');
|
||||||
const __Configuration = require('./configuration');
|
const loadHooks = require('./private/loadHooks');
|
||||||
const __loadHooks = require('./private/loadHooks');
|
|
||||||
const DEFAULT_HOOKS = require('./configuration/hooks/defaultHooks');
|
const DEFAULT_HOOKS = require('./configuration/hooks/defaultHooks');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,11 +22,6 @@ const DEFAULT_HOOKS = require('./configuration/hooks/defaultHooks');
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = function (configOverride, cb) {
|
module.exports = function (configOverride, cb) {
|
||||||
const self = this;
|
|
||||||
|
|
||||||
const Configuration = __Configuration(this);
|
|
||||||
const loadHooks = __loadHooks(this);
|
|
||||||
|
|
||||||
if (this._exiting) {
|
if (this._exiting) {
|
||||||
this.log.error('Cannot load or start an application after it has already been stopped.');
|
this.log.error('Cannot load or start an application after it has already been stopped.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@ -48,27 +42,38 @@ module.exports = function (configOverride, cb) {
|
|||||||
// Apply core defaults and hook-agnostic configuration,
|
// Apply core defaults and hook-agnostic configuration,
|
||||||
// esp. overrides including command-line options, environment variables,
|
// esp. overrides including command-line options, environment variables,
|
||||||
// and options that were passed in programmatically.
|
// and options that were passed in programmatically.
|
||||||
config: [Configuration.load],
|
config: cb => new Configuration().load(this, cb),
|
||||||
// Optionally expose globals as soon as the
|
// Optionally expose globals as soon as the
|
||||||
// config hook is loaded.
|
// config hook is loaded.
|
||||||
exposeGlobals: ['config', (result, cb) => self.exposeGlobals(cb)],
|
exposeGlobals: ['config', (result, cb) => this.exposeGlobals(cb)],
|
||||||
|
// Initialize dictionary's hooks.
|
||||||
|
preInitializeHooks: ['exposeGlobals', (result, cb) => preInitializeHooks.apply(this, [cb])],
|
||||||
// Create configurations tree (dictionary).
|
// Create configurations tree (dictionary).
|
||||||
dictionary: ['exposeGlobals', (result, cb) => {
|
loadDictionary: ['preInitializeHooks', (result, cb) => loadHooks.apply(this, [cb])],
|
||||||
// Pre-initialize hooks for create dictionary.
|
// Initialize hooks left.
|
||||||
_.assign(self.hooks, _.mapValues(_.get(DEFAULT_HOOKS, 'dictionary'), (hook, hookIdentity) => {
|
initializeHooks: ['loadDictionary', (result, cb) => initializeHooks.apply(this, [cb])],
|
||||||
return require('./configuration/hooks/dictionary/' + hookIdentity);
|
|
||||||
}));
|
|
||||||
|
|
||||||
loadHooks(self.hooks, cb);
|
|
||||||
}],
|
|
||||||
// Initialize hooks global variable and configurations
|
|
||||||
initializeHooks: ['dictionary', initializeHooks],
|
|
||||||
// Load hooks into memory.
|
// Load hooks into memory.
|
||||||
loadHooks: ['initializeHooks', (result, cb) => loadHooks(self.hooks, cb)]
|
loadHooks: ['initializeHooks', (result, cb) => loadHooks.apply(this, [cb])]
|
||||||
}, ready__(cb));
|
}, (err, results) => ready__.apply(this, [cb])());
|
||||||
|
|
||||||
// Makes `app.load()` chainable.
|
// Makes `app.load()` chainable.
|
||||||
return self;
|
return this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-initialize hooks by putting only dictionary hooks,
|
||||||
|
* into the `hooks` global varialbe.
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function preInitializeHooks(cb) {
|
||||||
|
// Pre-initialize hooks for create dictionary.
|
||||||
|
_.assign(this.hooks, _.mapValues(_.get(DEFAULT_HOOKS, 'dictionary'), (hook, hookIdentity) => {
|
||||||
|
return require('./configuration/hooks/dictionary/' + hookIdentity);
|
||||||
|
}));
|
||||||
|
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiliaze hooks,
|
* Initiliaze hooks,
|
||||||
@ -77,10 +82,9 @@ module.exports = function (configOverride, cb) {
|
|||||||
* @api private
|
* @api private
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function initializeHooks(cb) {
|
||||||
function initializeHooks(result, cb) {
|
|
||||||
// Reset
|
// Reset
|
||||||
self.hooks = {};
|
this.hooks = {};
|
||||||
|
|
||||||
const tree = {};
|
const tree = {};
|
||||||
|
|
||||||
@ -92,14 +96,14 @@ module.exports = function (configOverride, cb) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Extend tree with external hooks.
|
// Extend tree with external hooks.
|
||||||
_.forEach(self.externalHooks, (hook, hookIdentity) => {
|
_.forEach(this.externalHooks, (hook, hookIdentity) => {
|
||||||
_.set(tree, hookIdentity, hook);
|
_.set(tree, hookIdentity, hook);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove this sensitive object.
|
// Remove this sensitive object.
|
||||||
delete strapi.externalHooks;
|
delete this.externalHooks;
|
||||||
|
|
||||||
const mapper = _.clone(self.config.hooks);
|
const mapper = _.clone(this.config.hooks);
|
||||||
|
|
||||||
// Map (warning: we could have some order issues).
|
// Map (warning: we could have some order issues).
|
||||||
_.assignWith(mapper, tree, (objValue, srcValue) => {
|
_.assignWith(mapper, tree, (objValue, srcValue) => {
|
||||||
@ -107,15 +111,15 @@ module.exports = function (configOverride, cb) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Pick hook to load.
|
// Pick hook to load.
|
||||||
self.hooks = _.pickBy(mapper, value => value !== false);
|
this.hooks = _.pickBy(mapper, value => value !== false);
|
||||||
|
|
||||||
// Require only necessary hooks.
|
// Require only necessary hooks.
|
||||||
self.hooks =_.mapValues(self.hooks, (hook, hookIdentity) => {
|
this.hooks =_.mapValues(this.hooks, (hook, hookIdentity) => {
|
||||||
try {
|
try {
|
||||||
return require(_.get(tree, hookIdentity));
|
return require(_.get(tree, hookIdentity));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
try {
|
try {
|
||||||
return require(path.resolve(self.config.appPath, 'node_modules', hookIdentity));
|
return require(path.resolve(this.config.appPath, 'node_modules', hookIdentity));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
}
|
}
|
||||||
@ -124,7 +128,7 @@ module.exports = function (configOverride, cb) {
|
|||||||
|
|
||||||
return cb();
|
return cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns function which is fired when Strapi is ready to go
|
* Returns function which is fired when Strapi is ready to go
|
||||||
*
|
*
|
||||||
@ -132,44 +136,44 @@ module.exports = function (configOverride, cb) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function ready__(cb) {
|
function ready__(cb) {
|
||||||
self.emit('hooks:builtIn:ready');
|
this.emit('hooks:builtIn:ready');
|
||||||
|
|
||||||
return err => {
|
return err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// Displaying errors, try to start the server through
|
// Displaying errors, try to start the server through
|
||||||
self.log.error(err);
|
this.log.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically define the server URL from
|
// Automatically define the server URL from
|
||||||
// `proxy`, `ssl`, `host`, and `port` config.
|
// `proxy`, `ssl`, `host`, and `port` config.
|
||||||
if (_.isString(self.config.proxy)) {
|
if (_.isString(this.config.proxy)) {
|
||||||
self.config.url = self.config.proxy;
|
this.config.url = this.config.proxy;
|
||||||
} else {
|
} else {
|
||||||
if (_.isPlainObject(self.config.ssl) && self.config.ssl.disabled === false) {
|
if (_.isPlainObject(this.config.ssl) && this.config.ssl.disabled === false) {
|
||||||
self.config.url = 'https://' + self.config.host + ':' + self.config.port;
|
this.config.url = 'https://' + this.config.host + ':' + this.config.port;
|
||||||
} else {
|
} else {
|
||||||
self.config.url = 'http://' + self.config.host + ':' + self.config.port;
|
this.config.url = 'http://' + this.config.host + ':' + this.config.port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can finally make the server listen on the configured port.
|
// We can finally make the server listen on the configured port.
|
||||||
// Use of the `herd` node module to herd the child processes with
|
// Use of the `herd` node module to herd the child processes with
|
||||||
// zero downtime reloads.
|
// zero downtime reloads.
|
||||||
if (_.isPlainObject(self.config.reload) && !_.isEmpty(self.config.reload) && self.config.reload.workers > 0) {
|
if (_.isPlainObject(this.config.reload) && !_.isEmpty(this.config.reload) && this.config.reload.workers > 0) {
|
||||||
herd(self.config.name)
|
herd(this.config.name)
|
||||||
.close(function () {
|
.close(function () {
|
||||||
process.send('message');
|
process.send('message');
|
||||||
})
|
})
|
||||||
.timeout(self.config.reload.timeout)
|
.timeout(this.config.reload.timeout)
|
||||||
.size(self.config.reload.workers)
|
.size(this.config.reload.workers)
|
||||||
.run(function () {
|
.run(function () {
|
||||||
self.server.listen(self.config.port);
|
this.server.listen(this.config.port);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.server.listen(self.config.port);
|
this.server.listen(this.config.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
cb && cb(null, self);
|
cb && cb(null, this);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -18,87 +18,84 @@ const Hook = require('../configuration/hooks');
|
|||||||
* @api private
|
* @api private
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = function (strapi) {
|
module.exports = function(cb) {
|
||||||
return (hooks, cb) => {
|
function prepareHook(id) {
|
||||||
|
let hookPrototype = this.hooks[id];
|
||||||
|
|
||||||
function prepareHook(id) {
|
// Handle folder-defined modules (default to `./lib/index.js`)
|
||||||
let hookPrototype = hooks[id];
|
// Since a hook definition must be a function.
|
||||||
|
if (_.isObject(hookPrototype) && !_.isArray(hookPrototype) && !_.isFunction(hookPrototype)) {
|
||||||
// Handle folder-defined modules (default to `./lib/index.js`)
|
hookPrototype = hookPrototype.index;
|
||||||
// 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(strapi, def);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to apply a hook's `defaults` object or function.
|
if (!_.isFunction(hookPrototype)) {
|
||||||
function applyDefaults(hook) {
|
strapi.log.error('Malformed (`' + id + '`) hook!');
|
||||||
// Get the hook defaults.
|
strapi.log.error('Hooks should be a function with one argument (`strapi`)');
|
||||||
const defaults = (_.isFunction(hook.defaults) ? hook.defaults(strapi.config) : hook.defaults) || {};
|
strapi.stop();
|
||||||
|
|
||||||
_.defaultsDeep(strapi.config, defaults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a hook and initialize it.
|
// Instantiate the hook.
|
||||||
function loadHook(id, cb) {
|
const def = hookPrototype(strapi);
|
||||||
let timeout = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
// Mix in an `identity` property to hook definition.
|
||||||
if (timeout) {
|
def.identity = id.toLowerCase();
|
||||||
strapi.log.error('The hook `' + id + '` wasn\'t loaded (too long to load)!');
|
|
||||||
process.nextTick(cb);
|
|
||||||
}
|
|
||||||
}, strapi.config.hookTimeout || 1000);
|
|
||||||
|
|
||||||
hooks[id].load(err => {
|
// If a config key was defined for this hook when it was loaded
|
||||||
timeout = false;
|
// (probably because a user is overridding the default config key),
|
||||||
|
// set it on the hook definition.
|
||||||
|
def.configKey = hookPrototype.configKey || def.identity;
|
||||||
|
|
||||||
if (err) {
|
// New up an actual Hook instance.
|
||||||
strapi.log.error('The hook `' + id + '` failed to load!');
|
this.hooks[id] = new Hook(this, def);
|
||||||
strapi.emit('hook:' + id + ':error');
|
}
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
strapi.emit('hook:' + id + ':loaded');
|
// Function to apply a hook's `defaults` object or function.
|
||||||
|
function applyDefaults(hook) {
|
||||||
|
// Get the hook defaults.
|
||||||
|
const defaults = (_.isFunction(hook.defaults) ? hook.defaults(this.config) : hook.defaults) || {};
|
||||||
|
|
||||||
// Defer to next tick to allow other stuff to happen.
|
_.defaultsDeep(this.config, defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load a hook and initialize it.
|
||||||
|
function loadHook(id, cb) {
|
||||||
|
let timeout = true;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (timeout) {
|
||||||
|
this.log.error('The hook `' + id + '` wasn\'t loaded (too long to load)!');
|
||||||
process.nextTick(cb);
|
process.nextTick(cb);
|
||||||
});
|
}
|
||||||
|
}, this.config.hookTimeout || 1000);
|
||||||
|
|
||||||
|
this.hooks[id].load(err => {
|
||||||
|
timeout = false;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
this.log.error('The hook `' + id + '` failed to load!');
|
||||||
|
this.emit('hook:' + id + ':error');
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emit('hook:' + id + ':loaded');
|
||||||
|
|
||||||
|
// Defer to next tick to allow other stuff to happen.
|
||||||
|
process.nextTick(cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async.series(_.map(this.hooks, (hook, identity) => {
|
||||||
|
// Don't load disabled hook
|
||||||
|
if (_.get(this.config.hooks, identity) === false) {
|
||||||
|
return cb => {
|
||||||
|
cb();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async.series(_.map(hooks, (hook, identity) => {
|
return cb => {
|
||||||
// Don't load disabled hook
|
prepareHook.apply(this, [identity]);
|
||||||
if (_.get(strapi.config.hooks, identity) === false) {
|
applyDefaults.apply(this, [hook]);
|
||||||
return cb => {
|
loadHook.apply(this, [identity, cb]);
|
||||||
cb();
|
}
|
||||||
};
|
}), err => cb(err));
|
||||||
}
|
|
||||||
|
|
||||||
return cb => {
|
|
||||||
prepareHook(identity);
|
|
||||||
applyDefaults(hook);
|
|
||||||
loadHook(identity, cb);
|
|
||||||
}
|
|
||||||
}), err => cb(err));
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user