diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index fb130d26e..55e5a5d46 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -6,7 +6,7 @@ import isEqual from 'lodash/isEqual';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from 'coral-framework/translations';
const lang = new I18n(translations);
-import {graphImporter} from 'coral-framework/helpers/plugins';
+import {queriesAndMutators as pluginQueriesAndMutators} from 'coral-framework/helpers/plugins';
import {TabBar, Tab, TabContent, Spinner} from 'coral-ui';
@@ -306,5 +306,5 @@ export default compose(
removeCommentTag,
deleteAction,
queryStream,
- ...graphImporter
+ ...pluginQueriesAndMutators,
)(Embed);
diff --git a/client/coral-framework/actions/index.js b/client/coral-framework/actions/index.js
index 1168c9c9a..638630812 100644
--- a/client/coral-framework/actions/index.js
+++ b/client/coral-framework/actions/index.js
@@ -1,11 +1,11 @@
import * as authActions from './auth';
import * as assetActions from './asset';
import * as notificationActions from './notification';
-import {actionsImporter} from '../helpers/plugins';
+import {actions as pluginActions} from '../helpers/plugins';
export default {
authActions,
assetActions,
notificationActions,
- pluginActions: actionsImporter
+ pluginActions,
};
diff --git a/client/coral-framework/components/Slot.js b/client/coral-framework/components/Slot.js
index ecadd716c..c26fb17ca 100644
--- a/client/coral-framework/components/Slot.js
+++ b/client/coral-framework/components/Slot.js
@@ -1,11 +1,12 @@
import React, {Component} from 'react';
-import {injectPlugins} from 'coral-framework/helpers/plugins';
+import {getSlotComponents} from 'coral-framework/helpers/plugins';
class Slot extends Component {
render() {
+ const {fill, ...rest} = this.props;
return (
- {injectPlugins(this.props)}
+ {getSlotComponents(fill, rest)}
);
}
diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js
index e5ab297c8..cf12c4f62 100644
--- a/client/coral-framework/helpers/plugins.js
+++ b/client/coral-framework/helpers/plugins.js
@@ -1,157 +1,62 @@
import {client as clientPlugins} from 'pluginsConfig';
import React from 'react';
+import mapValues from 'lodash/mapValues';
+import values from 'lodash/values';
+import flatten from 'lodash/flatten';
+import merge from 'lodash/merge';
-function injectPlugins ({fill, ...props}) {
- let context,
- importedFiles;
-
- function buildContext() {
-
- /**
- * buildContext creates the context for the plugins
- * require.context(, true,
- * path: The path where the importer builds the context. 'plugins' is allowed as path because it's an alias
- * regxp: A Regular Expression to match the files that the importer needs. i.e (index.js, config.json)
- * data such as path and regexp cannot be passed as arguments or variables
- */
- context = require.context('plugins', true, /\.\/(.*)\/client\/(index|config).(js|json)$/);
- return importedFiles = context
- .keys()
- .map(key => shapeData(key));
- }
-
- function getConfig (name) {
-
- /**
- * getConfig finds a the config file for each plugin
- * returns the config.json as an object to be passed as props to the plugin
- */
- return importedFiles
- .filter(key => key.format === 'json' && key.name === name)
- .reduce((acc, plugin) => {
- return context(plugin.key);
- }, {});
- }
-
- function addProps (plugin) {
-
- /**
- * addProps add properties to the injected plugins
- */
- plugin.props = {
- ...getConfig(plugin.name),
- ...props
- };
-
- return plugin;
- }
-
- function filterBySlot (plugin) {
-
- /**
- * filterBySlot
- */
- return plugin.props.slot === fill;
- }
-
- function init() {
-
- /**
- * init will build the context and
- * returns a map with each plugin and its instance
- */
- buildContext();
-
- return importedFiles
- .filter(filterByUserConfig)
- .filter(key => key.format === 'js')
- .map(addProps)
- .filter(filterBySlot)
- .reduce((entry, plugin, i) => {
- const component = context(plugin.key);
- const element = React.createElement(component, {
- key: i,
- ...plugin.props
- }, null);
-
- entry = [...entry, element];
- return entry;
- }, []);
- }
-
- return init();
-}
-
-function shapeData(test) {
-
- /**
- * shapeData shapes each item in the plugins array with useful data
- * returns an Object with the name of the plugin, the format, and it's key(filename)
- */
- const match = test.match(/\.\/(.*)\/client\/.*.(json|js)$/);
- return {
- name: match[1],
- format: match[2],
- key: match[0]
- };
-}
-
-function filterByUserConfig (plugin) {
-
- /**
- * filterByUserConfig will filter the imported files and will only keep the allowed plugins
- */
- return clientPlugins.indexOf(plugin.name) > -1;
-}
-
-function importAll(context) {
-
- /**
- * importAll builds the map to import
- */
- return context
- .keys()
- .map(key => shapeData(key))
- .filter(filterByUserConfig)
- .reduce((entry, actionsPlugin) => {
- const input = context(actionsPlugin.key);
- return {...entry, ...input};
- }, {});
-}
-
-function importAllAsArr(context) {
-
- /**
- * importAllAsArr builds the array to import
- */
- return context
- .keys()
- .map(key => shapeData(key))
- .filter(filterByUserConfig)
- .reduce((entry, graphPlugin) => {
- const input = context(graphPlugin.key);
- const res = Object.keys(input)
- .map(key => input[key]);
- return [...entry, ...res];
- }, []);
-}
-
-function actionsImporter () {
- return importAll(require.context('plugins', true, /\.\/(.*)\/client\/actions.js$/));
-}
-
-function reducersImporter () {
- return importAll(require.context('plugins', true, /\.\/(.*)\/client\/reducer.js$/));
-}
-
-function graphImporter () {
- return importAllAsArr(require.context('plugins', true, /\.\/(.*)\/client\/(queries|mutations)\/index.js$/));
-}
-
-export default {
- injectPlugins,
- actionsImporter: actionsImporter(),
- reducersImporter: reducersImporter(),
- graphImporter: graphImporter()
+// Gather require context information of different parts of the plugins.
+const contextMap = {
+ actions: require.context('plugins', true, /\.\/(.*)\/client\/actions.js$/),
+ reducers: require.context('plugins', true, /\.\/(.*)\/client\/reducer.js$/),
+ graph: require.context('plugins', true, /\.\/(.*)\/client\/(mutations|queries)\/index.js$/),
+ configs: require.context('plugins', true, /\.\/(.*)\/client\/config.json$/),
+ components: require.context('plugins', true, /\.\/(.*)\/client\/index.js$/),
};
+const getPluginName = (key) => key.match(/\.\/(.*)\/client\/.*$/)[1];
+const isActivePlugin = (plugin) => clientPlugins.indexOf(plugin) > -1;
+
+/**
+ * Loads all enabled modules of the context and returns an
+ * Array with {plugin, module} entries.
+ */
+function loadActiveModules(context) {
+ return context
+ .keys()
+ .map(key => ({key, plugin: getPluginName(key)}))
+ .filter(info => isActivePlugin(info.plugin))
+ .map(info => ({plugin: info.plugin, module: context(info.key)}));
+}
+
+const loaded = mapValues(contextMap, loadActiveModules);
+
+/**
+ * getConfig returns the config object of given plugin.
+ */
+function getConfig(plugin) {
+ return loaded.configs.filter(o => o.plugin === plugin)[0].module;
+}
+
+/**
+ * getSlotComponents returns React Elements for given slot.
+ */
+export function getSlotComponents(slot, props = {}) {
+ return loaded.components
+ .map((o, i) => ({
+ component: o.module,
+ props: {...getConfig(o.plugin), ...props, key: i},
+ }))
+ .filter(o => o.props.slot === slot)
+ .map(o => React.createElement(o.component, o.props));
+}
+
+// actions is a map of redux actions .
+export const actions = merge(...loaded.actions.map(o => ({...o.module})));
+
+// reducers is a map of redux reducers.
+export const reducers = merge(...loaded.reducers.map(o => ({...o.module})));
+
+// queriesAndMutators is an array of graphQL queries and mutators.
+export const queriesAndMutators = flatten(loaded.graph.map(o => values(o.module)));
+
diff --git a/client/coral-framework/reducers/index.js b/client/coral-framework/reducers/index.js
index e2e003f7d..f174ddbb2 100644
--- a/client/coral-framework/reducers/index.js
+++ b/client/coral-framework/reducers/index.js
@@ -1,11 +1,11 @@
import auth from './auth';
import user from './user';
import asset from './asset';
-import {reducersImporter} from '../helpers/plugins';
+import {reducers as pluginReducers} from '../helpers/plugins';
export default {
auth,
user,
asset,
- ...reducersImporter
+ ...pluginReducers
};