UNPKG

bloggify-plugin-loader

Version:
305 lines (261 loc) 9.7 kB
"use strict"; 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; }();