From 5865c3015504e49812e10b1b345c4682d1af3d9c Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 11 Jan 2018 14:20:51 -0700 Subject: [PATCH 1/4] added a plugin context --- plugins.js | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/plugins.js b/plugins.js index 577289b25..0f0b4ab3d 100644 --- a/plugins.js +++ b/plugins.js @@ -4,6 +4,8 @@ const resolve = require('resolve'); const debug = require('debug')('talk:plugins'); const Joi = require('joi'); const amp = require('app-module-path'); +const pkg = require('./package.json'); +const config = require('./config'); const PLUGINS_JSON = process.env.TALK_PLUGINS_JSON; @@ -63,6 +65,16 @@ const hookSchemas = { }), }; +/** + * PluginContext provides server context for the global application. + */ +class PluginContext { + constructor() { + this.pkg = pkg; + this.config = config; + } +} + /** * isInternal checks to see if a given plugin is internal, and returns true * if it is. @@ -168,7 +180,8 @@ Object.keys(plugins).forEach((type) => itteratePlugins(plugins[type]).forEach((p * Stores a reference to a section for a section of Plugins. */ class PluginSection { - constructor(plugins) { + constructor(context, plugins) { + this.context = context; this.required = false; this.plugins = itteratePlugins(plugins); } @@ -195,43 +208,48 @@ class PluginSection { } /** - * This itterates over the section to provide all plugin hooks that are + * This iterates over the section to provide all plugin hooks that are * available. */ - hook(hook) { + hook(hookName) { // Load the plugin source if we haven't already. this.require(); return this.plugins - .filter(({module}) => hook in module) - .filter((plugin) => { + .filter(({module}) => hookName in module) + .map((plugin) => { + + // Optionally bind the plugin context to a function if it's one. + const hook = typeof plugin.module[hookName] === 'function' ? + plugin.module[hookName].bind(this.context) : + plugin.module[hookName]; // Validate the hook. - if (hook in hookSchemas) { - Joi.assert(plugin.module[hook], hookSchemas[hook], `Plugin '${plugin.name}' failed validation for the '${hook}' hook`); + if (hookName in hookSchemas) { + Joi.assert(hook, hookSchemas[hookName], `Plugin '${plugin.name}' failed validation for the '${hookName}' hook`); } - return true; - }) - .map((plugin) => ({ - plugin, - [hook]: plugin.module[hook] - })); + return { + plugin, + [hookName]: hook, + }; + }); } } -const NullPluginSection = new PluginSection([]); +const NullPluginSection = new PluginSection({}, []); /** * Stores references to all the plugins available on the application. */ class PluginManager { constructor(plugins) { + this.context = new PluginContext(); this.sections = {}; for (let section in plugins) { - this.sections[section] = new PluginSection(plugins[section]); + this.sections[section] = new PluginSection(this.context, plugins[section]); } } From 4eda547734a2ea41425c4b364f837a35c6c7bb28 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 11 Jan 2018 14:22:45 -0700 Subject: [PATCH 2/4] removed config from context --- plugins.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins.js b/plugins.js index 0f0b4ab3d..1d46cea1c 100644 --- a/plugins.js +++ b/plugins.js @@ -5,7 +5,6 @@ const debug = require('debug')('talk:plugins'); const Joi = require('joi'); const amp = require('app-module-path'); const pkg = require('./package.json'); -const config = require('./config'); const PLUGINS_JSON = process.env.TALK_PLUGINS_JSON; @@ -71,7 +70,6 @@ const hookSchemas = { class PluginContext { constructor() { this.pkg = pkg; - this.config = config; } } From 07826a9bf472cf0fe6bfa28316c56ca5617f0e65 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 11 Jan 2018 15:20:33 -0700 Subject: [PATCH 3/4] fixing spelling :( --- plugins.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins.js b/plugins.js index 1d46cea1c..eeb2c0786 100644 --- a/plugins.js +++ b/plugins.js @@ -138,14 +138,14 @@ class Plugin { require() { if (typeof this.path === 'undefined') { - throw new Error(`plugin '${this.name}' is not local and is not resolvable, plugin reconsiliation may be required`); + throw new Error(`plugin '${this.name}' is not local and is not resolvable, plugin reconciliation may be required`); } try { this.module = require(this.path); } catch (e) { if (e && e.code && e.code === 'MODULE_NOT_FOUND' && isInternal(this.name)) { - console.error(new Error(`plugin '${this.name}' could not be loaded due to missing dependencies, plugin reconsiliation may be required`)); + console.error(new Error(`plugin '${this.name}' could not be loaded due to missing dependencies, plugin reconciliation may be required`)); throw e; } @@ -156,19 +156,19 @@ class Plugin { } /** - * Itterates over the plugins and gets the plugin path's, version, and name. + * Iterates over the plugins and gets the plugin path's, version, and name. * * @param {Array} plugins * @returns {Array} */ -const itteratePlugins = (plugins) => plugins.map((p) => new Plugin(p)); +const iteratePlugins = (plugins) => plugins.map((p) => new Plugin(p)); // Add each plugin folder to the allowed import path so that they can import our -// internal dependancies. -Object.keys(plugins).forEach((type) => itteratePlugins(plugins[type]).forEach((plugin) => { +// internal dependencies. +Object.keys(plugins).forEach((type) => iteratePlugins(plugins[type]).forEach((plugin) => { // The plugin may be remote, and therefore not installed. We check here if the - // plugin path is available before trying to monkeypatch it's require path. + // plugin path is available before trying to monkey patch it's require path. if (plugin.path) { amp.enableForDir(path.dirname(plugin.path)); } @@ -181,7 +181,7 @@ class PluginSection { constructor(context, plugins) { this.context = context; this.required = false; - this.plugins = itteratePlugins(plugins); + this.plugins = iteratePlugins(plugins); } require() { @@ -278,5 +278,5 @@ module.exports = { PluginManager, isInternal, pluginPath, - itteratePlugins + iteratePlugins }; From a4e8ea93bc840acfe2f55b6f05998e3014b19990 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 11 Jan 2018 15:24:46 -0700 Subject: [PATCH 4/4] fixed import typo --- bin/cli-plugins | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/cli-plugins b/bin/cli-plugins index 4f293b0c3..bf4014e51 100755 --- a/bin/cli-plugins +++ b/bin/cli-plugins @@ -21,7 +21,7 @@ const path = require('path'); const spawn = require('cross-spawn'); const semver = require('semver'); const resolve = require('resolve'); -const {plugins, itteratePlugins, isInternal} = require('../plugins'); +const {plugins, iteratePlugins, isInternal} = require('../plugins'); function existsInNodeModules(name) { try { @@ -71,7 +71,7 @@ function reconcilePackages({quiet = false, upgradeRemote = false}) { } for (let i in plugins) { - let section = itteratePlugins(plugins[i]); + let section = iteratePlugins(plugins[i]); for (let j in section) { let {name, version} = section[j];