diff --git a/server/plugins-manager.js b/server/plugins-manager.js index 214c5cca..a1b13a4c 100644 --- a/server/plugins-manager.js +++ b/server/plugins-manager.js @@ -1,8 +1,13 @@ const fs = require("fs"); const { log } = require("../src/util"); +const path = require("path"); class PluginsManager { + /** + * Plugin List + * @type {Plugin[]} + */ pluginList = []; /** @@ -10,29 +15,93 @@ class PluginsManager { */ pluginsDir; - constructor(dir) { + /** + * + * @param {UptimeKumaServer} server + * @param {string} dir + */ + constructor(server, dir) { this.pluginsDir = dir; if (! fs.existsSync(this.pluginsDir)) { fs.mkdirSync(this.pluginsDir, { recursive: true }); } + log.debug("plugin", "Scanning plugin directory"); let list = fs.readdirSync(this.pluginsDir); this.pluginList = []; for (let item of list) { - let indexFile = this.pluginsDir + item + "/index.js"; + let plugin = new Plugin(server, this.pluginsDir + item); - if (fs.existsSync(indexFile)) { - this.pluginList.push(require(indexFile)); - log.debug("plugin", indexFile); - log.info("plugin", `${item} loaded`); + try { + plugin.load(); + this.pluginList.push(plugin); + } catch (e) { + log.error("plugin", "Failed to load plugin: " + this.pluginsDir + item); + log.error("plugin", "Reason: " + e.message); } } } +} +class Plugin { + + server = undefined; + pluginDir = undefined; + + /** + * Must be an `new-able` class. + * @type {function} + */ + pluginClass = undefined; + + /** + * + * @type {*} + */ + object = undefined; + info = {}; + + /** + * + * @param {UptimeKumaServer} server + * @param {string} pluginDir + */ + constructor(server, pluginDir) { + this.server = server; + this.pluginDir = pluginDir; + } + + load() { + let indexFile = this.pluginDir + "/index.js"; + let packageJSON = this.pluginDir + "/package.json"; + + if (fs.existsSync(indexFile)) { + this.pluginClass = require(path.join(process.cwd(), indexFile)); + + let pluginClassType = typeof this.pluginClass; + + if (pluginClassType === "function") { + this.object = new this.pluginClass(this.server); + } else { + throw new Error("Invalid plugin, it does not export a class"); + } + + if (fs.existsSync(packageJSON)) { + this.info = require(path.join(process.cwd(), packageJSON)); + } else { + this.info.fullName = this.pluginDir; + this.info.name = "[unknown]"; + this.info.version = "[unknown-version]"; + } + + log.info("plugin", `${this.info.fullName} v${this.info.version} loaded`); + } + } } module.exports = { - PluginsManager + PluginsManager, + Plugin }; diff --git a/server/uptime-kuma-server.js b/server/uptime-kuma-server.js index 483d7920..2f7ae0df 100644 --- a/server/uptime-kuma-server.js +++ b/server/uptime-kuma-server.js @@ -135,7 +135,7 @@ class UptimeKumaServer { } loadPlugins(dir) { - this.pluginsManager = new PluginsManager(dir); + this.pluginsManager = new PluginsManager(this, dir); } }