middlewarify
Advanced tools
Comparing version 0.0.4 to 0.1.0
@@ -12,2 +12,9 @@ /** | ||
/** @enum {string} middleware types */ | ||
middlewarify.Type = { | ||
BEFORE: 'before', | ||
AFTER: 'after', | ||
USE: 'use', | ||
}; | ||
/** | ||
@@ -25,20 +32,38 @@ * Apply the middleware pattern to the provided object's propert. | ||
var middObj = Object.create(null); | ||
middObj.midds = []; | ||
middObj.finalMidd = noopMidd; | ||
middObj.params = { | ||
middObj.mainCallback = noopMidd; | ||
/** | ||
* The default parameters object. | ||
* | ||
* @type {Object} | ||
*/ | ||
var defaultParams = { | ||
throwErrors: true, | ||
beforeAfter: false, | ||
}; | ||
if (__.isFunction(optFinalCb)) { | ||
middObj.finalMidd = optFinalCb; | ||
middObj.mainCallback = optFinalCb; | ||
} | ||
var params; | ||
if (__.isObject(optFinalCb)) { | ||
__.extend(middObj.params, optFinalCb); | ||
params = optFinalCb; | ||
} | ||
if (__.isObject(optParams)) { | ||
__.extend(middObj.params, optParams); | ||
params = optParams; | ||
} | ||
middObj.params = __.extend(defaultParams, params); | ||
obj[prop] = middlewarify._runAll.bind(null, middObj); | ||
obj[prop].use = middlewarify._use.bind(null, middObj); | ||
obj[prop] = middlewarify._invokeMiddleware.bind(null, middObj); | ||
if (middObj.params.beforeAfter) { | ||
middObj.beforeMidds = []; | ||
middObj.afterMidds = []; | ||
obj[prop].before = middlewarify._use.bind(null, middObj, middlewarify.Type.BEFORE); | ||
obj[prop].after = middlewarify._use.bind(null, middObj, middlewarify.Type.AFTER); | ||
} else { | ||
middObj.midds = []; | ||
obj[prop].use = middlewarify._use.bind(null, middObj, middlewarify.Type.USE); | ||
} | ||
}; | ||
@@ -54,3 +79,3 @@ | ||
*/ | ||
middlewarify._runAll = function(middObj) { | ||
middlewarify._invokeMiddleware = function(middObj) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
@@ -67,5 +92,11 @@ | ||
var midds = Array.prototype.slice.call(middObj.midds, 0); | ||
midds.push(middObj.finalMidd); | ||
var midds; | ||
if (middObj.params.beforeAfter) { | ||
midds = Array.prototype.slice.call(middObj.beforeMidds, 0); | ||
midds.push(middObj.mainCallback); | ||
midds = midds.concat(middObj.afterMidds); | ||
} else { | ||
midds = Array.prototype.slice.call(middObj.midds, 0); | ||
midds.push(middObj.mainCallback); | ||
} | ||
middlewarify._fetchAndInvoke(midds, args, middObj.params, done); | ||
@@ -122,23 +153,38 @@ | ||
* | ||
* @param {Object} middObj Internal midd object. | ||
* @param {Object} middObj Internal midd object. | ||
* @param {middlewarify.Type} middType Middleware type. | ||
* @param {Function|Array.<Function>...} Any combination of function containers. | ||
* @private | ||
*/ | ||
middlewarify._use = function(middObj) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
middlewarify._use = function(middObj, middType) { | ||
var middlewares = Array.prototype.slice.call(arguments, 2); | ||
var len = args.length; | ||
var len = middlewares.length; | ||
if (0 === len) return; | ||
args.forEach(function(argItem) { | ||
if (Array.isArray(argItem)) { | ||
argItem.forEach(function(argFn) { | ||
function pushMidd(fn) { | ||
switch(middType) { | ||
case middlewarify.Type.BEFORE: | ||
middObj.beforeMidds.push(fn); | ||
break; | ||
case middlewarify.Type.AFTER: | ||
middObj.afterMidds.push(fn); | ||
break; | ||
case middlewarify.Type.USE: | ||
middObj.midds.push(fn); | ||
break; | ||
} | ||
} | ||
middlewares.forEach(function(middleware) { | ||
if (Array.isArray(middleware)) { | ||
middleware.forEach(function(argFn) { | ||
if (__.isFunction(argFn)) { | ||
middObj.midds.push(argFn); | ||
pushMidd(argFn); | ||
} | ||
}); | ||
} else if (__.isFunction(argItem)) { | ||
middObj.midds.push(argItem); | ||
} else if (__.isFunction(middleware)) { | ||
pushMidd(middleware); | ||
} | ||
}); | ||
}; |
{ | ||
"name": "middlewarify", | ||
"description": "Apply the middleware pattern to any function.", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"homepage": "https://github.com/thanpolas/middlewarify", | ||
@@ -30,3 +30,3 @@ "author": { | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha -u tdd -R spec test.js" | ||
"test": "node_modules/.bin/mocha -u tdd -R spec test/" | ||
}, | ||
@@ -33,0 +33,0 @@ "dependencies": { |
147
README.md
# Middlewarify | ||
Apply the middleware pattern to any function. | ||
Apply the middleware pattern, easy. You can add two types of middleware, a single queue type using the keyword `use()` or a Before/After type using `before()` and `after()` hooks. | ||
[![Build Status](https://travis-ci.org/thanpolas/middlewarify.png)](https://travis-ci.org/thanpolas/middlewarify) | ||
[![NPM](https://nodei.co/npm/middlewarify.png?downloads=true&stars=true)](https://nodei.co/npm/middlewarify/) | ||
## Install | ||
@@ -13,7 +16,6 @@ | ||
## Documentation | ||
## Quick Start | ||
### Quick Start Example | ||
### Quick Start Examples | ||
Creating a middleware: | ||
@@ -26,10 +28,11 @@ | ||
// this will be the last callback to be invoked | ||
tasks._create = function(done) { | ||
console.log('tasks._create Final Fn to be invoked'); | ||
// this is the main callback of your middleware, | ||
// it will be the last callback to be invoked. | ||
function createTask(done) { | ||
console.log('createTask Final Fn to be invoked'); | ||
done(); | ||
}; | ||
} | ||
// Make the'create' Middleware Container. | ||
midd.make(tasks, 'create', tasks._create); | ||
midd.make(tasks, 'create', createTask); | ||
``` | ||
@@ -74,6 +77,48 @@ | ||
### Methods | ||
#### Using the Before / After Middleware type | ||
#### make(object, property, optFinalCallback, optOptions) | ||
```js | ||
var midd = require('middlewarify'); | ||
var tasks = module.exports = {}; | ||
// This is the main callback of your middleware, | ||
// it will be invoked after all 'before' middleware finish | ||
// and before any 'after' middleware. | ||
function createTask(done) { | ||
console.log('Invoked Second'); | ||
done(null); | ||
}; | ||
// Make the'create' Middleware Container using before/after hooks | ||
midd.make(tasks, 'create', createTask, {beforeAfter: true}); | ||
/** ... */ | ||
// add a before hook | ||
tasks.create.before(function(next) { | ||
console.log('Invoked First'); | ||
next(); | ||
}); | ||
// add an after hook | ||
tasks.create.after(function(next) { | ||
console.log('Invoked Third and last'); | ||
next(); | ||
}); | ||
/** ... */ | ||
// invoke all middleware | ||
tasks.create().done(function(err){ | ||
// at this point all middleware have finished. | ||
}); | ||
``` | ||
## Middlewarify Methods | ||
### make(object, property, optMainCallback, optOptions) | ||
The `middlewarify.make()` method will apply the middleware pattern to an Object's property, this property will be called the *Middleware Container*. | ||
@@ -89,5 +134,5 @@ | ||
You can add a third argument, the `optFinalCallback`. As the name suggests this will be the final callback to be invoked in the chain of middleware execution. This callback gets the same arguments as any other middleware. | ||
You can add a third argument, the `optMainCallback`, this is the main payload of your middleware. `optOptions` is one more argument you can pass to Middlewarify to define behavior. Both `optOptions` and `optMainCallback` are optional and can be interswitched, i.e. you can pass options as a third argument, read on for examples and what are the available options. | ||
##### make() Options | ||
#### make() Options | ||
@@ -97,3 +142,6 @@ `make()` accepts the following options: | ||
* `throwErrors` type: **Boolean**, default: `true` If set to false all thrown errors will be suppressed and available only through the `.done()` method. | ||
* `beforeAfter` type: **Boolean**, default: `false` If set to true the Before/After hooks will be used instead of the single queue `use` hook, which is the default, view the [example displayed above](#using-the-before--after-middleware-type). | ||
##### `throwErrors` Example | ||
```js | ||
@@ -118,3 +166,3 @@ | ||
The Middleware Container exposes a `use` method so you can add any number of middleware. `use()` accepts any number of parameters as long they are of type Function or Arrays of Functions. | ||
The Middleware Container by default exposes a `use` method so you can add any number of middleware. `use()` accepts any number of parameters as long they are of type Function or Arrays of Functions. When the Before/After flag is enabled `use` is no longer there and instead you get `before` and `after` methods to hook your middleware. All three hook types accept the same argument types and patterns as described bellow. | ||
@@ -230,9 +278,74 @@ ```js | ||
#### Why a .done() function | ||
The trailling `.done()` function will notify you of the ultimate outcome of the middleware execution. The problem for having the callback as an argument when invoking the middleware with `tasks.create()` is that there is no way to determine if that is the callback to call when all middleware are done, or an argument that should be passed to all middleware. | ||
This becomes more aparent when using the Before/After feature of Middlewarify which binds a `before` and `after` functions instead of `use`. | ||
```js | ||
var midd = require('middlewarify'); | ||
var tasks = module.exports = {}; | ||
// this is the main callback of your middleware. | ||
function createTask(cb, done) { | ||
anAsyncOp(function(err, result) { | ||
if (err) { | ||
cb(err); | ||
done(err); | ||
return; | ||
} | ||
// cb is the anon function passed as argument when the middleware will be | ||
// invoked, done will signal to Middlewarify that execution has completed. | ||
cb(null, result); | ||
done(null, result); | ||
}); | ||
} | ||
// Make the'create' Middleware Container using before/after hooks | ||
midd.make(tasks, 'create', createTask, {beforeAfter: true}); | ||
/** ... */ | ||
// add a before hook | ||
tasks.create.before(function(cb, next) { | ||
// ... | ||
next(); | ||
}); | ||
// add an after hook | ||
tasks.create.after(function(cb, result, next) { | ||
// do something with "result" | ||
next(); | ||
}); | ||
/** ... */ | ||
// invoke all middleware | ||
tasks.create(function(err, result, done){ | ||
// this is invoked by the "createTask" function and BEFORE any of the | ||
// "after" middleware are executed. | ||
done(); | ||
}).done(function(err, fn, result){ | ||
// the "fn" is the anon function defined as an argument to tasks.create()! | ||
// at this point all middleware have finished. | ||
}); | ||
``` | ||
## Release History | ||
- **v0.1.0**, *28 Jan 2014* | ||
- Added Before/After feature | ||
- Reorganized tests | ||
- **v0.0.4**, *10 Oct 2013* | ||
- Added option to not throw errors | ||
- Added option to not throw errors | ||
- **v0.0.3**, *02 Aug 2013* | ||
- Added a more explicit way to declare callbacks when invoking the middleware. | ||
- Added a more explicit way to declare callbacks when invoking the middleware. | ||
- **v0.0.2**, *15 JuL 2013* | ||
- Big Bang | ||
- Big Bang | ||
@@ -239,0 +352,0 @@ ## License |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
34256
12
582
356
1