UNPKG

express-response-middleware

Version:
182 lines (121 loc) 5.02 kB
# Express Response Middleware > [!NOTE] > Come from express-mung? Checkout the [Migration Guide](docs/MIGRATE_FROM_MUNG.md) <div align="center"> Middleware for express responses. Fork of [express-mung](https://www.npmjs.com/package/express-mung) This package allows synchronous and asynchronous transformation of an express response. This is a similar concept to the express middleware for a request but for a response. Note that the middleware is executed in LIFO order. It is implemented by monkey patching (hooking) the `res.end`, `res.json`, or `res.write` methods. ![NPM](https://img.shields.io/npm/v/express-response-middleware) ![GitHub CI](https://github.com/marklai1998/express-response-middleware/actions/workflows/runTest.yml/badge.svg) [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org) [![npm type definitions](https://img.shields.io/npm/types/typescript.svg)](https://www.typescriptlang.org/) [Installation](#-installation) | [Quick Start](#-quick-start) | [API](#-api) | [Contributing](#-contributing) </div> ## 📦 Installation ### NPM ```bash npm i express-response-middleware ``` ### Yarn ``` yarn add express-response-middleware ``` ### PNPM ``` pnpm i express-response-middleware ``` ## 🚀 Quick Start Sample middleware (redact.js) to remove classified information. ```javascript import { jsonMiddleware } from 'express-response-middleware' /* Remove any classified information from the response. */ export const hideSecretMiddleware = jsonMiddleware((body, req, res) => { if (body.secret) body.secret = '****' // ... return body }) ``` then add to your `app.js` file (before the route handling middleware) ```javascript app.use(hideSecretMiddleware) ``` ## 💻 API - [Json Middleware](#jsonmiddleware) - [Jsonp Middleware](#jsonpmiddleware) - [Send Middleware](#sendmiddleware) - [End Middleware](#endMiddleware) - [Write Middleware](#endMiddleware) - Legacy docs - [V1](docs/V1_README.md) ### `jsonMiddleware` Intercept `res.json`, allow transform the JSON body of the response. ```ts import { jsonMiddleware } from 'express-response-middleware' const myMiddleware = jsonMiddleware((json, req, res) => { // your code here return json }) ``` ### `jsonpMiddleware` Intercept `res.jsonp`, allow transform the JSON body of the response. ```ts import { jsonpMiddleware } from 'express-response-middleware' const myMiddleware = jsonpMiddleware((json, req, res) => { // your code here return json }) ``` ### `sendMiddleware` Intercept `res.send`, allow transform the body of the response. ```ts import { sendMiddleware } from 'express-response-middleware' const myMiddleware = sendMiddleware((payload, req, res) => { // your code here return payload }) ``` ### `endMiddleware` Intercept `end.json`, allow transform the HTTP headers of the response. ```ts import { endMiddleware } from 'express-response-middleware' const myMiddleware = endMiddleware((req, res) => { // your code here }) ``` > [!CAUTION] > Sending a response while in `endMiddleware*` is **undefined behaviour** and will most likely result in an error ### `writeMiddleware` Intercept `end.write`, allow transform buffer. ```ts import { writeMiddleware } from 'express-response-middleware' const myMiddleware = writeMiddleware((chunk, encoding, req, res) => { // your code here return chunk }) ``` > [!CAUTION] > Promise callback support is limited, it doesn't resolve multiple write call yet [Code](src/writeMiddleware.ts) - When `writeMiddleware` detects that a response has completed (i.e. if `res.end` has been called), it will abort. - Calling `res.json` or `res.send` from `writeMiddleware` can lead to unexpected behavior since they end the response internally. - The returned value of `res.write` will be inaccurate when using `writeMiddleware`, beware if you rely on it - `res.end` after `res.write` would not trigger endMiddleware, as header already sent ## Exception handling `responseMiddleware` catches any exception (synchronous, asynchronous or Promise reject) and sends an HTTP 500 response with the exception message. You should handle your own error if you want different behavior ## 🤝 Contributing ### TODO Current state project is up to modern standard and support all of the `express-mung` use case, here is the list that I think can improve on. - [ ] Support multiple write call with `writeMiddleware` + async handler ### Development #### Local Development ```bash pnpm i pnpm test ``` #### Build ```bash pnpm build ``` ### Release This repo uses [Release Please](https://github.com/google-github-actions/release-please-action) to release. #### To release a new version 1. Merge your changes into the `main` branch. 2. An automated GitHub Action will run, triggering the creation of a Release PR. 3. Merge the release PR. 4. Wait for the second GitHub Action to run automatically. 5. Congratulations, you're all set!