nocca
Version:
NodeJS Mock Server
99 lines (61 loc) • 2.74 kB
JavaScript
var $globby = require('globby');
module.exports = PluginLoader;
function PluginLoader (Nocca) {
var self = this;
var loadedPlugins = {};
var instantiatedPlugins = {};
self.registerPlugins = registerPlugins;
self.getPluginDefinition = getPluginDefinition;
self.instantiatePlugin = instantiatePlugin;
function registerPlugins () {
var plugins = $globby.sync(__dirname + '/plugins/**/*.js');
plugins.forEach(function (plugin) {
// load from the plugins dir, should return an object
plugin = require(plugin);
// if plugin was an object, or was require()'d as object, proceed
if (typeof plugin === 'object') {
// plugin definition!
registerPlugin(plugin);
}
});
}
function registerPlugin (pluginDefinition) {
// make sure it's valid before continuing
validatePluginDefinition(pluginDefinition);
// confirm plugin is not yet loaded
if (typeof loadedPlugins[pluginDefinition.id] === 'undefined') {
// register plugin
loadedPlugins[pluginDefinition.id] = pluginDefinition;
// some plugins are instantiated on load
if (pluginDefinition.interface === 'httpApi') {
Nocca.usePlugin(pluginDefinition.id);
}
}
else if (loadedPlugins[pluginDefinition.id].constructor !== pluginDefinition.constructor) {
throw 'Cannot load two different plugins with identical id\'s';
}
}
function getPluginDefinition (pluginId) {
return loadedPlugins[pluginId];
}
function instantiatePlugin (pluginId, pluginConfig) {
// bitch about it if the plugin is unknown (i.e. not defined in plugins config)
if (typeof loadedPlugins[pluginId] === 'undefined') {
throw 'Cannot use plugin with id ' + pluginId + ' as it is not loaded';
}
// at this time it is always a single instance that is shared. Is this desirable?
if (typeof instantiatedPlugins[pluginId] === 'undefined') {
instantiatedPlugins[pluginId] = new loadedPlugins[pluginId].constructor(Nocca);
}
return instantiatedPlugins[pluginId].invoke(pluginConfig);
}
function validatePluginDefinition (pluginDefinition) {
var requiredProperties = ['interface', 'id', 'constructor'];
requiredProperties.forEach(function (property) {
if (typeof pluginDefinition[property] === 'undefined') {
throw 'Property ' + property + ' is not found in plugin definition: ' + JSON.stringify(pluginDefinition);
}
});
}
}
;