2018-05-28 22:49:18 +00:00
|
|
|
const async = require('async');
|
2017-03-31 11:34:43 +00:00
|
|
|
var Plugin = require('./plugin.js');
|
2018-06-18 15:25:43 +00:00
|
|
|
var fs = require('../core/fs.js');
|
2017-03-31 11:34:43 +00:00
|
|
|
|
|
|
|
var Plugins = function(options) {
|
|
|
|
this.pluginList = options.plugins || [];
|
|
|
|
this.interceptLogs = options.interceptLogs;
|
|
|
|
this.plugins = [];
|
|
|
|
// TODO: need backup 'NullLogger'
|
|
|
|
this.logger = options.logger;
|
|
|
|
this.events = options.events;
|
|
|
|
this.config = options.config;
|
2018-04-25 14:34:17 +00:00
|
|
|
this.context = options.context;
|
2018-05-19 02:40:47 +00:00
|
|
|
this.env = options.env;
|
2017-03-30 11:12:39 +00:00
|
|
|
};
|
|
|
|
|
2017-03-31 11:34:43 +00:00
|
|
|
Plugins.prototype.loadPlugins = function() {
|
2018-08-10 10:31:10 +00:00
|
|
|
for (let pluginName in this.pluginList) {
|
|
|
|
let pluginConfig = this.pluginList[pluginName];
|
2017-03-31 11:34:43 +00:00
|
|
|
this.loadPlugin(pluginName, pluginConfig);
|
2017-03-29 15:37:30 +00:00
|
|
|
}
|
2017-03-31 11:34:43 +00:00
|
|
|
};
|
2016-12-07 02:33:31 +00:00
|
|
|
|
2017-03-31 11:34:43 +00:00
|
|
|
Plugins.prototype.listPlugins = function() {
|
2018-08-10 10:31:10 +00:00
|
|
|
return this.plugins.reduce((list, plugin) => {
|
2018-04-24 19:53:19 +00:00
|
|
|
if (plugin.loaded) {
|
|
|
|
list.push(plugin.name);
|
|
|
|
}
|
2018-08-10 10:31:10 +00:00
|
|
|
return list;
|
|
|
|
}, []);
|
2017-03-31 11:34:43 +00:00
|
|
|
};
|
2017-03-30 13:16:46 +00:00
|
|
|
|
2017-12-30 20:52:51 +00:00
|
|
|
// for services that act as a plugin but have core functionality
|
|
|
|
Plugins.prototype.createPlugin = function(pluginName, pluginConfig) {
|
|
|
|
let plugin = {};
|
2017-12-30 22:07:13 +00:00
|
|
|
let pluginPath = false;
|
2018-04-25 14:34:17 +00:00
|
|
|
var pluginWrapper = new Plugin({
|
|
|
|
name: pluginName,
|
|
|
|
pluginModule: plugin,
|
|
|
|
pluginConfig: pluginConfig,
|
|
|
|
logger: this.logger,
|
|
|
|
pluginPath: pluginPath,
|
|
|
|
interceptLogs: this.interceptLogs,
|
|
|
|
events: this.events,
|
|
|
|
config: this.config,
|
2018-07-12 13:02:16 +00:00
|
|
|
plugins: this.plugins,
|
2018-04-25 14:34:17 +00:00
|
|
|
isInternal: true,
|
|
|
|
context: this.context
|
|
|
|
});
|
2017-12-30 20:52:51 +00:00
|
|
|
this.plugins.push(pluginWrapper);
|
|
|
|
return pluginWrapper;
|
|
|
|
};
|
|
|
|
|
2017-12-16 20:39:30 +00:00
|
|
|
Plugins.prototype.loadInternalPlugin = function(pluginName, pluginConfig) {
|
2018-06-18 15:27:29 +00:00
|
|
|
var pluginPath = fs.embarkPath('lib/modules/' + pluginName);
|
2018-10-29 16:12:43 +00:00
|
|
|
var plugin;
|
|
|
|
try {
|
|
|
|
plugin = require(pluginPath);
|
|
|
|
} catch(_e) {
|
|
|
|
pluginPath = fs.embarkPath('modules/' + pluginName);
|
|
|
|
plugin = require(pluginPath);
|
|
|
|
}
|
2017-12-16 20:39:30 +00:00
|
|
|
|
2018-04-25 14:34:17 +00:00
|
|
|
var pluginWrapper = new Plugin({
|
|
|
|
name: pluginName,
|
|
|
|
pluginModule: plugin,
|
2018-05-30 16:26:49 +00:00
|
|
|
pluginConfig: pluginConfig || {},
|
2018-04-25 14:34:17 +00:00
|
|
|
logger: this.logger,
|
2018-06-18 15:27:29 +00:00
|
|
|
pluginPath: pluginPath,
|
2018-04-25 14:34:17 +00:00
|
|
|
interceptLogs: this.interceptLogs,
|
|
|
|
events: this.events,
|
|
|
|
config: this.config,
|
2018-07-12 13:02:16 +00:00
|
|
|
plugins: this.plugins,
|
2018-04-25 14:34:17 +00:00
|
|
|
isInternal: true,
|
2018-05-19 02:40:47 +00:00
|
|
|
context: this.context,
|
|
|
|
env: this.env
|
2018-04-25 14:34:17 +00:00
|
|
|
});
|
2017-12-16 20:39:30 +00:00
|
|
|
pluginWrapper.loadInternalPlugin();
|
|
|
|
this.plugins.push(pluginWrapper);
|
|
|
|
};
|
|
|
|
|
2017-03-31 11:34:43 +00:00
|
|
|
Plugins.prototype.loadPlugin = function(pluginName, pluginConfig) {
|
2018-08-17 17:41:39 +00:00
|
|
|
var pluginPath = fs.dappPath('node_modules', pluginName);
|
2017-03-31 11:34:43 +00:00
|
|
|
var plugin = require(pluginPath);
|
2017-03-29 15:37:30 +00:00
|
|
|
|
2018-04-25 14:34:17 +00:00
|
|
|
var pluginWrapper = new Plugin({
|
|
|
|
name: pluginName,
|
|
|
|
pluginModule: plugin,
|
|
|
|
pluginConfig: pluginConfig,
|
|
|
|
logger: this.logger,
|
|
|
|
pluginPath: pluginPath,
|
|
|
|
interceptLogs: this.interceptLogs,
|
|
|
|
events: this.events,
|
|
|
|
config: this.config,
|
2018-07-12 13:02:16 +00:00
|
|
|
plugins: this.plugins,
|
2018-04-25 14:34:17 +00:00
|
|
|
isInternal: false,
|
|
|
|
context: this.context
|
|
|
|
});
|
2017-03-31 11:34:43 +00:00
|
|
|
pluginWrapper.loadPlugin();
|
|
|
|
this.plugins.push(pluginWrapper);
|
|
|
|
};
|
2017-03-30 13:16:46 +00:00
|
|
|
|
2017-03-31 11:34:43 +00:00
|
|
|
Plugins.prototype.getPluginsFor = function(pluginType) {
|
|
|
|
return this.plugins.filter(function(plugin) {
|
|
|
|
return plugin.has(pluginType);
|
|
|
|
});
|
|
|
|
};
|
2017-03-29 15:37:30 +00:00
|
|
|
|
2018-05-28 22:49:18 +00:00
|
|
|
Plugins.prototype.getPluginsProperty = function(pluginType, property, sub_property) {
|
2017-12-29 13:08:04 +00:00
|
|
|
let matchingPlugins = this.plugins.filter(function(plugin) {
|
|
|
|
return plugin.has(pluginType);
|
|
|
|
});
|
|
|
|
|
2018-06-14 20:58:03 +00:00
|
|
|
// Sort internal plugins first
|
|
|
|
matchingPlugins.sort((a, b) => {
|
|
|
|
if (a.isInternal) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (b.isInternal) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
|
2017-12-29 13:26:31 +00:00
|
|
|
let matchingProperties = matchingPlugins.map((plugin) => {
|
2018-05-28 22:49:18 +00:00
|
|
|
if (sub_property) {
|
|
|
|
return plugin[property][sub_property];
|
|
|
|
}
|
2017-12-29 13:08:04 +00:00
|
|
|
return plugin[property];
|
|
|
|
});
|
2017-12-29 13:26:31 +00:00
|
|
|
|
2018-06-14 20:58:03 +00:00
|
|
|
// Remove empty properties
|
2018-05-29 13:36:27 +00:00
|
|
|
matchingProperties = matchingProperties.filter((property) => property);
|
|
|
|
|
2017-12-29 13:26:31 +00:00
|
|
|
//return flattened list
|
|
|
|
if (matchingProperties.length === 0) return [];
|
2018-05-28 22:49:18 +00:00
|
|
|
return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
|
|
|
|
};
|
|
|
|
|
2018-05-28 23:40:55 +00:00
|
|
|
Plugins.prototype.runActionsForEvent = function(eventName, args, cb) {
|
2018-05-29 13:58:19 +00:00
|
|
|
if (typeof (args) === 'function') {
|
2018-05-28 23:40:55 +00:00
|
|
|
cb = args;
|
|
|
|
}
|
2018-05-28 22:49:18 +00:00
|
|
|
let actionPlugins = this.getPluginsProperty('eventActions', 'eventActions', eventName);
|
|
|
|
|
2018-05-28 23:40:55 +00:00
|
|
|
if (actionPlugins.length === 0) {
|
2018-08-20 21:25:30 +00:00
|
|
|
return cb(args);
|
2018-05-28 23:40:55 +00:00
|
|
|
}
|
|
|
|
|
2018-08-20 21:25:30 +00:00
|
|
|
async.reduce(actionPlugins, args, function(current_args, plugin, nextEach) {
|
2018-05-29 13:58:19 +00:00
|
|
|
if (typeof (args) === 'function') {
|
2018-08-20 21:25:30 +00:00
|
|
|
plugin.call(plugin, (params) => {
|
|
|
|
nextEach(null, (params || current_args));
|
|
|
|
});
|
2018-05-28 23:40:55 +00:00
|
|
|
} else {
|
2018-08-20 21:25:30 +00:00
|
|
|
plugin.call(plugin, args, (params) => {
|
|
|
|
nextEach(null, (params || current_args));
|
|
|
|
});
|
2018-05-28 23:40:55 +00:00
|
|
|
}
|
2018-05-28 22:49:18 +00:00
|
|
|
}, cb);
|
2017-12-29 13:08:04 +00:00
|
|
|
};
|
|
|
|
|
2018-05-30 12:00:31 +00:00
|
|
|
Plugins.prototype.emitAndRunActionsForEvent = function(eventName, args, cb) {
|
|
|
|
this.events.emit(eventName);
|
|
|
|
return this.runActionsForEvent(eventName, args, cb);
|
|
|
|
};
|
|
|
|
|
2017-03-31 11:34:43 +00:00
|
|
|
module.exports = Plugins;
|