# node-request-interceptor

> Low-level HTTP/HTTPS/XHR request interception library for NodeJS

Latest version **0.6.3** (published 2021-01-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install node-request-interceptor
pnpm add node-request-interceptor
yarn add node-request-interceptor
bun add node-request-interceptor
```

## Health

**Score 40/100 (D)** — status: abandoned.

Positive: has types; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 0.6.3 |
| Published | 2021-01-03 |
| First published | 2020-04-27 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 4 |
| Unpacked size | 134.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 684 |
| Author | Artem Zakharchenko |
| Maintainers | kettanaito |
| Keywords | request, intercept, http, https, xmlhttprequest, xhr, fetch, low-level, mock |

## Links

- npm: https://www.npmjs.com/package/node-request-interceptor
- Repository: https://github.com/mswjs/node-request-interceptor
- npm.io page: https://npm.io/package/node-request-interceptor

## Dependencies (4)

- [debug](https://npm.io/package/debug.md) ^4.3.0
- [headers-utils](https://npm.io/package/headers-utils.md) ^1.2.0
- [@open-draft/until](https://npm.io/package/@open-draft/until.md) ^1.0.3
- [strict-event-emitter](https://npm.io/package/strict-event-emitter.md) ^0.1.0

## Alternatives

- [launchdarkly-js-client-sdk](https://npm.io/package/launchdarkly-js-client-sdk.md) — 2.5M weekly downloads
- [@elastic/elasticsearch](https://npm.io/package/@elastic/elasticsearch.md) — 2.1M weekly downloads
- [@c8y/client](https://npm.io/package/@c8y/client.md) — 15.3K weekly downloads
- [@signaldb/maverickjs](https://npm.io/package/@signaldb/maverickjs.md) — 1.7K weekly downloads
- [@bbc/http-transport-cache](https://npm.io/package/@bbc/http-transport-cache.md) — 1.2K weekly downloads

## Recent versions

- 0.6.3 (latest) — 2021-01-03
- 0.6.2 — 2020-12-20
- 0.6.1 — 2020-12-18
- 0.6.0 — 2020-12-18
- 0.5.9 — 2020-12-08
- 0.5.8 — 2020-12-03
- 0.5.7 — 2020-12-03
- 0.5.6 — 2020-11-29
- 0.5.5 — 2020-11-26
- 0.5.4 — 2020-11-20
- 0.5.3 — 2020-10-26
- 0.5.2 — 2020-10-26
- 0.5.1 — 2020-09-06
- 0.5.0 — 2020-08-25
- 0.4.0 — 2020-08-20
- … 24 more at https://npm.io/package/node-request-interceptor/versions

## README

[![Latest version](https://img.shields.io/npm/v/node-request-interceptor.svg)](https://www.npmjs.com/package/node-request-interceptor)
[![Build status](https://img.shields.io/circleci/project/github/mswjs/node-request-interceptor/master.svg)](https://app.circleci.com/pipelines/github/mswjs/node-request-interceptor)

# `node-request-interceptor`

Low-level HTTP/HTTPS/XHR request interception library for NodeJS.

**Intercepts any requests issued by:**

- `http.get`/`http.request`
- `https.get`/`https.request`
- `fetch`
- `XMLHttpRequest`
- Any third-party libraries that utilize the modules above (i.e. `request`, `node-fetch`, etc.)

## Motivation

While there are a lot of network communication mocking libraries, they tend to use request interception as an implementation detail, exposing you a high-level API that includes request matching, timeouts, retries, and so forth.

This library is a strip-to-bone implementation that provides as little abstraction as possible to execute arbitrary logic upon any request in NodeJS. It's primarily designed as an underlying component for a high-level API mocking solutions.

### How is this library different?

As interception is often combined with request route matching, some libraries can determine whether a request should be mocked _before_ it actually happens. This approach is not suitable for this library, as it rather _intercepts all requests_ and then let's you decide which ones should be mocked. This affects the level at which interception happens, and also the way mocked/original response is constructed, in comparison to other solutions.

### Why XMLHttpRequest?

Although NodeJS has no `XMLHttpRequest` implementation, this library covers it for the sake of processes that still run in NodeJS, but emulate a browser-like environment (i.e. `jsdom` when running tests in Jest).

## What this library does

This library monkey-patches the following native modules:

- `http.get`/`http.request`
- `https.get`/`https.request`
- `XMLHttpRequest`

Once patched, it provides an interface to execute an arbitrary logic upon any outgoing request using a request middleware function.

- Bypasses all requests by default, so your network channel is not affected.
- Handles an abstract response object returned from the request middleware as an actual response for the occurred request (taking into account the difference in constructing a response for different clients).

## What this library doesn't do

- Does **not** provide any request matching logic.
- Does **not** decide how to handle requests.
- Does **not** run in a browser (although supports `jsdom`).

## Getting started

```bash
npm install node-request-interceptor
```

## API

### `RequestInterceptor(interceptors: Interceptor[])`

```js
import { RequestInterceptor } from 'node-request-interceptor'
import withDefaultInterceptors from 'node-request-interceptor/presets/default'

const interceptor = new RequestInterceptor(withDefaultInterceptors)
```

> Using the `/presets/default` interceptors preset is the recommended way to ensure all requests get intercepted, regardless of their origin.

### Interceptors

This library utilizes a concept of an _interceptor_–a module that performs necessary patching, handles a mocked response, and restores patched instances.

**The list of interceptors:**

- `/interceptors/ClientRequest`
- `/interceptors/XMLHttpRequest`

To use one, or multiple interceptors, import and provide them to the `RequestInterceptor` constructor.

```js
import { RequestInterceptors } from 'node-request-interceptor'
import { interceptXMLHttpRequest } from 'node-request-interceptor/interceptors/XMLHttpRequest'

// This `interceptor` instance would handle only XMLHttpRequest,
// ignoring requests issued via `http`/`https` modules.
const interceptor = new RequestInterceptors([interceptXMLHttpRequest])
```

> Interceptors are crucial in leveraging environment-specific module overrides. Certain environments (i.e. React Native) do not have access to native NodeJS modules (like `http`). Importing such modules raises an exception, and must be avoided.

### Methods

#### `.use(middleware: (req: InterceptedRequest, ref: IncomingMessage | XMLHttpRequest) => MockedResponse): void`

Applies a given middleware function to an intercepted request. May return a [`MockedResponse`](#MockedResponse) object that is going to be used to respond to an intercepted request.

##### Requests monitoring

```js
interceptor.use((req) => {
  // Will print to stdout any outgoing requests
  // without affecting their responses
  console.log('%s %s', req.method, req.url.href)
})
```

##### Response mocking

When a request middleware returns a [`MockedResponse`](#MockedResponse) object, it will be returned as the response to the intercepted request. This library automatically creates a proper response instance according to the request issuing module (`http`/`XMLHttpRequest`).

```js
interceptor.use((req) => {
  if (['https://google.com'].includes(req.url.origin)) {
    // Will return a mocked response for any request
    // that is issued from the "https://google.com" origin.
    return {
      status: 301,
      headers: {
        'x-powered-by': 'node-request-interceptor',
      },
      body: JSON.stringify({
        message: 'Hey, I am a mocked response',
      }),
    }
  }
})
```

#### `.restore(): void`

Restores all patched modules and stops the interception of any future requests.

```js
interceptor.restore()
```

---

### `InterceptedRequest`

```ts
interface InterceptedRequest {
  url: URL
  method: string
  headers?: http.OutgoingHttpHeaders
  body?: string
}
```

---

### `MockedResponse`

Whenever a `MockedResponse` object is returned from the request middleware function, it's being used to constructs a relevant response for the intercepted request.

```ts
interface MockedResponse {
  status?: number
  statusText?: string
  headers?: Record<string, string | string[]>
  body?: string
}
```

## Special mention

The following libraries were used as an inspiration to write this low-level API:

- [`node`](https://github.com/nodejs/node)
- [`nock`](https://github.com/nock/nock)
- [`mock-xmlhttprequest`](https://github.com/berniegp/mock-xmlhttprequest)

---
_Source: https://npm.io/package/node-request-interceptor · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
