middie
Advanced tools
Comparing version 7.0.0 to 7.1.0
69
index.js
'use strict' | ||
const fp = require('fastify-plugin') | ||
const Middie = require('./engine') | ||
const kMiddlewares = Symbol('fastify-middie-middlewares') | ||
const kMiddie = Symbol('fastify-middie-instance') | ||
const warning = require('process-warning')() | ||
warning.create('FastifyWarning.middie', 'FST_MODULE_DEP_middie'.toUpperCase(), 'middie has been deprecated. Use @fastify/middie@8.0.0 instead.') | ||
warning.emit('FST_MODULE_DEP_middie'.toUpperCase()) | ||
function middiePlugin (fastify, options, next) { | ||
fastify.decorate('use', use) | ||
fastify[kMiddlewares] = [] | ||
fastify[kMiddie] = Middie(onMiddieEnd) | ||
fastify | ||
.addHook(options.hook || 'onRequest', runMiddie) | ||
.addHook('onRegister', onRegister) | ||
function use (path, fn) { | ||
if (typeof path === 'string') { | ||
const prefix = this.prefix | ||
path = prefix + (path === '/' && prefix.length > 0 ? '' : path) | ||
} | ||
this[kMiddlewares].push([path, fn]) | ||
if (fn == null) { | ||
this[kMiddie].use(path) | ||
} else { | ||
this[kMiddie].use(path, fn) | ||
} | ||
return this | ||
} | ||
function runMiddie (req, reply, next) { | ||
if (this[kMiddlewares].length > 0) { | ||
req.raw.originalUrl = req.raw.url | ||
req.raw.id = req.id | ||
req.raw.hostname = req.hostname | ||
req.raw.ip = req.ip | ||
req.raw.ips = req.ips | ||
req.raw.log = req.log | ||
req.raw.body = req.body | ||
req.raw.query = req.query | ||
reply.raw.log = req.log | ||
this[kMiddie].run(req.raw, reply.raw, next) | ||
} else { | ||
next() | ||
} | ||
} | ||
function onMiddieEnd (err, req, res, next) { | ||
next(err) | ||
} | ||
function onRegister (instance) { | ||
const middlewares = instance[kMiddlewares].slice() | ||
instance[kMiddlewares] = [] | ||
instance[kMiddie] = Middie(onMiddieEnd) | ||
instance.decorate('use', use) | ||
for (const middleware of middlewares) { | ||
instance.use(...middleware) | ||
} | ||
} | ||
next() | ||
} | ||
module.exports = fp(middiePlugin, { | ||
fastify: '4.x', | ||
name: 'middie' | ||
}) | ||
module.exports = require('middie-deprecated') |
{ | ||
"name": "middie", | ||
"version": "7.0.0", | ||
"description": "Middleware engine for Fastify", | ||
"version": "7.1.0", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"scripts": { | ||
"coverage": "tap --cov --coverage-report=html test.js", | ||
"test": "standard && tap --no-coverage test/*.test.js && tsd" | ||
}, | ||
"keywords": [ | ||
"fastify", | ||
"middleware", | ||
"webframework", | ||
"performances" | ||
], | ||
"author": "Matteo Collina <hello@matteocollina.com>", | ||
"contributors": [ | ||
{ | ||
"name": "Tomas Della Vedova", | ||
"url": "http://delved.org" | ||
} | ||
], | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/fastify/middleman.git" | ||
"url": "git://github.com/fastify/middie.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/fastify/middleman/issues" | ||
}, | ||
"homepage": "https://github.com/fastify/middleman#readme", | ||
"devDependencies": { | ||
"@types/connect": "^3.4.33", | ||
"@types/node": "^17.0.0", | ||
"cors": "^2.8.5", | ||
"fastify": "^4.0.0-rc.2", | ||
"helmet": "^5.0.0", | ||
"pre-commit": "^1.2.2", | ||
"serve-static": "^1.14.1", | ||
"simple-get": "^4.0.0", | ||
"standard": "^17.0.0", | ||
"tap": "^16.0.0", | ||
"tsd": "^0.20.0", | ||
"typescript": "4.6.4" | ||
}, | ||
"homepage": "https://github.com/fastify/middie", | ||
"dependencies": { | ||
"fastify-plugin": "^3.0.0", | ||
"path-to-regexp": "^6.1.0", | ||
"reusify": "^1.0.4" | ||
}, | ||
"tsd": { | ||
"directory": "test" | ||
"process-warning": "^1.0.0", | ||
"middie-deprecated": "npm:middie@7.0.0" | ||
} | ||
} |
252
README.md
# middie | ||
![CI](https://github.com/fastify/middie/workflows/CI/badge.svg) | ||
[![NPM version](https://img.shields.io/npm/v/middie.svg?style=flat)](https://www.npmjs.com/package/middie) | ||
[![Known Vulnerabilities](https://snyk.io/test/github/fastify/middie/badge.svg)](https://snyk.io/test/github/fastify/middie) | ||
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) | ||
*middie* is the plugin that adds middleware support on steroids to [Fastify](https://www.npmjs.com/package/fastify). | ||
The syntax style is the same as [express](http://npm.im/express)/[connect](https://www.npmjs.com/package/connect). | ||
Does not support the full syntax `middleware(err, req, res, next)`, because error handling is done inside Fastify. | ||
## Install | ||
``` | ||
npm install middie | ||
``` | ||
## Usage | ||
Register the plugin and start using your middleware. | ||
```js | ||
const Fastify = require('fastify') | ||
async function build () { | ||
const fastify = Fastify() | ||
await fastify.register(require('middie'), { | ||
hook: 'onRequest' // default | ||
}) | ||
// do you know we also have cors support? | ||
// https://github.com/fastify/fastify-cors | ||
fastify.use(require('cors')()) | ||
return fastify | ||
} | ||
build() | ||
.then(fastify => fastify.listen(3000)) | ||
.catch(console.log) | ||
``` | ||
### Encapsulation support | ||
The encapsulation works as usual with Fastify, you can register the plugin in a subsystem and your code will work only inside there, or you can declare the middie plugin top level and register a middleware in a nested plugin, and the middleware will be executed only for the nested routes of the specific plugin. | ||
*Register the plugin in its own subsystem:* | ||
```js | ||
const fastify = require('fastify')() | ||
fastify.register(subsystem) | ||
async function subsystem (fastify, opts) { | ||
await fastify.register(require('middie')) | ||
fastify.use(require('cors')()) | ||
} | ||
``` | ||
*Register a middleware in a specific plugin:* | ||
```js | ||
const fastify = require('fastify')() | ||
fastify | ||
.register(require('middie')) | ||
.register(subsystem) | ||
async function subsystem (fastify, opts) { | ||
fastify.use(require('cors')()) | ||
} | ||
``` | ||
### Hooks and middleware | ||
__Every registered middleware will be run during the `onRequest` hook phase__, so the registration order is important. | ||
Take a look at the [Lifecycle](https://www.fastify.io/docs/latest/Reference/Lifecycle/) documentation page to understand better how every request is executed. | ||
```js | ||
const fastify = require('fastify')() | ||
fastify | ||
.register(require('middie')) | ||
.register(subsystem) | ||
async function subsystem (fastify, opts) { | ||
fastify.addHook('onRequest', async (req, reply) => { | ||
console.log('first') | ||
}) | ||
fastify.use((req, res, next) => { | ||
console.log('second') | ||
next() | ||
}) | ||
fastify.addHook('onRequest', async (req, reply) => { | ||
console.log('third') | ||
}) | ||
} | ||
``` | ||
If you want to change the Fastify hook that the middleware will be attached to, pass a `hook` option like so: | ||
*Note you can access `req.body` from the `preValidation` lifecycle step onwards. Take a look at the [Lifecycle](https://www.fastify.io/docs/latest/Reference/Lifecycle/) documentation page to see the order of the steps.* | ||
```js | ||
const fastify = require('fastify')() | ||
fastify | ||
.register(require('middie'), { hook: 'preHandler' }) | ||
.register(subsystem) | ||
async function subsystem (fastify, opts) { | ||
fastify.addHook('onRequest', async (req, reply) => { | ||
console.log('first') | ||
}) | ||
fastify.use((req, res, next) => { | ||
console.log('third') | ||
next() | ||
}) | ||
fastify.addHook('onRequest', async (req, reply) => { | ||
console.log('second') | ||
}) | ||
fastify.addHook('preHandler', async (req, reply) => { | ||
console.log('fourth') | ||
}) | ||
} | ||
``` | ||
### Restrict middleware execution to a certain path(s) | ||
If you need to run a middleware only under certain path(s), just pass the path as first parameter to use and you are done! | ||
```js | ||
const fastify = require('fastify')() | ||
const path = require('path') | ||
const serveStatic = require('serve-static') | ||
fastify | ||
.register(require('middie')) | ||
.register(subsystem) | ||
async function subsystem (fastify, opts) { | ||
// Single path | ||
fastify.use('/css', serveStatic(path.join(__dirname, '/assets'))) | ||
// Wildcard path | ||
fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets'))) | ||
// Multiple paths | ||
fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets'))) | ||
} | ||
``` | ||
# Middie Engine | ||
You can also use the engine itself without the Fastify plugin system. | ||
## Usage | ||
```js | ||
const Middie = require('middie/engine') | ||
const http = require('http') | ||
const helmet = require('helmet') | ||
const cors = require('cors') | ||
const middie = Middie(_runMiddlewares) | ||
middie.use(helmet()) | ||
middie.use(cors()) | ||
http | ||
.createServer(function handler (req, res) { | ||
middie.run(req, res) | ||
}) | ||
.listen(3000) | ||
function _runMiddlewares (err, req, res) { | ||
if (err) { | ||
console.log(err) | ||
res.end(err) | ||
return | ||
} | ||
// => routing function | ||
} | ||
``` | ||
<a name="keep-context"></a> | ||
#### Keep the context | ||
If you need it you can also keep the context of the calling function by calling `run` with `run(req, res, this)`, in this way you can avoid closures allocation. | ||
```js | ||
http | ||
.createServer(function handler (req, res) { | ||
middie.run(req, res, { context: 'object' }) | ||
}) | ||
.listen(3000) | ||
function _runMiddlewares (err, req, res, ctx) { | ||
if (err) { | ||
console.log(err) | ||
res.end(err) | ||
return | ||
} | ||
console.log(ctx) | ||
} | ||
``` | ||
<a name="restrict-usage"></a> | ||
#### Restrict middleware execution to a certain path(s) | ||
If you need to run a middleware only under certains path(s), just pass the path as first parameter to `use` and you are done! | ||
*Note that this does support routes with parameters, e.g. `/user/:id/comments`, but all the matched parameters will be discarded* | ||
```js | ||
// Single path | ||
middie.use('/public', staticFiles('/assets')) | ||
// Multiple middleware | ||
middie.use('/public', [cors(), staticFiles('/assets')]) | ||
// Multiple paths | ||
middie.use(['/public', '/dist'], staticFiles('/assets')) | ||
// Multiple paths and multiple middleware | ||
middie.use(['/public', '/dist'], [cors(), staticFiles('/assets')]) | ||
``` | ||
To guarantee compatibility with Express, adding a prefix uses [`path-to-regexp`](https://www.npmjs.com/package/path-to-regexp) to compute | ||
a `RegExp`, which is then used to math every request: it is significantly slower. | ||
## TypeScript support | ||
To use this module with TypeScript, make sure to install `@types/connect`. | ||
## Middleware alternatives | ||
Fastify offers some alternatives to the most commonly used Express middleware: | ||
| Express Middleware | Fastify Plugin | | ||
| ------------- |---------------| | ||
| [`helmet`](https://github.com/helmetjs/helmet) | [`fastify-helmet`](https://github.com/fastify/fastify-helmet) | | ||
| [`cors`](https://github.com/expressjs/cors) | [`fastify-cors`](https://github.com/fastify/fastify-cors) | | ||
| [`serve-static`](https://github.com/expressjs/serve-static) | [`fastify-static`](https://github.com/fastify/fastify-static) | | ||
## Acknowledgements | ||
This project is kindly sponsored by: | ||
- [nearForm](https://nearform.com) | ||
Past sponsors: | ||
- [LetzDoIt](https://www.letzdoitapp.com/) | ||
## License | ||
Licensed under [MIT](./LICENSE). | ||
`middie@7.1.0` has been deprecated. Please use | ||
`@fastify/middie@8.0.0` instead. |
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
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
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
2
0
705
3
5
2
5
3
+ Addedprocess-warning@^1.0.0
+ Addedmiddie@7.0.0(transitive)
+ Addedprocess-warning@1.0.0(transitive)
- Removedfastify-plugin@^3.0.0
- Removedpath-to-regexp@^6.1.0
- Removedreusify@^1.0.4