Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

express-interceptor

Package Overview
Dependencies
Maintainers
2
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-interceptor - npm Package Compare versions

Comparing version 0.1.0 to 1.0.0

.travis.yml

29

index.js

@@ -0,1 +1,13 @@

function validateParams(methods){
var ACCEPT = ['isInterceptable', 'intercept', 'afterSend'];
for(var k in methods){
if(ACCEPT.indexOf(k) < 0){
throw(new Error(k+' isn\'t a valid param ('+ACCEPT.join(', ')+')'));
}
}
if(!('isInterceptable' in methods)){
throw('isInterceptable is a required param (function)');
}
}
module.exports = function(fn) {

@@ -6,2 +18,3 @@ var debug = require('debug')('express-interceptor');

var methods = fn(req,res);
validateParams(methods);

@@ -17,3 +30,3 @@ var originalEnd = res.end;

isFirstWrite = false;
isIntercepting = methods.initerceptPredicate();
isIntercepting = methods.isInterceptable();
}

@@ -55,11 +68,9 @@ debug('isIntercepting? %s', isIntercepting);

var oldBody = chunks.join('');
if (typeof methods.send === 'function'){
debug(' methods.send is defined');
if (methods.intercept){
if(typeof methods.intercept !== 'function'){
throw new Error('`send` must be a function with the body to be sent as the only param');
}
res.removeHeader('Content-Length');
// allow the user to re-write destiny
methods.send(oldBody, function(err,newBody) {
// debug(' newBody is %s',newBody);
if(err){
return cb && cb(err);
}
// allow the user to re-write response
methods.intercept(oldBody, function(newBody) {
args[0] = newBody;

@@ -66,0 +77,0 @@ originalEnd.apply(res,args);

{
"name": "express-interceptor",
"version": "0.1.0",
"version": "1.0.0",
"description": "A tiny interceptor for Express responses",

@@ -10,6 +10,15 @@ "main": "index.js",

"scripts": {
"test": "./node_modules/mocha/bin/mocha -R spec --recursive examples"
"test": "./node_modules/mocha/bin/mocha -R spec --recursive tests"
},
"author": "AxiomZen (https://axiomzen.co)",
"keywords": ["express", "expressjs", "middleware", "modify", "response", "hack", "interceptor", "hijack"],
"keywords": [
"express",
"expressjs",
"middleware",
"modify",
"response",
"hack",
"interceptor",
"hijack"
],
"contributors": [

@@ -27,2 +36,9 @@ {

],
"repository": {
"type": "git",
"url": "https://github.com/axiomzen/express-interceptor"
},
"bugs": {
"url": "https://github.com/axiomzen/express-interceptor/issues"
},
"license": "MIT",

@@ -35,3 +51,4 @@ "devDependencies": {

"supertest": "~0.15.0",
"mocha": "~2.1.0"
"mocha": "~2.1.0",
"cheerio": "~0.18.0"
},

@@ -38,0 +55,0 @@ "dependencies": {

@@ -1,68 +0,120 @@

# raison d'etre
# express-interceptor
Born out of the need for a reliable, customized and maintenable middleware we need for Sesame CMS.
_A tiny Express response interceptor_
[![NPM](https://nodei.co/npm/express-interceptor.png)](https://nodei.co/npm/express-interceptor/)
[![Build Status](https://travis-ci.org/axiomzen/express-interceptor.svg)](https://travis-ci.org/axiomzen/express-interceptor) [![Dependencies](https://david-dm.org/axiomzen/express-interceptor.png)](https://david-dm.org/axiomzen/express-interceptor.png)
<a href="https://zenhub.io"><img src="https://raw.githubusercontent.com/ZenHubIO/support/master/zenhub-badge.png" height="18px"></a>
Express-interceptor allows you to define a previous step before sending a response. This allows you to do anything you want with the response, such as processing, transforming, replacing, or logging it. Express-interceptor allows you to avoid calling `next()` over and over. Further more, you can avoid managing nested scopes. Using a declarative API, it’s simple to use and maintain.
Some use cases include:
- conditionally transform any kind of response
- have access to responses after they are sent
- Transpile custom elements into standard HTML elements.
- Transform JSX or compile less files on the fly.
- Store statistics about responses.
- Set response headers based on tags in the response body.
- Dynamically inject live-reload scripts to HTML.
## API
## Usage
npm i --save express-interceptor
Install the package
npm i --save express-interceptor
Define your interceptor
```javascript
var express = require('express');
var cheerio = require('cheerio');
var interceptor = require('express-interceptor');
app.use(interceptor(function(req,res){
var app = express();
var finalParagraphInterceptor = interceptor(function(req, res){
return {
// define your custom condition to intercept this response
// returning `true` cause to buffer this request, and activate methods below
// otherwise we ignore it completely
initerceptPredicate: function(){
// Only HTML responses will be intercepted
isInterceptable: function(){
return /text\/html/.test(res.get('Content-Type'));
},
// can transform the body, it's a properly encoded String,
// done(err, string) param[1] will become the new response
// may omit secrets, erase words, append stuff, etc.
send: function(body, done) {
// Appends a paragraph at the end of the response body
intercept: function(body, send) {
var $document = cheerio.load(body);
$document('body').append('<p>From interceptor!</p>');
},
// useful for caching, keeping stats, etc.
afterSend: function(oldBody, newBody) {
send($document.html());
}
};
}));
})
// Add the interceptor middleware
app.use(finalParagraphInterceptor);
app.use(express.static(__dirname + '/public/'));
app.listen(3000);
```
You can find many other examples at [/examples folder](https://github.com/axiomzen/express-interceptor/tree/master/examples) - which also happen to be the tests.
You're defining an interceptor that will be executed whenever the response contains html as Content-Type. If this is true, it will append a child at the end of the body. In other words, it will transform the response:
## technicalities
```html
<html>
<head></head>
<body>
<p>"Hello world"</p>
</body>
</html>
```
Express extends Node.js functionalities, that by default:
Into:
- allow setting and modifying of headers until the moment there is a write to the socket, this will submit headers.
- when `initerceptPredicate` returns true, we will buffer the contents, preventing `.write` to be called
- the whole buffer is presented to `send` function that can modify response headers right there, as well as return a new `body` that will be sent right away.
- `afterSend` is optional and happens on next tick.
- this package tries to be minimally obtrusive on the way Node or Express works, original `write` and `end` methods hijacked but then at the end.
```html
<html>
<head></head>
<body>
<p>"Hello world"</p>
<p>From interceptor!</p>
</body>
</html>
```
See [more examples](https://github.com/axiomzen/express-interceptor/tree/master/examples).
## similar to
## API
- [tamper](https://www.npmjs.com/package/tamper)
Similar functionality, with different APIs.
* `isInterceptable()` (required): is a predicate function where you define a condition whether or not to intercept a response. Returning `true` buffers the request, and proceeds calling `intercept()` as well as `afterSend()`. Typically, you want to check for this condition in the `res` object in the definition of the middleware.
* `intercept(body, send)` (required): Parse the body as an encoded string. After processing the body, call `send(newBody)` with the content to be sent back to the client.
* `afterSend(oldBody, newBody)`: This method will be called after sending the response to the client – after the `done()` callback in the `send()` method is executed. This method would typically be used to cache something, log stats, fire a job, among other things.
## Similar to
- [express-hijackresponse](https://github.com/papandreou/express-hijackresponse)
Have issues with cache, code is hard to maintain.
Different API, using callbacks with no top down structure, more obtrusive to HTTP internals.
## words of advice
- [tamper](https://www.npmjs.com/package/tamper)
Similar functionality but different internals and API.
This module is new, tests are appreciated. There might be edge cases that need fix.
## Words of advice
Not recommended to intercept and transform big responses.
If your `intercept` method make calls to a database, or needs to make expensive transformations to the original response, you should take in account the time that will add to the response. You should define your `isInterceptable` method carefully, checking the type of the response, or even the route that was fired by the request, also you may consider implementing a cache strategy to get faster responses.
Activate debug with `DEBUG=express-interceptor npm test`
If you face any issue, don't hesitate to submit it [here](https://github.com/axiomzen/express-interceptor/issues).
## Author
* [AxiomZen](https://www.axiomzen.co/).
## Collaborators
* [Fabiano Soriani](https://github.com/flockonus).
* [Raul Pino](https://github.com/p1nox).
## License
[MIT](LICENSE)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc