
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Generic plugin loader facility.
Install the module with: npm install in
const PluginLoader = require('in');
A plugin should expose a init function.
module.exports.init = function(app, config){};
A module can expose a priority value:
module.exports.priority = 5000;
A negative value indicates a higher priority
A module can expose a 'dependencies' value:
module.exports.dependencies = ['logger'];
A plugin is nothing more than a regular Node module. By default, we expect plugins to expose an init function that takes two arguments:
This is where all plugins will be mounted. This would normally be your application instance.
It will mount all plugins found in directory into the provided context.
This is in effect applying find, filter, load, sort, and mount in that order.
Scans a directory for files and directories, returning a list of absolute paths to the files.
It target is not an absolute path, we resolve it against basepath.
Sorts an array of plugins after they have been loaded. By default it uses sortFilter:
It will looks for module.exports.priority and sort based on that:
function _sortFilter(plugins){
function filter(a, b) {
function p(i){
return i.priority === undefined ? 0 : i.priority;
}
return p(a) < p(b) ? -1 : 1;
}
return plugins.sort(filter);
}
The library also exposes a sortByDependencies filter, which you can use instead of the default sortFilter.
const loader = new PluginLoader({
sortFilter: require('in').sortByDependencies
});
Modules should expose a dependencies array listing the ids of depended modules.
module.exports.dependencies = ['logger', 'persistence'];
When we call load we apply the normalize function which will ensures that plugins can be any of the following:
const plugins = '/Users/application/plugins/authentication';
Output after calling normalize:
[
{
"id": "authentication",
"path": "/Users/application/plugins/authentication",
"config": {}
}
]
const plugins = ['/Users/application/plugins/authentication'];
Output after calling normalize:
[
{
"id": "authentication",
"path": "/Users/application/plugins/authentication",
"config": {}
}
]
const plugins = {
'/Users/application/plugins/authentication': { hash: 'sh1' }
};
Output after calling normalize:
[
{
"id": "authentication",
"path": "/Users/application/plugins/authentication",
"config": {
"hash": "sh1"
}
}
]
const plugins = [
{'/Users/application/plugins/authentication':{ hash: 'sh1' }},
'debug'
];
Output after calling normalize:
[
{
"id": "authentication",
"path": "/Users/application/plugins/authentication",
"config": {
"hash": "sh1"
}
},
{
"id": "debug",
"path": "debug",
"config": {}
}
]
Public: Apply minimatch patterns against paths, an array of paths. The default pattern is ['**', '!node_modules', '!.git']
Returns a Promise which once resolved will contain an Array of filtered paths.
Given a list of plugins, create a plugin object with metadata and the result of requireing the module.
We create a bean per plugin:
{
id: 'logger',
path: '/Users/in/examples/plugins/logger.js',
config: {},
plugin: { init: [Function], priority: -100 },
isLocal: true
}
Makes plugins available to the provided context by calling mountHandler to previously loaded plugins.
Adds a plugin to the provided context.
function _mount(bean, context, config={}){
config = extend({}, bean.config, config);
var plugin = bean.plugin;
if(typeof bean.config === 'function') return bean.config(plugin, context, config);
if(typeof bean.config.mount === 'function') return bean.config.mount(plugin, context, config);
if(typeof plugin.init === 'function') return plugin.init(context, config);
return context[bean.id] = plugin;
}
Function that will be called right after mount
Look at the examples directory. Run it with node examples/index.js.
Directory structure:
const PluginManager = require('..');
const EventEmitter = require('events');
const app = new EventEmitter();
app.on('plugins.ready', _ => {
app.logger.info('Application plugins loaded');
});
const manager = new PluginManager({
context: app,
basepath: __dirname,
afterMount: (context) => context.emit('plugins.ready')
});
manager.mountDirectory('./plugins')
.catch(console.error);
logger.js:
module.exports.init = function(app, config) {
app.logger = console;
app.logger.info('Plugin logger loaded!');
};
module.exports.priority = -100;
repl.js:
module.exports.init = function(app, config) {
app.repl = {
context: {app}
};
app.logger.info('Plugin REPL loaded!');
};
pubsub.js:
module.exports.init = function(app, config) {
app.pubsub = {
publibsh: function(type, event){
app.logger.warn('publish: %s. payload: %s', type, event);
},
subscribe: function(type, handler){
app.logger.warn('subscribe to %s', type);
}
};
app.logger.info('Plugin pubsub loaded!');
};
authentication/index.js:
module.exports.init = function(app, config) {
app.auth = {
check: function(){}
};
app.logger.info('Plugin auth loaded!');
};
module.exports.priority = 500;
node examples/load/index.js:
Plugin logger loaded!
Plugin REPL loaded!
Plugin pubsub loaded!
Plugin auth loaded!
Application plugins loaded
normalizePath from lib/normalizeArguments.jsgetIdFromPath from lib/normalizeArguments.jssortByDependenciesafterMount in optionsnormalizePath use basepath from argumentafterMountmountDirectoryCopyright (c) 2015 goliatone
Licensed under the MIT license.
FAQs
Plugin loader. Plays with Ware
The npm package in receives a total of 6,075 weekly downloads. As such, in popularity was classified as popular.
We found that in demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.