-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
92a090e
commit de41864
Showing
7 changed files
with
3,706 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,107 @@ | ||
# middleware-if-unless | ||
Invokes connect-like middleware if / unless routing criteria matches. Inspired on express-unless module. | ||
Invokes connect-like middleware if / unless routing criteria matches. Inspired on [express-unless](https://www.npmjs.com/package/express-unless) module. | ||
|
||
## Main features | ||
- Advanced routes matching capabilities. Uses [find-my-way](https://www.npmjs.com/package/find-my-way) or any compatible router to match the routes. | ||
- `iff`: execute middleware only if the routes matches. Ideal use case: API gateways (see: [k-fastify-gateway](https://www.npmjs.com/package/k-fastify-gateway)) | ||
- `unless`: execute middleware always unless the routes matches. | ||
- Arbitraty chaining of iff -> unless of vice-versa. | ||
- Low overhead, crazy fast implementation. | ||
|
||
|
||
# Usage example | ||
How to extend any connect-like middleware: | ||
```js | ||
const iu = require('middleware-if-unless')() | ||
|
||
const middleware = function (req, res, next) { | ||
res.body = 'hit' | ||
|
||
return next() | ||
} | ||
|
||
// extend middleware with iff/unless capabilities | ||
iu(middleware) | ||
``` | ||
## unless | ||
Execute middleware unless routing restrictions matches: | ||
```js | ||
const app = require('express')() | ||
app.use(middleware.unless([ | ||
'/not/allowed/to/hit' | ||
])) | ||
|
||
... | ||
``` | ||
In this example, all requests except `[GET] /not/allowed/to/hit` will cause the middleware to be executed. | ||
|
||
## if | ||
Execute middleware only if routing restrictions matches: | ||
```js | ||
const app = require('express')() | ||
app.use(middleware.iff([ | ||
{ | ||
methods: ['POST', 'DELETE', 'PUT', 'PATCH'], | ||
url: '/tasks/:id' | ||
} | ||
])) | ||
|
||
... | ||
``` | ||
### Chaining | ||
You can optionally chain iff -> unless or vice-versa: | ||
```js | ||
app.use(middleware | ||
.iff(req => req.url.startsWith('/pets')) // 4 check | ||
.iff([ // 3 check | ||
'/pets/*', | ||
'/pets/:id/*' | ||
]).unless([ // 2 check | ||
'/pets/:id/owners', | ||
{ | ||
url: '/pets/:id', methods: ['DELETE'] | ||
} | ||
]).unless(req => req.url.endsWith('.js')) // 1 check | ||
) | ||
``` | ||
# Configuration | ||
## module | ||
```js | ||
const iu = require('middleware-if-unless')( | ||
// optional router configuration: | ||
// https://www.npmjs.com/package/find-my-way#findmywayoptions | ||
{ | ||
} | ||
, | ||
// optional router factory: | ||
// allows to override find-my-way as default router | ||
function(opts){} | ||
) | ||
``` | ||
## iff / unless | ||
Both methods share the same configuration format: | ||
|
||
### - routing criteria is a function | ||
```js | ||
middleware.iff(req => req.url.startsWith('/pets')) | ||
``` | ||
### - routing criteria is an array of routes | ||
```js | ||
middleware.iff([ | ||
'/login', // if string is passed, the GET method is inferred | ||
{ | ||
methods: ['DELETE', 'POST', '...'], | ||
url: '/task/:id/*' | ||
} | ||
]) | ||
``` | ||
### - routing criteria is an object | ||
```js | ||
middleware.unless({ endpoints: [ | ||
'/login', // if string is passed, the GET method is inferred | ||
{ | ||
methods: ['DELETE', 'POST', '...'], | ||
url: '/task/:id/*' | ||
} | ||
]}) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
const op = () => true | ||
|
||
module.exports = function (routerOpts = {}, routerFactory) { | ||
routerOpts.defaultRoute = () => false | ||
routerFactory = routerFactory || require('find-my-way') | ||
|
||
function exec (options, isIff = true) { | ||
const middleware = this | ||
|
||
// independent router instance per config | ||
const router = routerFactory(routerOpts) | ||
|
||
const opts = typeof options === 'function' ? { custom: options } : (Array.isArray(options) ? { endpoints: options } : options) | ||
if (opts.endpoints && opts.endpoints.length) { | ||
// setup matching router | ||
opts.endpoints.map(endpoint => typeof endpoint === 'string' ? { methods: ['GET'], url: endpoint } : endpoint).forEach(({ methods, url }) => { | ||
router.on(methods, url, op) | ||
}) | ||
} | ||
|
||
const result = function (req, res, next) { | ||
// supporting custom matching function | ||
if (opts.custom) { | ||
if (opts.custom(req)) { | ||
if (isIff) { | ||
return middleware(req, res, next) | ||
} | ||
} else if (!isIff) { | ||
return middleware(req, res, next) | ||
} | ||
|
||
// leave here and do not process opts.endpoints | ||
return next() | ||
} | ||
|
||
// matching endpoints and moving forward | ||
if (router.lookup(req, res)) { | ||
if (isIff) { | ||
return middleware(req, res, next) | ||
} | ||
} else if (!isIff) { | ||
return middleware(req, res, next) | ||
} | ||
|
||
return next() | ||
} | ||
|
||
// allowing chaining | ||
result.iff = iff | ||
result.unless = unless | ||
|
||
return result | ||
} | ||
|
||
function iff (options) { | ||
return exec.call(this, options, true) | ||
} | ||
function unless (options) { | ||
return exec.call(this, options, false) | ||
} | ||
|
||
return function (middleware) { | ||
middleware.iff = iff | ||
middleware.unless = unless | ||
|
||
return middleware | ||
} | ||
} |
Oops, something went wrong.