bloggify-plugin-loader
Version:
The Bloggify plugin loader.
305 lines (261 loc) • 9.7 kB
JavaScript
;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var fs = require("fs"),
BloggifyPlugin = require("bloggify-plugin-class"),
oneByOne = require("one-by-one"),
bindy = require("bindy"),
noop = require("noop6"),
typpy = require("typpy"),
assured = require("assured"),
Path = require("path");
module.exports = function () {
/**
* BloggifyPluginLoader
* The Bloggify plugin loader.
*
* @name bloggifyPluginLoader
* @function
* @param {BloggifyCore} bloggify The `BloggifyCore` instance.
* @return {BloggifyPluginLoader} The `BloggifyPluginLoader` instance.
*/
function BloggifyPluginLoader(bloggify) {
_classCallCheck(this, BloggifyPluginLoader);
this.bloggify = bloggify;
this.plugins = {};
}
/**
* getPluginPath
* Fetches the plugin's path.
*
* @param {BloggifyPlugin} pluginName The plugin's name.
* @return {String} The plugin's path.
*/
_createClass(BloggifyPluginLoader, [{
key: "getPluginPath",
value: function getPluginPath(plugin) {
if (plugin.name) {
return plugin;
}
if (!plugin) {
return null;
}
plugin = typeof plugin === "string" ? [plugin, {}] : plugin;
var isLocalPlugin = plugin[0].startsWith("/");
if (isLocalPlugin) {
plugin[0] = Path.join(this.bloggify.paths.root, plugin[0]);
} else if (!plugin[0].startsWith("bloggify-")) {
plugin[0] = "bloggify-" + plugin[0];
}
return {
pluginPath: isLocalPlugin ? plugin[0] : this.bloggify.paths.pluginPath(plugin[0]),
name: plugin[0],
config: plugin[1]
};
}
/**
* namesToPaths
* Fetches the path list for each plugin.
*
* @param {Array} names The list of plugin names.
* @return {Array} The path list.
*/
}, {
key: "namesToPaths",
value: function namesToPaths(plugins) {
var _this = this;
return plugins.map(function (plugin) {
return plugin && _this.getPluginPath(plugin);
}).filter(Boolean);
}
/**
* listPluginDirs
* Fetches the list of the plugin's instances.
*
* @param {Array} names The list of plugin names.
* @param {Function} cb The callback function.
*/
}, {
key: "listPluginDirs",
value: function listPluginDirs(names, cb) {
var _this2 = this;
if (typeof names === "function") {
cb = names;
names = null;
}
cb = cb || noop;
if (Array.isArray(names)) {
return cb(null, this.namesToPaths(names));
}
var pluginsDir = this.bloggify.paths.plugins;
fs.readdir(pluginsDir, function (err, dirs) {
if (err) {
if (err.code === "ENOENT") {
return cb(null, [], err);
}
return cb(err, []);
}
cb(null, _this2.namesToPaths(dirs.sort()));
});
}
/**
* getPlugin
* Fetches called plugin's content if it's valid. Otherwise, it fetches a new one.
*
* @param {BloggifyPlugin} plugin The plugin's name.
* @return {BloggifyPlugin|String} The plugin's name or instance.
*/
}, {
key: "getPlugin",
value: function getPlugin(plugin) {
if (typpy(plugin, BloggifyPlugin)) {
return plugin;
}
plugin = this.getPluginPath(plugin);
return new BloggifyPlugin(plugin.name, plugin.pluginPath, plugin.config);
}
/**
* listPlugins
* Fetches the plugins list.
*
* @param {Array} names The list of plugin names.
* @param {Function} cb The callback function.
*/
}, {
key: "listPlugins",
value: function listPlugins(names, cb) {
var _this3 = this;
if (!cb) {
cb = names;
names = null;
}
cb = cb || noop;
this.listPluginDirs(names, function (err, dirs, warning) {
var plugs = dirs.map(function (pluginName) {
return _this3.getPlugin(pluginName);
});
cb(err, plugs, warning);
});
}
/**
* initPlugin
* Initializes the plugin's instance.
*
* @param {BloggifyPlugin} plug The plugin instance.
* @param {Function} cb The callback function.
*/
}, {
key: "initPlugin",
value: function initPlugin(plug, cb) {
plug = this.getPlugin(plug);
var maybeInitializedAlready = this.plugins[plug.name];
if (maybeInitializedAlready) {
cb(null, this.plugins[plug.name]);
return Promise.resolve(maybeInitializedAlready);
}
this.plugins[plug.name] = plug;
return plug.init(cb);
}
/**
* loadAll
* Initializes the plugins that need to be loaded.
*
* @param {Array} names The list of plugin names.
* @param {Function} cb The callback function.
* @return {Promise} A promise.
*/
}, {
key: "loadAll",
value: function loadAll(names, cb) {
var _this4 = this;
if (typeof names === "function") {
cb = names;
names = null;
}
cb = assured(cb || noop);
if (!names) {
this.bloggify.log("A list of plugins was not provided, therefore all the plugins in the plugin directory will be loaded.");
}
this.listPlugins(names, function (err, plugins) {
if (err) {
return cb(err);
}
var chain = Promise.resolve();
plugins.forEach(function (plugin) {
chain = chain.then(function () {
return _this4.initPlugin(plugin);
});
});
chain.then(function () {
cb();
}).catch(function (err) {
cb(err);
});
});
return cb._;
}
/**
* loadPlugin
* Loads the provided plugin.
*
* @param {BloggifyPlugin} plugin The plugin instance.
* @param {Function} cb The callback function.
*/
}, {
key: "loadPlugin",
value: function loadPlugin(plugin, cb) {
plugin = this.getPlugin(plugin);
return this.initPlugin(plugin, cb);
}
/**
* get
* If `true`, the raw plugin module will be returned. Otherwise, it will fetch the instance of the plugin.
*
* @param {String} name The plugin's name.
* @param {Boolean} mod The plugin's module. Default: `true`
* @return {BloggifyPlugin|String} The plugin's name or instance.
*/
}, {
key: "get",
value: function get(name) {
var _this5 = this;
var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var cb = arguments[2];
if (typeof mod === "function") {
cb = mod;
mod = false;
}
var names = [name, "bloggify-" + name, "_bloggify-" + name, name.replace(/^_?bloggify\-/g, "")];
var plug = null;
for (var i = 0; i < names.length; ++i) {
plug = this.plugins[names[i]];
if (plug) {
break;
}
}
if (mod && plug) {
plug = plug._module;
}
if (cb) {
if (plug) {
cb(plug);
} else {
var events = names.map(function (c) {
return "plugin-loaded:" + c;
});
var onload = function onload(plug, plugModule, err) {
events.forEach(function (c) {
_this5.bloggify.removeListener(c, onload);
});
cb(mod ? plugModule : plug);
};
events.forEach(function (ev) {
return _this5.bloggify.once(ev, onload);
});
}
}
return plug;
}
}]);
return BloggifyPluginLoader;
}();