mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-12-28 11:14:46 +08:00
144 lines
4.1 KiB
JavaScript
144 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
const config = require('wild-config');
|
|
const pathlib = require('path');
|
|
const log = require('npmlog');
|
|
const db = require('./db');
|
|
|
|
const WD_PATH = pathlib.join(__dirname, '..');
|
|
const CONFIG_PATH = config.configDirectory || WD_PATH;
|
|
|
|
const hooks = new Map();
|
|
|
|
class PluginInstance {
|
|
constructor(key, config) {
|
|
this.db = db;
|
|
|
|
this.key = key;
|
|
this.config = config || {};
|
|
|
|
this.logger = {};
|
|
['silly', 'verbose', 'info', 'http', 'warn', 'error', 'debug', 'err'].forEach(level => {
|
|
this.logger[level] = (...args) => {
|
|
switch (level) {
|
|
case 'debug':
|
|
level = 'verbose';
|
|
break;
|
|
case 'err':
|
|
level = 'error';
|
|
break;
|
|
}
|
|
log[level]('[' + key + ']', ...args);
|
|
};
|
|
});
|
|
}
|
|
|
|
addHook(hook, handler) {
|
|
hook = (hook || '')
|
|
.toString()
|
|
.replace(/\s+/g, '')
|
|
.toLowerCase();
|
|
if (!hook) {
|
|
return;
|
|
}
|
|
if (!hooks.has(hook)) {
|
|
hooks.set(hook, []);
|
|
}
|
|
hooks.get(hook).push({ plugin: this, handler });
|
|
}
|
|
|
|
init(done) {
|
|
if (!this.config.path) {
|
|
this.logger.debug('Plugin path not provided, skipping');
|
|
return setImmediate(done);
|
|
}
|
|
try {
|
|
let pluginPath = this.config.path.replace(/\$WD/g, WD_PATH).replace(/\$CONFIG/g, CONFIG_PATH);
|
|
this.module = require(pluginPath); //eslint-disable-line global-require
|
|
} catch (E) {
|
|
this.logger.error('Failed to load plugin. %s', E.message);
|
|
return setImmediate(done);
|
|
}
|
|
|
|
if (typeof this.module.init !== 'function') {
|
|
this.logger.debug('Init method not found');
|
|
return setImmediate(done);
|
|
}
|
|
|
|
try {
|
|
return this.module.init(this, err => {
|
|
if (err) {
|
|
this.logger.error('Initialization resulted with an error. %s', err.message);
|
|
} else {
|
|
this.logger.debug('Plugin "%s" initialized', this.module.title || this.key);
|
|
}
|
|
return setImmediate(done);
|
|
});
|
|
} catch (E) {
|
|
this.logger.error('Failed executing init method. %s', E.message);
|
|
return setImmediate(done);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports.init = next => {
|
|
let keys = Object.keys(config.plugins || {});
|
|
|
|
let pos = 0;
|
|
let loadNextPlugin = () => {
|
|
if (pos >= keys.length) {
|
|
return setImmediate(next);
|
|
}
|
|
let key = keys[pos++];
|
|
if (!config.plugins[key].enabled) {
|
|
return setImmediate(loadNextPlugin);
|
|
}
|
|
let plugin = new PluginInstance(key, config.plugins[key]);
|
|
plugin.init(loadNextPlugin);
|
|
};
|
|
setImmediate(loadNextPlugin);
|
|
};
|
|
|
|
module.exports.runHooks = (hook, ...args) => {
|
|
let next = args.pop();
|
|
|
|
hook = (hook || '')
|
|
.toString()
|
|
.replace(/\s+/g, '')
|
|
.toLowerCase();
|
|
|
|
if (!hook || !hooks.has(hook)) {
|
|
return setImmediate(next);
|
|
}
|
|
|
|
let handlers = hooks.get(hook);
|
|
let pos = 0;
|
|
let processHandler = () => {
|
|
if (pos >= handlers.length) {
|
|
return setImmediate(next);
|
|
}
|
|
let entry = handlers[pos++];
|
|
let returned = false;
|
|
try {
|
|
entry.handler(...args, err => {
|
|
if (returned) {
|
|
return;
|
|
}
|
|
returned = true;
|
|
|
|
if (err) {
|
|
entry.plugin.logger.error('Failed processing hook %s. %s', hook, err.message);
|
|
}
|
|
setImmediate(processHandler);
|
|
});
|
|
} catch (E) {
|
|
if (returned) {
|
|
return;
|
|
}
|
|
returned = true;
|
|
entry.plugin.logger.error('Failed processing hook %s. %s', hook, E.message);
|
|
setImmediate(processHandler);
|
|
}
|
|
};
|
|
setImmediate(processHandler);
|
|
};
|