Comparing version 0.1.10 to 0.1.11
208
architect.js
@@ -0,1 +1,2 @@ | ||
/*global require console process setTimeout*/ | ||
( // Module boilerplate to support node.js and AMD. | ||
@@ -127,14 +128,22 @@ (typeof module !== "undefined" && function (m) { module.exports = m(require('events')); }) || | ||
resolvePackage(base, modulePath + "/package.json", function(err, packagePath) { | ||
if (err && err.code !== "ENOENT") return callback(err); | ||
//if (err && err.code !== "ENOENT") return callback(err); | ||
var metadata = {}; | ||
try { | ||
metadata = packagePath && require(packagePath).plugin || {}; | ||
} catch(e) { | ||
return callback(e); | ||
if (!err) { | ||
try { | ||
metadata = packagePath && require(packagePath).plugin || {}; | ||
} catch(e) { | ||
return callback(e); | ||
} | ||
} | ||
(function(next) { | ||
if (packagePath) { | ||
if (err) { | ||
//@todo Fabian what is a better way? | ||
resolvePackage(base, modulePath + ".js", next); | ||
} | ||
else if (packagePath) { | ||
next(null, dirname(packagePath)); | ||
} else { | ||
} | ||
else { | ||
resolvePackage(base, modulePath, next); | ||
@@ -151,2 +160,3 @@ } | ||
} | ||
metadata.provides = metadata.provides || module.provides || []; | ||
@@ -228,3 +238,3 @@ metadata.consumes = metadata.consumes || module.consumes || []; | ||
function tryNext(base) { | ||
if (!base) { | ||
if (base == "/") { | ||
var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'"); | ||
@@ -269,3 +279,8 @@ err.code = "ENOENT"; | ||
function resolveConfig(config, callback) { | ||
function resolveConfig(config, base, callback) { | ||
if (typeof base == "function") { | ||
callback = base; | ||
base = ""; | ||
} | ||
var paths = [], pluginIndexes = {}; | ||
@@ -279,3 +294,3 @@ config.forEach(function (plugin, index) { | ||
if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) { | ||
paths.push(plugin.packagePath); | ||
paths.push((base || "") + plugin.packagePath); | ||
pluginIndexes[plugin.packagePath] = index; | ||
@@ -368,8 +383,25 @@ } | ||
if (plugins.length) { | ||
var unresolved = {}; | ||
plugins.forEach(function(plugin) { | ||
delete plugin.config; | ||
plugin.consumes.forEach(function(name) { | ||
if (unresolved[name] == false) | ||
return; | ||
if (!unresolved[name]) | ||
unresolved[name] = []; | ||
unresolved[name].push(plugin.packagePath); | ||
}); | ||
plugin.provides.forEach(function(name) { | ||
unresolved[name] = false; | ||
}); | ||
}); | ||
Object.keys(unresolved).forEach(function(name) { | ||
if (unresolved[name] == false) | ||
delete unresolved[name]; | ||
}); | ||
console.error("Could not resolve dependencies of these plugins:", plugins); | ||
console.error("Resovled services:", resolved); | ||
console.error("Resolved services:", Object.keys(resolved)); | ||
console.error("Missing services:", unresolved); | ||
throw new Error("Could not resolve dependencies"); | ||
@@ -383,4 +415,5 @@ } | ||
var app = this; | ||
app.config = config; | ||
var services = app.services = { | ||
app.config = []; | ||
app.destructors = []; | ||
app.services = { | ||
hub: { | ||
@@ -393,61 +426,122 @@ on: function (name, callback) { | ||
// Check the config | ||
// Give createApp some time to subscribe to our "ready" event | ||
(typeof process === "object" ? process.nextTick : setTimeout)(function() { | ||
app.loadPlugins(config, function(err) { | ||
if (err) { | ||
throw err; | ||
} | ||
app.emit("ready", app); | ||
}); | ||
}); | ||
} | ||
Architect.prototype = Object.create(EventEmitter.prototype, {constructor:{value:Architect}}); | ||
Architect.prototype.destroy = function() { | ||
var app = this; | ||
app.destructors.forEach(function(destroy) { | ||
destroy(); | ||
}); | ||
app.destructors = []; | ||
}; | ||
Architect.prototype.loadPlugins = function(config, callback) { | ||
var app = this; | ||
var sortedConfig; | ||
try { | ||
var sortedPlugins = checkConfig(config); | ||
} catch (err) { | ||
return app.emit("error", err); | ||
sortedConfig = checkConfig(config.concat(app.config)); | ||
} | ||
catch(ex) { | ||
return callback(ex); | ||
} | ||
var destructors = []; | ||
// prevent double loading of plugins | ||
sortedConfig = sortedConfig.filter(function(c) { | ||
return config.indexOf(c) > -1; | ||
}); | ||
function startPlugins() { | ||
var plugin = sortedPlugins.shift(); | ||
if (!plugin) | ||
return app.emit("ready", app); | ||
var p; | ||
function next(err) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
if (p && app.config.indexOf(p) === -1) { | ||
app.config.push(p); | ||
} | ||
var imports = {}; | ||
if (plugin.consumes) { | ||
plugin.consumes.forEach(function (name) { | ||
imports[name] = services[name]; | ||
}); | ||
p = sortedConfig.shift(); | ||
if (!p) { | ||
return callback(); | ||
} | ||
app.registerPlugin(p, next); | ||
} | ||
next(); | ||
}; | ||
try { | ||
plugin.setup(plugin, imports, register); | ||
} catch(e) { | ||
return app.emit("error", e); | ||
/** | ||
* Register a plugin in the service | ||
*/ | ||
Architect.prototype.registerPlugin = function(plugin, next) { | ||
var app = this; | ||
var services = app.services; | ||
var imports = {}; | ||
if (plugin.consumes) { | ||
plugin.consumes.forEach(function (name) { | ||
imports[name] = services[name]; | ||
}); | ||
} | ||
try { | ||
plugin.setup(plugin, imports, register); | ||
} catch(e) { | ||
return app.emit("error", e); | ||
} | ||
function register(err, provided) { | ||
if (err) { | ||
return app.emit("error", err); | ||
} | ||
function register(err, provided) { | ||
if (err) { return app.emit("error", err); } | ||
plugin.provides.forEach(function (name) { | ||
if (!provided.hasOwnProperty(name)) { | ||
var err = new Error("Plugin failed to provide " + name + " service. " + JSON.stringify(plugin)); | ||
return app.emit("error", err); | ||
} | ||
services[name] = provided[name]; | ||
plugin.provides.forEach(function (name) { | ||
if (!provided.hasOwnProperty(name)) { | ||
var err = new Error("Plugin failed to provide " + name + " service. " + JSON.stringify(plugin)); | ||
return app.emit("error", err); | ||
} | ||
services[name] = provided[name]; | ||
if (typeof provided[name] != "function") | ||
provided[name].name = name; | ||
app.emit("service", name, services[name]); | ||
}); | ||
if (provided && provided.hasOwnProperty("onDestroy")) | ||
destructors.push(provided.onDestroy); | ||
app.emit("plugin", plugin); | ||
startPlugins(); | ||
app.emit("service", name, services[name]); | ||
}); | ||
if (provided && provided.hasOwnProperty("onDestroy")) { | ||
app.destructors.push(provided.onDestroy); | ||
} | ||
} | ||
// Give createApp some time to subscribe to our "ready" event | ||
(typeof process === "object" ? process.nextTick : setTimeout)(startPlugins); | ||
plugin.destroy = function() { | ||
if (plugin.provides.length) { | ||
// @todo, make it possible if all consuming plugins are also dead | ||
var err = new Error("Plugins that provide services cannot be destroyed. " + JSON.stringify(plugin)); | ||
return app.emit("error", err); | ||
} | ||
this.destroy = function() { | ||
destructors.forEach(function(destroy) { | ||
destroy(); | ||
}); | ||
if (provided && provided.hasOwnProperty("onDestroy")) { | ||
app.destructors.splice(app.destructors.indexOf(provided.onDestroy), 1); | ||
provided.onDestroy(); | ||
} | ||
destructors = []; | ||
}; | ||
} | ||
Architect.prototype = Object.create(EventEmitter.prototype, {constructor:{value:Architect}}); | ||
// delete from config | ||
app.config.splice(app.config.indexOf(plugin), 1); | ||
app.emit("destroyed", plugin); | ||
}; | ||
app.emit("plugin", plugin); | ||
next(); | ||
} | ||
}; | ||
Architect.prototype.getService = function(name) { | ||
@@ -454,0 +548,0 @@ if (!this.services[name]) { |
{ | ||
"name": "architect", | ||
"description": "A Simple yet powerful plugin system for node applications", | ||
"version": "0.1.10", | ||
"version": "0.1.11", | ||
"author": "ajax.org B.V. <info@ajax.org>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
25833
544
0
1