Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
#ConduitJS v0.3.3
ConduitJS can be used to intercept your methods and give them a pre- and post-invocation pipeline. You can think of it as targeted AOP for JavaScript methods or the Decorator pattern used to target methods specifically. Need the ability to execute behavior just before or after a method is invoked? Want to apply a predicate that determines if the method should actually fire? You can use ConduitJS to make that happen.
##Concepts Conduit supports both asynchronous & synchronous <airquotes>pipelines</airquotes>. (By "pipeline", I mean a series of functions that can be executed before and after the target method, where each step in the pipeline has the chance to mutate the args being passed to the next step.)
The primary difference(s) between async and sync Conduits, is that an asynchronous Conduit should be applied to a method that does not return a value and where you might want steps in the pipeline to be async (for example, a step might use setTimeout
- the steps don't have to be async, though). Synchronous Conduits should be applied to methods that return a value, and by their nature, each step should be synchronous (so don't use async primitives like setTimeout
and setImmediate
, etc. in the steps of a sync Conduit). It's currently possible to abort the execution of an async Conduit, but the sync Conduits can't be aborted (this may change if the need arises). The step callbacks have slightly different method signatures in sync vs async Conduits, which we'll explore below.
(where steps can optionally be async, and a next
continuation callback is passed into each step, allowing you to determine when it proceeds to the next step) and synchronous pipelines (where a return value is expected, and each step is pased the prior step's return value, with the last return value being the result passed to the caller).
##Example Usage
###Conduit.Async
As we noted above, an async Conduit doesn't have to use async primitives in steps, but it should be able to handle them. It manages this by passing a next
continuation argument to each step so that the step can invoke it when it's ready to proceed to the next step, etc. For example, adding a "before" step:
obj.doStuff.before(function(next, someValue) {
console.log("Pre-invocation step. We can see the value is: " + someValue);
next(someValue);
});
Notice that the "before" step callback function's signature is *exactly the same as the target method, except the next
callback is inserted as the first argument. Let's look at some more examples:
####Making a method an Async-Capable Conduit:
var obj = {
doStuff: function(someValue) {
console.log("The actual method is doing stuff. The actual value is " + someValue);
}
}
// make the doStuff method a conduit
obj.doStuff = new Conduit.Async({ context: obj, target: obj.doStuff });
obj.doStuff(1);
// The actual method is doing stuff. The actual value is 1
####Add a pre-invocation step to the pipeline:
// Conduit's pipeline steps are functions that take a "next" continuation callback
// as the first argument. After that you can have 0-n arguments - whatever your
// original target method signature should be
obj.doStuff.before(function(next, someValue) {
console.log("Pre-invocation step. We can see the value is: " + someValue);
next(someValue);
});
obj.doStuff(1);
/*
Pre-invocation step. We can see the value is: 1
The actual method is doing stuff. The actual value is 1
*/
####Add a post-invocation step to the pipeline:
obj.doStuff.after(function(next, someValue) {
console.log("Post-invocation step. We can see the value is: " + someValue);
next(someValue);
}, { phase: "post" });
obj.doStuff(1);
/*
Pre-invocation step. We can see the value is: 1
The actual method is doing stuff. The actual value is 1
Post-invocation step. We can see the value is: 1
*/
####Adding a pre-invocation step before other pre-invocation steps:
obj.doStuff.before(function(next, someValue) {
console.log("Another Pre-invocation step. This should execute first...");
next(someValue);
}, { prepend: true });
obj.doStuff(1)
/*
Another Pre-invocation step. This should execute first...
Pre-invocation step. We can see the value is: 1
The actual method is doing stuff. The actual value is 1
Post-invocation step. We can see the value is: 1
*/
####Adding a post-invocation step before other post-invocation steps:
obj.doStuff.after(function(next, someValue) {
console.log("Another Post-invocation step. This should execute before any other post-invocation steps...");
next(someValue);
}, { prepend: true, phase: "post" });
obj.doStuff(1)
/*
Another Pre-invocation step. This should execute first...
Pre-invocation step. We can see the value is: 1
The actual method is doing stuff. The actual value is 1
Another Post-invocation step. This should execute before any other post-invocation steps...
Post-invocation step. We can see the value is: 1
*/
####Using a predicate to determine if steps should continue processing:
var someFlag = false;
obj.doStuff.before(function(next, someValue) {
console.log("Pre-invocation predicate. I will halt execution");
if(someFlag) {
next(someValue);
}
});
obj.doStuff(1);
/*
Another Pre-invocation step. This should execute first...
Pre-invocation step. We can see the value is: 1
Pre-invocation predicate. I will halt execution
*/
####Steps can be Asynchronous with Conduit.Async
obj.doStuff.after(function(next, someValue) {
setTimeout(function() {
console.log("Post-invocation step. We can see the value is: " + someValue);
next(someValue);
}, 0);
}, { phase: "post" });
obj.doStuff(1);
###Conduit.Sync
A Synchronous Conduit should be used when you need to capture (or mutate) the return value of the target method. The rules differ slightly with synchronous Conduits:
returnValue
argument that was passed into the step as the first arg).So, in a nutshell - with synchronous Conduits, "before" steps can mutate the arguments fed the target method and "after" steps can mutate the return value of the target method.
####Making a Method a Synchronous Conduit:
var obj = {
doStuff: function(someValue) {
console.log("The actual method is doing stuff. The actual value is " + someValue);
return "doStuff fn return value";
}
}
// make the doStuff method a conduit
obj.doStuff = new Conduit.Sync({ context: obj, target: obj.doStuff });
var result = obj.doStuff(1);
// result = "doStuff fn return value"
// The actual method is doing stuff. The actual value is 1
####Add a pre-invocation step to a synchronous pipeline:
// Conduit's sync pipeline "before" steps are functions that match
// whatever your original target method signature is. These steps
// can return an array of values that will be used as the new args
// for the next step in the chain
obj.doStuff.before(function(someValue) {
console.log("Pre-invocation step. We can see the value is: " + someValue);
return [someValue + 1];
});
var result = obj.doStuff(1);
/*
result = "doStuff fn return value"
Pre-invocation step. We can see the value is: 1
The actual method is doing stuff. The actual value is 2
*/
####Add a post-invocation step to the pipeline:
// Conduit's sync pipeline "after" steps are functions that match
// whatever your original target method signature is, BUT with the
// return value of the target method or previous before step function
// as the first arg. These steps can return a value that will be
// used as the new return value, and fed to the next step in the chain.
obj.doStuff.after(function(returnValue, someValue) {
console.log("Post-invocation step. We can see the value is: " + returnValue);
return returnValue + " after step";
});
var result = obj.doStuff(1);
// result = "doStuff fn return value after step"
/*
Pre-invocation step. We can see the value is: 1
The actual method is doing stuff. The actual value is 2
Post-invocation step. We can see the value is: doStuff fn return value
doStuff fn return value after step
*/
##License It's MIT. Go forth and fork (please consider contributing back as well!).
FAQs
Give any method a pre/post invocation pipeline....
The npm package conduitjs receives a total of 149 weekly downloads. As such, conduitjs popularity was classified as not popular.
We found that conduitjs 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
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.