{"_id":"@avivasyuta/request-interceptor","_rev":"4-74fb2c34dc47f5d801e34b5c52b7278d","name":"@avivasyuta/request-interceptor","dist-tags":{"latest":"0.1.3","dev":"0.1.1-dev2"},"versions":{"0.1.0":{"name":"@avivasyuta/request-interceptor","description":"Low-level HTTP/HTTPS/XHR/fetch request interception library. Fork of @mswjs/interceptors.","version":"0.1.0","main":"./lib/node/index.js","module":"./lib/node/index.mjs","types":"./lib/node/index.d.ts","publishConfig":{"access":"public"},"exports":{".":{"types":"./lib/node/index.d.ts","require":"./lib/node/index.js","import":"./lib/node/index.mjs","default":"./lib/node/index.js"},"./ClientRequest":{"browser":null,"types":"./lib/node/interceptors/ClientRequest/index.d.ts","require":"./lib/node/interceptors/ClientRequest/index.js","import":"./lib/node/interceptors/ClientRequest/index.mjs","default":"./lib/node/interceptors/ClientRequest/index.js"},"./XMLHttpRequest":{"browser":{"types":"./lib/browser/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/browser/interceptors/XMLHttpRequest/index.js","import":"./lib/browser/interceptors/XMLHttpRequest/index.mjs","default":"./lib/browser/interceptors/XMLHttpRequest/index.js"},"types":"./lib/node/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/node/interceptors/XMLHttpRequest/index.js","import":"./lib/node/interceptors/XMLHttpRequest/index.mjs","default":"./lib/node/interceptors/XMLHttpRequest/index.js"},"./fetch":{"browser":{"types":"./lib/browser/interceptors/fetch/index.d.ts","require":"./lib/browser/interceptors/fetch/index.js","import":"./lib/browser/interceptors/fetch/index.mjs","default":"./lib/browser/interceptors/fetch/index.js"},"types":"./lib/node/interceptors/fetch/index.d.ts","require":"./lib/node/interceptors/fetch/index.js","import":"./lib/node/interceptors/fetch/index.mjs","default":"./lib/node/interceptors/fetch/index.js"},"./RemoteHttpInterceptor":{"browser":null,"types":"./lib/node/interceptors/RemoteHttpInterceptor.d.ts","require":"./lib/node/interceptors/RemoteHttpInterceptor.js","import":"./lib/node/interceptors/RemoteHttpInterceptor.mjs","default":"./lib/node/interceptors/RemoteHttpInterceptor.js"},"./presets/node":{"browser":null,"types":"./lib/node/presets/node.d.ts","require":"./lib/node/presets/node.js","import":"./lib/node/presets/node.mjs","default":"./lib/node/presets/node.js"},"./presets/browser":{"browser":{"types":"./lib/browser/presets/browser.d.ts","require":"./lib/browser/presets/browser.js","import":"./lib/browser/presets/browser.mjs","default":"./lib/browser/presets/browser.js"}}},"author":{"name":"Artem Zakharchenko"},"license":"MIT","engines":{"node":">=18"},"scripts":{"start":"tsc --build -w","test":"yarn test:unit && yarn test:integration","test:unit":"vitest run","test:integration":"yarn test:integration:node && yarn test:integration:browser","test:integration:node":"vitest run -c test/vitest.config.js","test:integration:browser":"playwright test -c test/playwright.config.ts","clean":"rimraf lib","build":"yarn clean && cross-env NODE_ENV=production tsup --splitting","prepare":"yarn simple-git-hooks init","release":"release publish"},"repository":{"type":"git","url":"git+https://github.com/mswjs/interceptors.git"},"devDependencies":{"@commitlint/cli":"^16.0.2","@commitlint/config-conventional":"^16.0.0","@open-draft/test-server":"^0.5.1","@ossjs/release":"^0.4.0","@playwright/test":"^1.31.1","@types/cors":"^2.8.12","@types/express":"^4.17.13","@types/express-rate-limit":"^6.0.0","@types/follow-redirects":"^1.14.1","@types/jest":"^27.0.3","@types/node":"^16.11.26","@types/node-fetch":"2.5.12","@types/supertest":"^2.0.11","axios":"^0.24.0","body-parser":"^1.19.0","commitizen":"^4.2.4","cors":"^2.8.5","cross-env":"^7.0.3","cz-conventional-changelog":"3.3.0","express":"^4.17.3","express-rate-limit":"^6.3.0","follow-redirects":"^1.15.1","got":"^11.8.3","jest":"^27.4.3","node-fetch":"2.6.7","playwright":"^1.31.1","rimraf":"^3.0.2","simple-git-hooks":"^2.7.0","superagent":"^6.1.0","supertest":"^6.1.6","ts-jest":"^27.1.1","tsup":"^6.5.0","typescript":"^4.9.4","vitest":"^0.28.5","wait-for-expect":"^3.0.2","web-encoding":"^1.1.5","webpack-http-server":"^0.5.0"},"dependencies":{"@open-draft/deferred-promise":"^2.1.0","@open-draft/logger":"^0.3.0","@open-draft/until":"^2.0.0","headers-polyfill":"^3.1.0","is-node-process":"^1.2.0","outvariant":"^1.2.1","strict-event-emitter":"^0.5.0"},"resolutions":{"memfs":"^3.4.13"},"keywords":["request","intercept","http","https","xmlhttprequest","xhr","fetch","low-level","mock","spy","testing"],"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"34076579810d267baa8981b08cded4d436844dcd","bugs":{"url":"https://github.com/mswjs/interceptors/issues"},"homepage":"https://github.com/mswjs/interceptors#readme","_id":"@avivasyuta/request-interceptor@0.1.0","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-DF5wDLna/9v+s0iIhekfcXYs9l7s6Rtwsj5SHnZVQJcaCAqILzoZDvMXFt9crkWs/4X3J3bct4m9pi+WkOQN6w==","shasum":"b43ddf6da598b1e69909c58c4f8b5ab8110f7ccd","tarball":"https://registry.npmjs.org/@avivasyuta/request-interceptor/-/request-interceptor-0.1.0.tgz","fileCount":129,"unpackedSize":556165,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDk8VkivnLgKTcK32BRqjhVWeW2j7QrrKjSr5+ngqtPbgIhALQHGCqg0if82OeKDmB0PcP4VuFMwhE5asuxr3t2s1as"}]},"_npmUser":{"name":"avivasyuta","email":"avivasyuta@gmail.com"},"directories":{},"maintainers":[{"name":"avivasyuta","email":"avivasyuta@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/request-interceptor_0.1.0_1691863983511_0.06852441114782581"},"_hasShrinkwrap":false},"0.1.1-dev":{"name":"@avivasyuta/request-interceptor","description":"Low-level HTTP/HTTPS/XHR/fetch request interception library. Fork of @mswjs/interceptors.","version":"0.1.1-dev","main":"./lib/node/index.js","module":"./lib/node/index.mjs","types":"./lib/node/index.d.ts","publishConfig":{"access":"public"},"exports":{".":{"types":"./lib/node/index.d.ts","require":"./lib/node/index.js","import":"./lib/node/index.mjs","default":"./lib/node/index.js"},"./ClientRequest":{"browser":null,"types":"./lib/node/interceptors/ClientRequest/index.d.ts","require":"./lib/node/interceptors/ClientRequest/index.js","import":"./lib/node/interceptors/ClientRequest/index.mjs","default":"./lib/node/interceptors/ClientRequest/index.js"},"./XMLHttpRequest":{"browser":{"types":"./lib/browser/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/browser/interceptors/XMLHttpRequest/index.js","import":"./lib/browser/interceptors/XMLHttpRequest/index.mjs","default":"./lib/browser/interceptors/XMLHttpRequest/index.js"},"types":"./lib/node/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/node/interceptors/XMLHttpRequest/index.js","import":"./lib/node/interceptors/XMLHttpRequest/index.mjs","default":"./lib/node/interceptors/XMLHttpRequest/index.js"},"./fetch":{"browser":{"types":"./lib/browser/interceptors/fetch/index.d.ts","require":"./lib/browser/interceptors/fetch/index.js","import":"./lib/browser/interceptors/fetch/index.mjs","default":"./lib/browser/interceptors/fetch/index.js"},"types":"./lib/node/interceptors/fetch/index.d.ts","require":"./lib/node/interceptors/fetch/index.js","import":"./lib/node/interceptors/fetch/index.mjs","default":"./lib/node/interceptors/fetch/index.js"},"./RemoteHttpInterceptor":{"browser":null,"types":"./lib/node/interceptors/RemoteHttpInterceptor.d.ts","require":"./lib/node/interceptors/RemoteHttpInterceptor.js","import":"./lib/node/interceptors/RemoteHttpInterceptor.mjs","default":"./lib/node/interceptors/RemoteHttpInterceptor.js"},"./presets/node":{"browser":null,"types":"./lib/node/presets/node.d.ts","require":"./lib/node/presets/node.js","import":"./lib/node/presets/node.mjs","default":"./lib/node/presets/node.js"},"./presets/browser":{"browser":{"types":"./lib/browser/presets/browser.d.ts","require":"./lib/browser/presets/browser.js","import":"./lib/browser/presets/browser.mjs","default":"./lib/browser/presets/browser.js"}}},"author":{"name":"Artem Zakharchenko"},"license":"MIT","engines":{"node":">=18"},"scripts":{"start":"tsc --build -w","test":"yarn test:unit && yarn test:integration","test:unit":"vitest run","test:integration":"yarn test:integration:node && yarn test:integration:browser","test:integration:node":"vitest run -c test/vitest.config.js","test:integration:browser":"playwright test -c test/playwright.config.ts","clean":"rimraf lib","build":"yarn clean && cross-env NODE_ENV=production tsup --splitting","prepare":"yarn simple-git-hooks init","release":"release publish"},"repository":{"type":"git","url":"git+https://github.com/mswjs/interceptors.git"},"devDependencies":{"@commitlint/cli":"^16.0.2","@commitlint/config-conventional":"^16.0.0","@open-draft/test-server":"^0.5.1","@ossjs/release":"^0.4.0","@playwright/test":"^1.31.1","@types/cors":"^2.8.12","@types/express":"^4.17.13","@types/express-rate-limit":"^6.0.0","@types/follow-redirects":"^1.14.1","@types/jest":"^27.0.3","@types/node":"^16.11.26","@types/node-fetch":"2.5.12","@types/supertest":"^2.0.11","axios":"^0.24.0","body-parser":"^1.19.0","commitizen":"^4.2.4","cors":"^2.8.5","cross-env":"^7.0.3","cz-conventional-changelog":"3.3.0","express":"^4.17.3","express-rate-limit":"^6.3.0","follow-redirects":"^1.15.1","got":"^11.8.3","jest":"^27.4.3","node-fetch":"2.6.7","playwright":"^1.31.1","rimraf":"^3.0.2","simple-git-hooks":"^2.7.0","superagent":"^6.1.0","supertest":"^6.1.6","ts-jest":"^27.1.1","tsup":"^6.5.0","typescript":"^4.9.4","vitest":"^0.28.5","wait-for-expect":"^3.0.2","web-encoding":"^1.1.5","webpack-http-server":"^0.5.0"},"dependencies":{"@open-draft/deferred-promise":"^2.1.0","@open-draft/logger":"^0.3.0","@open-draft/until":"^2.0.0","headers-polyfill":"^3.1.0","is-node-process":"^1.2.0","outvariant":"^1.2.1","strict-event-emitter":"^0.5.0"},"resolutions":{"memfs":"^3.4.13"},"keywords":["request","intercept","http","https","xmlhttprequest","xhr","fetch","low-level","mock","spy","testing"],"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"[![Latest version](https://img.shields.io/npm/v/@mswjs/interceptors.svg)](https://www.npmjs.com/package/@mswjs/interceptors)\n\n# `@mswjs/interceptors`\n\nLow-level HTTP/HTTPS/XHR/fetch request interception library.\n\n**Intercepts any requests issued by:**\n\n- `http.get`/`http.request`\n- `https.get`/`https.request`\n- `XMLHttpRequest`\n- `window.fetch`\n- Any third-party libraries that use the modules above (i.e. `axios`, `request`, `node-fetch`, `supertest`, etc.)\n\n## Motivation\n\nWhile there are a lot of network communication mocking libraries, they tend to use request interception as an implementation detail, giving you a high-level API that includes request matching, timeouts, retries, and so forth.\n\nThis library is a strip-to-bone implementation that provides as little abstraction as possible to execute arbitrary logic upon any request. It's primarily designed as an underlying component for high-level API mocking solutions such as [Mock Service Worker](https://github.com/mswjs/msw).\n\n### How is this library different?\n\nA traditional API mocking implementation in Node.js looks roughly like this:\n\n```js\nimport http from 'http'\n\nfunction applyMock() {\n  // Store the original request module.\n  const originalHttpRequest = http.request\n\n  // Rewrite the request module entirely.\n  http.request = function (...args) {\n    // Decide whether to handle this request before\n    // the actual request happens.\n    if (shouldMock(args)) {\n      // If so, never create a request, respond to it\n      // using the mocked response from this blackbox.\n      return coerceToResponse.bind(this, mock)\n    }\n\n    // Otherwise, construct the original request\n    // and perform it as-is (receives the original response).\n    return originalHttpRequest(...args)\n  }\n}\n```\n\nThis library deviates from such implementation and uses _class extensions_ instead of module rewrites. Such deviation is necessary because, unlike other solutions that include request matching and can determine whether to mock requests _before_ they actually happen, this library is not opinionated about the mocked/bypassed nature of the requests. Instead, it _intercepts all requests_ and delegates the decision of mocking to the end consumer.\n\n```js\nclass NodeClientRequest extends ClientRequest {\n  async end(...args) {\n    // Check if there's a mocked response for this request.\n    // You control this in the \"resolver\" function.\n    const mockedResponse = await resolver(request)\n\n    // If there is a mocked response, use it to respond to this\n    // request, finalizing it afterward as if it received that\n    // response from the actual server it connected to.\n    if (mockedResponse) {\n      this.respondWith(mockedResponse)\n      this.finish()\n      return\n    }\n\n    // Otherwise, perform the original \"ClientRequest.prototype.end\" call.\n    return super.end(...args)\n  }\n}\n```\n\nBy extending the native modules, this library actually constructs requests as soon as they are constructed by the consumer. This enables all the request input validation and transformations done natively by Node.js—something that traditional solutions simply cannot do (they replace `http.ClientRequest` entirely). The class extension allows to fully utilize Node.js internals instead of polyfilling them, which results in more resilient mocks.\n\n## What this library does\n\nThis library extends (or patches, where applicable) the following native modules:\n\n- `http.get`/`http.request`\n- `https.get`/`https.request`\n- `XMLHttpRequest`\n- `fetch`\n\nOnce extended, it intercepts and normalizes all requests to the Fetch API `Request` instances. This way, no matter the request source (`http.ClientRequest`, `XMLHttpRequest`, `window.Request`, etc), you always get a specification-compliant request instance to work with.\n\nYou can respond to the intercepted request by constructing a Fetch API Response instance. Instead of designing custom abstractions, this library respects the Fetch API specification and takes the responsibility to coerce a single response declaration to the appropriate response formats based on the request-issuing modules (like `http.OutgoingMessage` to respond to `http.ClientRequest`, or updating `XMLHttpRequest` response-related properties).\n\n## What this library doesn't do\n\n- Does **not** provide any request matching logic;\n- Does **not** decide how to handle requests.\n\n## Getting started\n\n```bash\nnpm install @mswjs/interceptors\n```\n\n## Interceptors\n\nTo use this library you need to choose one or multiple interceptors to apply. There are different interceptors exported by this library to spy on respective request-issuing modules:\n\n- `ClientRequestInterceptor` to spy on `http.ClientRequest` (`http.get`/`http.request`);\n- `XMLHttpRequestInterceptor` to spy on `XMLHttpRequest`;\n- `FetchInterceptor` to spy on `fetch`.\n\nUse an interceptor by constructing it and attaching request/response listeners:\n\n```js\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\n\nconst interceptor = new ClientRequestInterceptor()\n\n// Enable the interception of requests.\ninterceptor.apply()\n\n// Listen to any \"http.ClientRequest\" being dispatched,\n// and log its method and full URL.\ninterceptor.on('request', ({ request, requestId }) => {\n  console.log(request.method, request.url)\n})\n\n// Listen to any responses sent to \"http.ClientRequest\".\n// Note that this listener is read-only and cannot affect responses.\ninterceptor.on(\n  'response',\n  ({ response, isMockedResponse, request, requestId }) => {\n    console.log('response to %s %s was:', request.method, request.url, response)\n  }\n)\n```\n\nAll HTTP request interceptors implement the same events:\n\n- `request`, emitted whenever a request has been dispatched;\n- `response`, emitted whenever any request receives a response.\n\n### Using multiple interceptors\n\nYou can combine multiple interceptors to capture requests from different request-issuing modules at once.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: [\n    new ClientRequestInterceptor(),\n    new XMLHttpRequestInterceptor(),\n  ],\n})\n\ninterceptor.apply()\n\n// This \"request\" listener will be called on both\n// \"http.ClientRequest\" and \"XMLHttpRequest\" being dispatched.\ninterceptor.on('request', listener)\n```\n\n> Note that you can use [pre-defined presets](#presets) that cover all the request sources for a given environment type.\n\n## Presets\n\nWhen using [`BatchInterceptor`](#batchinterceptor), you can provide a pre-defined preset to its \"interceptors\" option to capture all request for that environment.\n\n### Node.js preset\n\nThis preset combines `ClientRequestInterceptor`, `XMLHttpRequestInterceptor` and is meant to be used in Node.js.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport nodeInterceptors from '@mswjs/interceptors/presets/node'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: nodeInterceptors,\n})\n\ninterceptor.apply()\n\ninterceptor.on('request', listener)\n```\n\n### Browser preset\n\nThis preset combines `XMLHttpRequestInterceptor` and `FetchInterceptor` and is meant to be used in a browser.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport browserInterceptors from '@mswjs/interceptors/presets/browser'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: browserInterceptors,\n})\n\ninterceptor.on('request', listener)\n```\n\n## Introspecting requests\n\nAll HTTP request interceptors emit a \"request\" event. In the listener to this event, they expose a `request` reference, which is a [Fetch API Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) instance.\n\n> There are many ways to describe a request in Node.js but this library coerces different request definitions to a single specification-compliant `Request` instance to make the handling consistent.\n\n```js\ninterceptor.on('reqest', ({ request, requestId }) => {\n  console.log(request.method, request.url)\n})\n```\n\nSince the exposed `request` instance implements the Fetch API specification, you can operate with it just as you do with the regular browser request. For example, this is how you would read the request body as JSON:\n\n```js\ninterceptor.on('request', async ({ request, requestId }) => {\n  const json = await request.clone().json()\n})\n```\n\n> **Do not forget to clone the request before reading its body!**\n\n## Modifying requests\n\nRequest representations are readonly. You can, however, mutate the intercepted request's headers in the \"request\" listener:\n\n```js\ninterceptor.on('request', ({ request }) => {\n  request.headers.set('X-My-Header', 'true')\n})\n```\n\n> This restriction is done so that the library wouldn't have to unnecessarily synchronize the actual request instance and its Fetch API request representation. As of now, this library is not meant to be used as a full-scale proxy.\n\n## Mocking responses\n\nAlthough this library can be used purely for request introspection purposes, you can also affect request resolution by responding to any intercepted request within the \"request\" event.\n\nUse the `request.respondWith()` method to respond to a request with a mocked response:\n\n```js\ninterceptor.on('request', ({ request, requestId }) => {\n  request.respondWith(\n    new Response(\n      JSON.stringify({\n        firstName: 'John',\n        lastName: 'Maverick',\n      }),\n      {\n        status: 201,\n        statusText: 'Created',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n      }\n    )\n  )\n})\n```\n\n> We use Fetch API `Response` class as the middle-ground for mocked response definition. This library then coerces the response instance to the appropriate response format (e.g. to `http.OutgoingMessage` in the case of `http.ClientRequest`).\n\n**The `Response` class is built-in in since Node.js 18. Use a Fetch API-compatible polyfill, like `node-fetch`, for older versions of Node.js.`**\n\nNote that a single request _can only be handled once_. You may want to introduce conditional logic, like routing, in your request listener but it's generally advised to use a higher-level library like [Mock Service Worker](https://github.com/mswjs/msw) that does request matching for you.\n\nRequests must be responded to within the same tick as the request listener. This means you cannot respond to a request using `setTimeout`, as this will delegate the callback to the next tick. If you wish to introduce asynchronous side-effects in the listener, consider making it an `async` function, awaiting any side-effects you need.\n\n```js\n// Respond to all requests with a 500 response\n// delayed by 500ms.\ninterceptor.on('request', async ({ request, requestId }) => {\n  await sleep(500)\n  request.respondWith(new Response(null, { status: 500 }))\n})\n```\n\n## Observing responses\n\nYou can use the \"response\" event to transparently observe any incoming responses in your Node.js process.\n\n```js\ninterceptor.on(\n  'response',\n  ({ response, isMockedResponse, request, requestId }) => {\n    // react to the incoming response...\n  }\n)\n```\n\n> Note that the `isMockedResponse` property will only be set to `true` if you resolved this request in the \"request\" event listener using the `request.respondWith()` method and providing a mocked `Response` instance.\n\n## API\n\n### `Interceptor`\n\nA generic class implemented by all interceptors. You do not interact with this class directly.\n\n```ts\nclass Interceptor {\n  // Applies the interceptor, enabling the interception of requests\n  // in the current process.\n  apply(): void\n\n  // Listens to the public interceptor events.\n  // For HTTP requests, these are \"request' and \"response\" events.\n  on(event, listener): void\n\n  // Cleans up any side-effects introduced by the interceptor\n  // and disables the interception of requests.\n  dispose(): void\n}\n```\n\n**For public consumption, use [interceptors](#interceptors) instead**.\n\n### `BatchInterceptor`\n\nApplies multiple request interceptors at the same time.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport nodeInterceptors from '@mswjs/interceptors/presets/node'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: nodeInterceptors,\n})\n\ninterceptor.apply()\n\ninterceptor.on('request', ({ request, requestId }) => {\n  // Inspect the intercepted \"request\".\n  // Optionally, return a mocked response.\n})\n```\n\n> Using the `/presets/node` interceptors preset is the recommended way to ensure all requests get intercepted, regardless of their origin.\n\n### `RemoteHttpInterceptor`\n\nEnables request interception in the current process while delegating the response resolution logic to the _parent process_. **Requires the current process to be a child process**. Requires the parent process to establish a resolver by calling the `createRemoteResolver` function.\n\n```js\n// child.js\nimport { RemoteHttpInterceptor } from '@mswjs/interceptors/RemoteHttpInterceptor'\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\n\nconst interceptor = new RemoteHttpInterceptor({\n  // Alternatively, you can use presets.\n  interceptors: [new ClientRequestInterceptor()],\n})\n\ninterceptor.apply()\n\nprocess.on('disconnect', () => {\n  interceptor.dispose()\n})\n```\n\nYou can still listen to and handle any requests in the child process via the `request` event listener. Keep in mind that a single request can only be responded to once.\n\n### `RemoteHttpResolver`\n\nResolves an intercepted request in the given child `process`. Requires for that child process to enable request interception by calling the `createRemoteInterceptor` function.\n\n```js\n// parent.js\nimport { spawn } from 'child_process'\nimport { RemoteHttpResolver } from '@mswjs/interceptors/RemoteHttpInterceptor'\n\nconst appProcess = spawn('node', ['app.js'], {\n  stdio: ['inherit', 'inherit', 'inherit', 'ipc'],\n})\n\nconst resolver = new RemoteHttpResolver({\n  process: appProcess,\n})\n\nresolver.on('request', ({ request, requestId }) => {\n  // Optionally, return a mocked response\n  // for a request that occurred in the \"appProcess\".\n})\n```\n\n## Special mention\n\nThe following libraries were used as an inspiration to write this low-level API:\n\n- [`node`](https://github.com/nodejs/node)\n- [`nock`](https://github.com/nock/nock)\n- [`mock-xmlhttprequest`](https://github.com/berniegp/mock-xmlhttprequest)\n","readmeFilename":"README.md","gitHead":"34076579810d267baa8981b08cded4d436844dcd","bugs":{"url":"https://github.com/mswjs/interceptors/issues"},"homepage":"https://github.com/mswjs/interceptors#readme","_id":"@avivasyuta/request-interceptor@0.1.1-dev","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-7KQTQopTjY1K01Gulx4qvwJFKvx2mnCWHmv2ahZiusIMVKeJkLy4cfbpxnqWoXtS1M8Q7qBynCLf1MaocA3MZg==","shasum":"7d64d14c33b9ab24d509f2de05dd8da5148f9e06","tarball":"https://registry.npmjs.org/@avivasyuta/request-interceptor/-/request-interceptor-0.1.1-dev.tgz","fileCount":129,"unpackedSize":556724,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEpSl4hrHvigxpdx28owbsxyyzGRnZTa5nXBwDDZQb5+AiEA9WXJMgLJP8whI2CnoMhAIT5lZPQUQVDvdtvcQ20+hmE="}]},"_npmUser":{"name":"avivasyuta","email":"avivasyuta@gmail.com"},"directories":{},"maintainers":[{"name":"avivasyuta","email":"avivasyuta@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/request-interceptor_0.1.1-dev_1692209105834_0.559542027239941"},"_hasShrinkwrap":false},"0.1.1-dev2":{"name":"@avivasyuta/request-interceptor","description":"Low-level HTTP/HTTPS/XHR/fetch request interception library. Fork of @mswjs/interceptors.","version":"0.1.1-dev2","main":"./lib/node/index.js","module":"./lib/node/index.mjs","types":"./lib/node/index.d.ts","publishConfig":{"access":"public"},"exports":{".":{"types":"./lib/node/index.d.ts","require":"./lib/node/index.js","import":"./lib/node/index.mjs","default":"./lib/node/index.js"},"./ClientRequest":{"browser":null,"types":"./lib/node/interceptors/ClientRequest/index.d.ts","require":"./lib/node/interceptors/ClientRequest/index.js","import":"./lib/node/interceptors/ClientRequest/index.mjs","default":"./lib/node/interceptors/ClientRequest/index.js"},"./XMLHttpRequest":{"browser":{"types":"./lib/browser/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/browser/interceptors/XMLHttpRequest/index.js","import":"./lib/browser/interceptors/XMLHttpRequest/index.mjs","default":"./lib/browser/interceptors/XMLHttpRequest/index.js"},"types":"./lib/node/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/node/interceptors/XMLHttpRequest/index.js","import":"./lib/node/interceptors/XMLHttpRequest/index.mjs","default":"./lib/node/interceptors/XMLHttpRequest/index.js"},"./fetch":{"browser":{"types":"./lib/browser/interceptors/fetch/index.d.ts","require":"./lib/browser/interceptors/fetch/index.js","import":"./lib/browser/interceptors/fetch/index.mjs","default":"./lib/browser/interceptors/fetch/index.js"},"types":"./lib/node/interceptors/fetch/index.d.ts","require":"./lib/node/interceptors/fetch/index.js","import":"./lib/node/interceptors/fetch/index.mjs","default":"./lib/node/interceptors/fetch/index.js"},"./RemoteHttpInterceptor":{"browser":null,"types":"./lib/node/interceptors/RemoteHttpInterceptor.d.ts","require":"./lib/node/interceptors/RemoteHttpInterceptor.js","import":"./lib/node/interceptors/RemoteHttpInterceptor.mjs","default":"./lib/node/interceptors/RemoteHttpInterceptor.js"},"./presets/node":{"browser":null,"types":"./lib/node/presets/node.d.ts","require":"./lib/node/presets/node.js","import":"./lib/node/presets/node.mjs","default":"./lib/node/presets/node.js"},"./presets/browser":{"browser":{"types":"./lib/browser/presets/browser.d.ts","require":"./lib/browser/presets/browser.js","import":"./lib/browser/presets/browser.mjs","default":"./lib/browser/presets/browser.js"}}},"author":{"name":"Artem Zakharchenko"},"license":"MIT","engines":{"node":">=18"},"scripts":{"start":"tsc --build -w","test":"yarn test:unit && yarn test:integration","test:unit":"vitest run","test:integration":"yarn test:integration:node && yarn test:integration:browser","test:integration:node":"vitest run -c test/vitest.config.js","test:integration:browser":"playwright test -c test/playwright.config.ts","clean":"rimraf lib","build":"yarn clean && cross-env NODE_ENV=production tsup --splitting","prepare":"yarn simple-git-hooks init","release":"release publish"},"repository":{"type":"git","url":"git+https://github.com/mswjs/interceptors.git"},"devDependencies":{"@commitlint/cli":"^16.0.2","@commitlint/config-conventional":"^16.0.0","@open-draft/test-server":"^0.5.1","@ossjs/release":"^0.4.0","@playwright/test":"^1.31.1","@types/cors":"^2.8.12","@types/express":"^4.17.13","@types/express-rate-limit":"^6.0.0","@types/follow-redirects":"^1.14.1","@types/jest":"^27.0.3","@types/node":"^16.11.26","@types/node-fetch":"2.5.12","@types/supertest":"^2.0.11","axios":"^0.24.0","body-parser":"^1.19.0","commitizen":"^4.2.4","cors":"^2.8.5","cross-env":"^7.0.3","cz-conventional-changelog":"3.3.0","express":"^4.17.3","express-rate-limit":"^6.3.0","follow-redirects":"^1.15.1","got":"^11.8.3","jest":"^27.4.3","node-fetch":"2.6.7","playwright":"^1.31.1","rimraf":"^3.0.2","simple-git-hooks":"^2.7.0","superagent":"^6.1.0","supertest":"^6.1.6","ts-jest":"^27.1.1","tsup":"^6.5.0","typescript":"^4.9.4","vitest":"^0.28.5","wait-for-expect":"^3.0.2","web-encoding":"^1.1.5","webpack-http-server":"^0.5.0"},"dependencies":{"@open-draft/deferred-promise":"^2.1.0","@open-draft/logger":"^0.3.0","@open-draft/until":"^2.0.0","headers-polyfill":"^3.1.0","is-node-process":"^1.2.0","outvariant":"^1.2.1","strict-event-emitter":"^0.5.0"},"resolutions":{"memfs":"^3.4.13"},"keywords":["request","intercept","http","https","xmlhttprequest","xhr","fetch","low-level","mock","spy","testing"],"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"[![Latest version](https://img.shields.io/npm/v/@mswjs/interceptors.svg)](https://www.npmjs.com/package/@mswjs/interceptors)\n\n# `@mswjs/interceptors`\n\nLow-level HTTP/HTTPS/XHR/fetch request interception library.\n\n**Intercepts any requests issued by:**\n\n- `http.get`/`http.request`\n- `https.get`/`https.request`\n- `XMLHttpRequest`\n- `window.fetch`\n- Any third-party libraries that use the modules above (i.e. `axios`, `request`, `node-fetch`, `supertest`, etc.)\n\n## Motivation\n\nWhile there are a lot of network communication mocking libraries, they tend to use request interception as an implementation detail, giving you a high-level API that includes request matching, timeouts, retries, and so forth.\n\nThis library is a strip-to-bone implementation that provides as little abstraction as possible to execute arbitrary logic upon any request. It's primarily designed as an underlying component for high-level API mocking solutions such as [Mock Service Worker](https://github.com/mswjs/msw).\n\n### How is this library different?\n\nA traditional API mocking implementation in Node.js looks roughly like this:\n\n```js\nimport http from 'http'\n\nfunction applyMock() {\n  // Store the original request module.\n  const originalHttpRequest = http.request\n\n  // Rewrite the request module entirely.\n  http.request = function (...args) {\n    // Decide whether to handle this request before\n    // the actual request happens.\n    if (shouldMock(args)) {\n      // If so, never create a request, respond to it\n      // using the mocked response from this blackbox.\n      return coerceToResponse.bind(this, mock)\n    }\n\n    // Otherwise, construct the original request\n    // and perform it as-is (receives the original response).\n    return originalHttpRequest(...args)\n  }\n}\n```\n\nThis library deviates from such implementation and uses _class extensions_ instead of module rewrites. Such deviation is necessary because, unlike other solutions that include request matching and can determine whether to mock requests _before_ they actually happen, this library is not opinionated about the mocked/bypassed nature of the requests. Instead, it _intercepts all requests_ and delegates the decision of mocking to the end consumer.\n\n```js\nclass NodeClientRequest extends ClientRequest {\n  async end(...args) {\n    // Check if there's a mocked response for this request.\n    // You control this in the \"resolver\" function.\n    const mockedResponse = await resolver(request)\n\n    // If there is a mocked response, use it to respond to this\n    // request, finalizing it afterward as if it received that\n    // response from the actual server it connected to.\n    if (mockedResponse) {\n      this.respondWith(mockedResponse)\n      this.finish()\n      return\n    }\n\n    // Otherwise, perform the original \"ClientRequest.prototype.end\" call.\n    return super.end(...args)\n  }\n}\n```\n\nBy extending the native modules, this library actually constructs requests as soon as they are constructed by the consumer. This enables all the request input validation and transformations done natively by Node.js—something that traditional solutions simply cannot do (they replace `http.ClientRequest` entirely). The class extension allows to fully utilize Node.js internals instead of polyfilling them, which results in more resilient mocks.\n\n## What this library does\n\nThis library extends (or patches, where applicable) the following native modules:\n\n- `http.get`/`http.request`\n- `https.get`/`https.request`\n- `XMLHttpRequest`\n- `fetch`\n\nOnce extended, it intercepts and normalizes all requests to the Fetch API `Request` instances. This way, no matter the request source (`http.ClientRequest`, `XMLHttpRequest`, `window.Request`, etc), you always get a specification-compliant request instance to work with.\n\nYou can respond to the intercepted request by constructing a Fetch API Response instance. Instead of designing custom abstractions, this library respects the Fetch API specification and takes the responsibility to coerce a single response declaration to the appropriate response formats based on the request-issuing modules (like `http.OutgoingMessage` to respond to `http.ClientRequest`, or updating `XMLHttpRequest` response-related properties).\n\n## What this library doesn't do\n\n- Does **not** provide any request matching logic;\n- Does **not** decide how to handle requests.\n\n## Getting started\n\n```bash\nnpm install @mswjs/interceptors\n```\n\n## Interceptors\n\nTo use this library you need to choose one or multiple interceptors to apply. There are different interceptors exported by this library to spy on respective request-issuing modules:\n\n- `ClientRequestInterceptor` to spy on `http.ClientRequest` (`http.get`/`http.request`);\n- `XMLHttpRequestInterceptor` to spy on `XMLHttpRequest`;\n- `FetchInterceptor` to spy on `fetch`.\n\nUse an interceptor by constructing it and attaching request/response listeners:\n\n```js\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\n\nconst interceptor = new ClientRequestInterceptor()\n\n// Enable the interception of requests.\ninterceptor.apply()\n\n// Listen to any \"http.ClientRequest\" being dispatched,\n// and log its method and full URL.\ninterceptor.on('request', ({ request, requestId }) => {\n  console.log(request.method, request.url)\n})\n\n// Listen to any responses sent to \"http.ClientRequest\".\n// Note that this listener is read-only and cannot affect responses.\ninterceptor.on(\n  'response',\n  ({ response, isMockedResponse, request, requestId }) => {\n    console.log('response to %s %s was:', request.method, request.url, response)\n  }\n)\n```\n\nAll HTTP request interceptors implement the same events:\n\n- `request`, emitted whenever a request has been dispatched;\n- `response`, emitted whenever any request receives a response.\n\n### Using multiple interceptors\n\nYou can combine multiple interceptors to capture requests from different request-issuing modules at once.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: [\n    new ClientRequestInterceptor(),\n    new XMLHttpRequestInterceptor(),\n  ],\n})\n\ninterceptor.apply()\n\n// This \"request\" listener will be called on both\n// \"http.ClientRequest\" and \"XMLHttpRequest\" being dispatched.\ninterceptor.on('request', listener)\n```\n\n> Note that you can use [pre-defined presets](#presets) that cover all the request sources for a given environment type.\n\n## Presets\n\nWhen using [`BatchInterceptor`](#batchinterceptor), you can provide a pre-defined preset to its \"interceptors\" option to capture all request for that environment.\n\n### Node.js preset\n\nThis preset combines `ClientRequestInterceptor`, `XMLHttpRequestInterceptor` and is meant to be used in Node.js.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport nodeInterceptors from '@mswjs/interceptors/presets/node'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: nodeInterceptors,\n})\n\ninterceptor.apply()\n\ninterceptor.on('request', listener)\n```\n\n### Browser preset\n\nThis preset combines `XMLHttpRequestInterceptor` and `FetchInterceptor` and is meant to be used in a browser.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport browserInterceptors from '@mswjs/interceptors/presets/browser'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: browserInterceptors,\n})\n\ninterceptor.on('request', listener)\n```\n\n## Introspecting requests\n\nAll HTTP request interceptors emit a \"request\" event. In the listener to this event, they expose a `request` reference, which is a [Fetch API Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) instance.\n\n> There are many ways to describe a request in Node.js but this library coerces different request definitions to a single specification-compliant `Request` instance to make the handling consistent.\n\n```js\ninterceptor.on('reqest', ({ request, requestId }) => {\n  console.log(request.method, request.url)\n})\n```\n\nSince the exposed `request` instance implements the Fetch API specification, you can operate with it just as you do with the regular browser request. For example, this is how you would read the request body as JSON:\n\n```js\ninterceptor.on('request', async ({ request, requestId }) => {\n  const json = await request.clone().json()\n})\n```\n\n> **Do not forget to clone the request before reading its body!**\n\n## Modifying requests\n\nRequest representations are readonly. You can, however, mutate the intercepted request's headers in the \"request\" listener:\n\n```js\ninterceptor.on('request', ({ request }) => {\n  request.headers.set('X-My-Header', 'true')\n})\n```\n\n> This restriction is done so that the library wouldn't have to unnecessarily synchronize the actual request instance and its Fetch API request representation. As of now, this library is not meant to be used as a full-scale proxy.\n\n## Mocking responses\n\nAlthough this library can be used purely for request introspection purposes, you can also affect request resolution by responding to any intercepted request within the \"request\" event.\n\nUse the `request.respondWith()` method to respond to a request with a mocked response:\n\n```js\ninterceptor.on('request', ({ request, requestId }) => {\n  request.respondWith(\n    new Response(\n      JSON.stringify({\n        firstName: 'John',\n        lastName: 'Maverick',\n      }),\n      {\n        status: 201,\n        statusText: 'Created',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n      }\n    )\n  )\n})\n```\n\n> We use Fetch API `Response` class as the middle-ground for mocked response definition. This library then coerces the response instance to the appropriate response format (e.g. to `http.OutgoingMessage` in the case of `http.ClientRequest`).\n\n**The `Response` class is built-in in since Node.js 18. Use a Fetch API-compatible polyfill, like `node-fetch`, for older versions of Node.js.`**\n\nNote that a single request _can only be handled once_. You may want to introduce conditional logic, like routing, in your request listener but it's generally advised to use a higher-level library like [Mock Service Worker](https://github.com/mswjs/msw) that does request matching for you.\n\nRequests must be responded to within the same tick as the request listener. This means you cannot respond to a request using `setTimeout`, as this will delegate the callback to the next tick. If you wish to introduce asynchronous side-effects in the listener, consider making it an `async` function, awaiting any side-effects you need.\n\n```js\n// Respond to all requests with a 500 response\n// delayed by 500ms.\ninterceptor.on('request', async ({ request, requestId }) => {\n  await sleep(500)\n  request.respondWith(new Response(null, { status: 500 }))\n})\n```\n\n## Observing responses\n\nYou can use the \"response\" event to transparently observe any incoming responses in your Node.js process.\n\n```js\ninterceptor.on(\n  'response',\n  ({ response, isMockedResponse, request, requestId }) => {\n    // react to the incoming response...\n  }\n)\n```\n\n> Note that the `isMockedResponse` property will only be set to `true` if you resolved this request in the \"request\" event listener using the `request.respondWith()` method and providing a mocked `Response` instance.\n\n## API\n\n### `Interceptor`\n\nA generic class implemented by all interceptors. You do not interact with this class directly.\n\n```ts\nclass Interceptor {\n  // Applies the interceptor, enabling the interception of requests\n  // in the current process.\n  apply(): void\n\n  // Listens to the public interceptor events.\n  // For HTTP requests, these are \"request' and \"response\" events.\n  on(event, listener): void\n\n  // Cleans up any side-effects introduced by the interceptor\n  // and disables the interception of requests.\n  dispose(): void\n}\n```\n\n**For public consumption, use [interceptors](#interceptors) instead**.\n\n### `BatchInterceptor`\n\nApplies multiple request interceptors at the same time.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport nodeInterceptors from '@mswjs/interceptors/presets/node'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: nodeInterceptors,\n})\n\ninterceptor.apply()\n\ninterceptor.on('request', ({ request, requestId }) => {\n  // Inspect the intercepted \"request\".\n  // Optionally, return a mocked response.\n})\n```\n\n> Using the `/presets/node` interceptors preset is the recommended way to ensure all requests get intercepted, regardless of their origin.\n\n### `RemoteHttpInterceptor`\n\nEnables request interception in the current process while delegating the response resolution logic to the _parent process_. **Requires the current process to be a child process**. Requires the parent process to establish a resolver by calling the `createRemoteResolver` function.\n\n```js\n// child.js\nimport { RemoteHttpInterceptor } from '@mswjs/interceptors/RemoteHttpInterceptor'\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\n\nconst interceptor = new RemoteHttpInterceptor({\n  // Alternatively, you can use presets.\n  interceptors: [new ClientRequestInterceptor()],\n})\n\ninterceptor.apply()\n\nprocess.on('disconnect', () => {\n  interceptor.dispose()\n})\n```\n\nYou can still listen to and handle any requests in the child process via the `request` event listener. Keep in mind that a single request can only be responded to once.\n\n### `RemoteHttpResolver`\n\nResolves an intercepted request in the given child `process`. Requires for that child process to enable request interception by calling the `createRemoteInterceptor` function.\n\n```js\n// parent.js\nimport { spawn } from 'child_process'\nimport { RemoteHttpResolver } from '@mswjs/interceptors/RemoteHttpInterceptor'\n\nconst appProcess = spawn('node', ['app.js'], {\n  stdio: ['inherit', 'inherit', 'inherit', 'ipc'],\n})\n\nconst resolver = new RemoteHttpResolver({\n  process: appProcess,\n})\n\nresolver.on('request', ({ request, requestId }) => {\n  // Optionally, return a mocked response\n  // for a request that occurred in the \"appProcess\".\n})\n```\n\n## Special mention\n\nThe following libraries were used as an inspiration to write this low-level API:\n\n- [`node`](https://github.com/nodejs/node)\n- [`nock`](https://github.com/nock/nock)\n- [`mock-xmlhttprequest`](https://github.com/berniegp/mock-xmlhttprequest)\n","readmeFilename":"README.md","gitHead":"34076579810d267baa8981b08cded4d436844dcd","bugs":{"url":"https://github.com/mswjs/interceptors/issues"},"homepage":"https://github.com/mswjs/interceptors#readme","_id":"@avivasyuta/request-interceptor@0.1.1-dev2","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-K4/sOK4rOYNjYowT3OEP8UOXJbj/7d0+urwibwldN+7ILoHFk8+NKzK1/+u259o1ZwqkwvkH8ilRIH/8UwKGgg==","shasum":"c3bd2077bf5b876310cd3858e6b69b6f25787b62","tarball":"https://registry.npmjs.org/@avivasyuta/request-interceptor/-/request-interceptor-0.1.1-dev2.tgz","fileCount":129,"unpackedSize":556773,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICoBJ6L7/BaUuaCacAOCXwmetfzlCm5g4DdHqTtNe2JVAiEAnaM2rmeRyviq6zAWpyQE1UqjEKa6acvs7lYQRtadF5k="}]},"_npmUser":{"name":"avivasyuta","email":"avivasyuta@gmail.com"},"directories":{},"maintainers":[{"name":"avivasyuta","email":"avivasyuta@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/request-interceptor_0.1.1-dev2_1692209563590_0.18462924167133443"},"_hasShrinkwrap":false},"0.1.2":{"name":"@avivasyuta/request-interceptor","description":"Low-level HTTP/HTTPS/XHR/fetch request interception library. Fork of @mswjs/interceptors.","version":"0.1.2","main":"./lib/node/index.js","module":"./lib/node/index.mjs","types":"./lib/node/index.d.ts","publishConfig":{"access":"public"},"exports":{".":{"types":"./lib/node/index.d.ts","require":"./lib/node/index.js","import":"./lib/node/index.mjs","default":"./lib/node/index.js"},"./ClientRequest":{"browser":null,"types":"./lib/node/interceptors/ClientRequest/index.d.ts","require":"./lib/node/interceptors/ClientRequest/index.js","import":"./lib/node/interceptors/ClientRequest/index.mjs","default":"./lib/node/interceptors/ClientRequest/index.js"},"./XMLHttpRequest":{"browser":{"types":"./lib/browser/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/browser/interceptors/XMLHttpRequest/index.js","import":"./lib/browser/interceptors/XMLHttpRequest/index.mjs","default":"./lib/browser/interceptors/XMLHttpRequest/index.js"},"types":"./lib/node/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/node/interceptors/XMLHttpRequest/index.js","import":"./lib/node/interceptors/XMLHttpRequest/index.mjs","default":"./lib/node/interceptors/XMLHttpRequest/index.js"},"./fetch":{"browser":{"types":"./lib/browser/interceptors/fetch/index.d.ts","require":"./lib/browser/interceptors/fetch/index.js","import":"./lib/browser/interceptors/fetch/index.mjs","default":"./lib/browser/interceptors/fetch/index.js"},"types":"./lib/node/interceptors/fetch/index.d.ts","require":"./lib/node/interceptors/fetch/index.js","import":"./lib/node/interceptors/fetch/index.mjs","default":"./lib/node/interceptors/fetch/index.js"},"./RemoteHttpInterceptor":{"browser":null,"types":"./lib/node/interceptors/RemoteHttpInterceptor.d.ts","require":"./lib/node/interceptors/RemoteHttpInterceptor.js","import":"./lib/node/interceptors/RemoteHttpInterceptor.mjs","default":"./lib/node/interceptors/RemoteHttpInterceptor.js"},"./presets/node":{"browser":null,"types":"./lib/node/presets/node.d.ts","require":"./lib/node/presets/node.js","import":"./lib/node/presets/node.mjs","default":"./lib/node/presets/node.js"},"./presets/browser":{"browser":{"types":"./lib/browser/presets/browser.d.ts","require":"./lib/browser/presets/browser.js","import":"./lib/browser/presets/browser.mjs","default":"./lib/browser/presets/browser.js"}}},"author":{"name":"Artem Zakharchenko"},"license":"MIT","engines":{"node":">=18"},"scripts":{"start":"tsc --build -w","test":"yarn test:unit && yarn test:integration","test:unit":"vitest run","test:integration":"yarn test:integration:node && yarn test:integration:browser","test:integration:node":"vitest run -c test/vitest.config.js","test:integration:browser":"playwright test -c test/playwright.config.ts","clean":"rimraf lib","build":"yarn clean && cross-env NODE_ENV=production tsup --splitting","prepare":"yarn simple-git-hooks init","release":"release publish"},"repository":{"type":"git","url":"git+https://github.com/mswjs/interceptors.git"},"devDependencies":{"@commitlint/cli":"^16.0.2","@commitlint/config-conventional":"^16.0.0","@open-draft/test-server":"^0.5.1","@ossjs/release":"^0.4.0","@playwright/test":"^1.31.1","@types/cors":"^2.8.12","@types/express":"^4.17.13","@types/express-rate-limit":"^6.0.0","@types/follow-redirects":"^1.14.1","@types/jest":"^27.0.3","@types/node":"^16.11.26","@types/node-fetch":"2.5.12","@types/supertest":"^2.0.11","axios":"^0.24.0","body-parser":"^1.19.0","commitizen":"^4.2.4","cors":"^2.8.5","cross-env":"^7.0.3","cz-conventional-changelog":"3.3.0","express":"^4.17.3","express-rate-limit":"^6.3.0","follow-redirects":"^1.15.1","got":"^11.8.3","jest":"^27.4.3","node-fetch":"2.6.7","playwright":"^1.31.1","rimraf":"^3.0.2","simple-git-hooks":"^2.7.0","superagent":"^6.1.0","supertest":"^6.1.6","ts-jest":"^27.1.1","tsup":"^6.5.0","typescript":"^4.9.4","vitest":"^0.28.5","wait-for-expect":"^3.0.2","web-encoding":"^1.1.5","webpack-http-server":"^0.5.0"},"dependencies":{"@open-draft/deferred-promise":"^2.1.0","@open-draft/logger":"^0.3.0","@open-draft/until":"^2.0.0","headers-polyfill":"^3.1.0","is-node-process":"^1.2.0","outvariant":"^1.2.1","strict-event-emitter":"^0.5.0"},"resolutions":{"memfs":"^3.4.13"},"keywords":["request","intercept","http","https","xmlhttprequest","xhr","fetch","low-level","mock","spy","testing"],"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"34076579810d267baa8981b08cded4d436844dcd","bugs":{"url":"https://github.com/mswjs/interceptors/issues"},"homepage":"https://github.com/mswjs/interceptors#readme","_id":"@avivasyuta/request-interceptor@0.1.2","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-7x/jWHrytaLbuaUPsndCZPB5SLI6+FWtBy3HPHbgmCHZzvRoISBNoMbOriZ6ANEMrC+Jn3bjt3HVJPWqCnMFjQ==","shasum":"a3b489d92f4c1ccf19d560789dc0826ddf191498","tarball":"https://registry.npmjs.org/@avivasyuta/request-interceptor/-/request-interceptor-0.1.2.tgz","fileCount":72,"unpackedSize":177660,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDUlQiusndzmFoM4niSC2IG05GKS6uZr61MWEkVPgFf7QIhAKEN2aiB4fUz4DGVIrj/T/JeiJikZ7b/AO62sZVygET5"}]},"_npmUser":{"name":"avivasyuta","email":"avivasyuta@gmail.com"},"directories":{},"maintainers":[{"name":"avivasyuta","email":"avivasyuta@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/request-interceptor_0.1.2_1692210409534_0.7086141776517338"},"_hasShrinkwrap":false},"0.1.3":{"name":"@avivasyuta/request-interceptor","description":"Low-level HTTP/HTTPS/XHR/fetch request interception library. Fork of @mswjs/interceptors.","version":"0.1.3","main":"./lib/node/index.js","module":"./lib/node/index.mjs","types":"./lib/node/index.d.ts","publishConfig":{"access":"public"},"exports":{".":{"types":"./lib/node/index.d.ts","require":"./lib/node/index.js","import":"./lib/node/index.mjs","default":"./lib/node/index.js"},"./ClientRequest":{"browser":null,"types":"./lib/node/interceptors/ClientRequest/index.d.ts","require":"./lib/node/interceptors/ClientRequest/index.js","import":"./lib/node/interceptors/ClientRequest/index.mjs","default":"./lib/node/interceptors/ClientRequest/index.js"},"./XMLHttpRequest":{"browser":{"types":"./lib/browser/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/browser/interceptors/XMLHttpRequest/index.js","import":"./lib/browser/interceptors/XMLHttpRequest/index.mjs","default":"./lib/browser/interceptors/XMLHttpRequest/index.js"},"types":"./lib/node/interceptors/XMLHttpRequest/index.d.ts","require":"./lib/node/interceptors/XMLHttpRequest/index.js","import":"./lib/node/interceptors/XMLHttpRequest/index.mjs","default":"./lib/node/interceptors/XMLHttpRequest/index.js"},"./fetch":{"browser":{"types":"./lib/browser/interceptors/fetch/index.d.ts","require":"./lib/browser/interceptors/fetch/index.js","import":"./lib/browser/interceptors/fetch/index.mjs","default":"./lib/browser/interceptors/fetch/index.js"},"types":"./lib/node/interceptors/fetch/index.d.ts","require":"./lib/node/interceptors/fetch/index.js","import":"./lib/node/interceptors/fetch/index.mjs","default":"./lib/node/interceptors/fetch/index.js"},"./RemoteHttpInterceptor":{"browser":null,"types":"./lib/node/interceptors/RemoteHttpInterceptor.d.ts","require":"./lib/node/interceptors/RemoteHttpInterceptor.js","import":"./lib/node/interceptors/RemoteHttpInterceptor.mjs","default":"./lib/node/interceptors/RemoteHttpInterceptor.js"},"./presets/node":{"browser":null,"types":"./lib/node/presets/node.d.ts","require":"./lib/node/presets/node.js","import":"./lib/node/presets/node.mjs","default":"./lib/node/presets/node.js"},"./presets/browser":{"browser":{"types":"./lib/browser/presets/browser.d.ts","require":"./lib/browser/presets/browser.js","import":"./lib/browser/presets/browser.mjs","default":"./lib/browser/presets/browser.js"}}},"author":{"name":"Artem Zakharchenko"},"license":"MIT","engines":{"node":">=18"},"scripts":{"start":"tsc --build -w","test":"yarn test:unit && yarn test:integration","test:unit":"vitest run","test:integration":"yarn test:integration:node && yarn test:integration:browser","test:integration:node":"vitest run -c test/vitest.config.js","test:integration:browser":"playwright test -c test/playwright.config.ts","clean":"rimraf lib","build":"yarn clean && cross-env NODE_ENV=production tsup --splitting","prepare":"yarn simple-git-hooks init","release":"release publish"},"repository":{"type":"git","url":"git+https://github.com/mswjs/interceptors.git"},"devDependencies":{"@commitlint/cli":"^16.0.2","@commitlint/config-conventional":"^16.0.0","@open-draft/test-server":"^0.5.1","@ossjs/release":"^0.4.0","@playwright/test":"^1.31.1","@types/cors":"^2.8.12","@types/express":"^4.17.13","@types/express-rate-limit":"^6.0.0","@types/follow-redirects":"^1.14.1","@types/jest":"^27.0.3","@types/node":"^16.11.26","@types/node-fetch":"2.5.12","@types/supertest":"^2.0.11","axios":"^0.24.0","body-parser":"^1.19.0","commitizen":"^4.2.4","cors":"^2.8.5","cross-env":"^7.0.3","cz-conventional-changelog":"3.3.0","express":"^4.17.3","express-rate-limit":"^6.3.0","follow-redirects":"^1.15.1","got":"^11.8.3","jest":"^27.4.3","node-fetch":"2.6.7","playwright":"^1.31.1","rimraf":"^3.0.2","simple-git-hooks":"^2.7.0","superagent":"^6.1.0","supertest":"^6.1.6","ts-jest":"^27.1.1","tsup":"^6.5.0","typescript":"^4.9.4","vitest":"^0.28.5","wait-for-expect":"^3.0.2","web-encoding":"^1.1.5","webpack-http-server":"^0.5.0"},"dependencies":{"@open-draft/deferred-promise":"^2.1.0","@open-draft/logger":"^0.3.0","@open-draft/until":"^2.0.0","headers-polyfill":"^3.1.0","is-node-process":"^1.2.0","outvariant":"^1.2.1","strict-event-emitter":"^0.5.0"},"resolutions":{"memfs":"^3.4.13"},"keywords":["request","intercept","http","https","xmlhttprequest","xhr","fetch","low-level","mock","spy","testing"],"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"34076579810d267baa8981b08cded4d436844dcd","bugs":{"url":"https://github.com/mswjs/interceptors/issues"},"homepage":"https://github.com/mswjs/interceptors#readme","_id":"@avivasyuta/request-interceptor@0.1.3","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-a7/cEyplAQd4A8awy8+CONlvGVrLVXfqsQ4hLU/LlnzB2g44FqHcTVqWwE+v78a9pO27GFDzcNC9gkHea5U+kQ==","shasum":"d03cd6eb54f728497a06645ce1f282314de5db91","tarball":"https://registry.npmjs.org/@avivasyuta/request-interceptor/-/request-interceptor-0.1.3.tgz","fileCount":129,"unpackedSize":556545,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEbcYk0rUWe12izPonU73lWTlfvKJkXW1YfQQN/tY9PTAiEA8KrXA8v4AUUGKTFGDAlr0FV8ILBwfxgOi0kFbyBCYN0="}]},"_npmUser":{"name":"avivasyuta","email":"avivasyuta@gmail.com"},"directories":{},"maintainers":[{"name":"avivasyuta","email":"avivasyuta@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/request-interceptor_0.1.3_1692210758295_0.46739232030264155"},"_hasShrinkwrap":false}},"time":{"created":"2023-08-12T18:13:03.452Z","0.1.0":"2023-08-12T18:13:03.815Z","modified":"2023-08-16T18:32:38.768Z","0.1.1-dev":"2023-08-16T18:05:06.065Z","0.1.1-dev2":"2023-08-16T18:12:43.864Z","0.1.2":"2023-08-16T18:26:49.760Z","0.1.3":"2023-08-16T18:32:38.590Z"},"maintainers":[{"name":"avivasyuta","email":"avivasyuta@gmail.com"}],"description":"Low-level HTTP/HTTPS/XHR/fetch request interception library. Fork of @mswjs/interceptors.","homepage":"https://github.com/mswjs/interceptors#readme","keywords":["request","intercept","http","https","xmlhttprequest","xhr","fetch","low-level","mock","spy","testing"],"repository":{"type":"git","url":"git+https://github.com/mswjs/interceptors.git"},"author":{"name":"Artem Zakharchenko"},"bugs":{"url":"https://github.com/mswjs/interceptors/issues"},"license":"MIT","readme":"[![Latest version](https://img.shields.io/npm/v/@mswjs/interceptors.svg)](https://www.npmjs.com/package/@mswjs/interceptors)\n\n# `@mswjs/interceptors`\n\nLow-level HTTP/HTTPS/XHR/fetch request interception library.\n\n**Intercepts any requests issued by:**\n\n- `http.get`/`http.request`\n- `https.get`/`https.request`\n- `XMLHttpRequest`\n- `window.fetch`\n- Any third-party libraries that use the modules above (i.e. `axios`, `request`, `node-fetch`, `supertest`, etc.)\n\n## Motivation\n\nWhile there are a lot of network communication mocking libraries, they tend to use request interception as an implementation detail, giving you a high-level API that includes request matching, timeouts, retries, and so forth.\n\nThis library is a strip-to-bone implementation that provides as little abstraction as possible to execute arbitrary logic upon any request. It's primarily designed as an underlying component for high-level API mocking solutions such as [Mock Service Worker](https://github.com/mswjs/msw).\n\n### How is this library different?\n\nA traditional API mocking implementation in Node.js looks roughly like this:\n\n```js\nimport http from 'http'\n\nfunction applyMock() {\n  // Store the original request module.\n  const originalHttpRequest = http.request\n\n  // Rewrite the request module entirely.\n  http.request = function (...args) {\n    // Decide whether to handle this request before\n    // the actual request happens.\n    if (shouldMock(args)) {\n      // If so, never create a request, respond to it\n      // using the mocked response from this blackbox.\n      return coerceToResponse.bind(this, mock)\n    }\n\n    // Otherwise, construct the original request\n    // and perform it as-is (receives the original response).\n    return originalHttpRequest(...args)\n  }\n}\n```\n\nThis library deviates from such implementation and uses _class extensions_ instead of module rewrites. Such deviation is necessary because, unlike other solutions that include request matching and can determine whether to mock requests _before_ they actually happen, this library is not opinionated about the mocked/bypassed nature of the requests. Instead, it _intercepts all requests_ and delegates the decision of mocking to the end consumer.\n\n```js\nclass NodeClientRequest extends ClientRequest {\n  async end(...args) {\n    // Check if there's a mocked response for this request.\n    // You control this in the \"resolver\" function.\n    const mockedResponse = await resolver(request)\n\n    // If there is a mocked response, use it to respond to this\n    // request, finalizing it afterward as if it received that\n    // response from the actual server it connected to.\n    if (mockedResponse) {\n      this.respondWith(mockedResponse)\n      this.finish()\n      return\n    }\n\n    // Otherwise, perform the original \"ClientRequest.prototype.end\" call.\n    return super.end(...args)\n  }\n}\n```\n\nBy extending the native modules, this library actually constructs requests as soon as they are constructed by the consumer. This enables all the request input validation and transformations done natively by Node.js—something that traditional solutions simply cannot do (they replace `http.ClientRequest` entirely). The class extension allows to fully utilize Node.js internals instead of polyfilling them, which results in more resilient mocks.\n\n## What this library does\n\nThis library extends (or patches, where applicable) the following native modules:\n\n- `http.get`/`http.request`\n- `https.get`/`https.request`\n- `XMLHttpRequest`\n- `fetch`\n\nOnce extended, it intercepts and normalizes all requests to the Fetch API `Request` instances. This way, no matter the request source (`http.ClientRequest`, `XMLHttpRequest`, `window.Request`, etc), you always get a specification-compliant request instance to work with.\n\nYou can respond to the intercepted request by constructing a Fetch API Response instance. Instead of designing custom abstractions, this library respects the Fetch API specification and takes the responsibility to coerce a single response declaration to the appropriate response formats based on the request-issuing modules (like `http.OutgoingMessage` to respond to `http.ClientRequest`, or updating `XMLHttpRequest` response-related properties).\n\n## What this library doesn't do\n\n- Does **not** provide any request matching logic;\n- Does **not** decide how to handle requests.\n\n## Getting started\n\n```bash\nnpm install @mswjs/interceptors\n```\n\n## Interceptors\n\nTo use this library you need to choose one or multiple interceptors to apply. There are different interceptors exported by this library to spy on respective request-issuing modules:\n\n- `ClientRequestInterceptor` to spy on `http.ClientRequest` (`http.get`/`http.request`);\n- `XMLHttpRequestInterceptor` to spy on `XMLHttpRequest`;\n- `FetchInterceptor` to spy on `fetch`.\n\nUse an interceptor by constructing it and attaching request/response listeners:\n\n```js\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\n\nconst interceptor = new ClientRequestInterceptor()\n\n// Enable the interception of requests.\ninterceptor.apply()\n\n// Listen to any \"http.ClientRequest\" being dispatched,\n// and log its method and full URL.\ninterceptor.on('request', ({ request, requestId }) => {\n  console.log(request.method, request.url)\n})\n\n// Listen to any responses sent to \"http.ClientRequest\".\n// Note that this listener is read-only and cannot affect responses.\ninterceptor.on(\n  'response',\n  ({ response, isMockedResponse, request, requestId }) => {\n    console.log('response to %s %s was:', request.method, request.url, response)\n  }\n)\n```\n\nAll HTTP request interceptors implement the same events:\n\n- `request`, emitted whenever a request has been dispatched;\n- `response`, emitted whenever any request receives a response.\n\n### Using multiple interceptors\n\nYou can combine multiple interceptors to capture requests from different request-issuing modules at once.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: [\n    new ClientRequestInterceptor(),\n    new XMLHttpRequestInterceptor(),\n  ],\n})\n\ninterceptor.apply()\n\n// This \"request\" listener will be called on both\n// \"http.ClientRequest\" and \"XMLHttpRequest\" being dispatched.\ninterceptor.on('request', listener)\n```\n\n> Note that you can use [pre-defined presets](#presets) that cover all the request sources for a given environment type.\n\n## Presets\n\nWhen using [`BatchInterceptor`](#batchinterceptor), you can provide a pre-defined preset to its \"interceptors\" option to capture all request for that environment.\n\n### Node.js preset\n\nThis preset combines `ClientRequestInterceptor`, `XMLHttpRequestInterceptor` and is meant to be used in Node.js.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport nodeInterceptors from '@mswjs/interceptors/presets/node'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: nodeInterceptors,\n})\n\ninterceptor.apply()\n\ninterceptor.on('request', listener)\n```\n\n### Browser preset\n\nThis preset combines `XMLHttpRequestInterceptor` and `FetchInterceptor` and is meant to be used in a browser.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport browserInterceptors from '@mswjs/interceptors/presets/browser'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: browserInterceptors,\n})\n\ninterceptor.on('request', listener)\n```\n\n## Introspecting requests\n\nAll HTTP request interceptors emit a \"request\" event. In the listener to this event, they expose a `request` reference, which is a [Fetch API Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) instance.\n\n> There are many ways to describe a request in Node.js but this library coerces different request definitions to a single specification-compliant `Request` instance to make the handling consistent.\n\n```js\ninterceptor.on('reqest', ({ request, requestId }) => {\n  console.log(request.method, request.url)\n})\n```\n\nSince the exposed `request` instance implements the Fetch API specification, you can operate with it just as you do with the regular browser request. For example, this is how you would read the request body as JSON:\n\n```js\ninterceptor.on('request', async ({ request, requestId }) => {\n  const json = await request.clone().json()\n})\n```\n\n> **Do not forget to clone the request before reading its body!**\n\n## Modifying requests\n\nRequest representations are readonly. You can, however, mutate the intercepted request's headers in the \"request\" listener:\n\n```js\ninterceptor.on('request', ({ request }) => {\n  request.headers.set('X-My-Header', 'true')\n})\n```\n\n> This restriction is done so that the library wouldn't have to unnecessarily synchronize the actual request instance and its Fetch API request representation. As of now, this library is not meant to be used as a full-scale proxy.\n\n## Mocking responses\n\nAlthough this library can be used purely for request introspection purposes, you can also affect request resolution by responding to any intercepted request within the \"request\" event.\n\nUse the `request.respondWith()` method to respond to a request with a mocked response:\n\n```js\ninterceptor.on('request', ({ request, requestId }) => {\n  request.respondWith(\n    new Response(\n      JSON.stringify({\n        firstName: 'John',\n        lastName: 'Maverick',\n      }),\n      {\n        status: 201,\n        statusText: 'Created',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n      }\n    )\n  )\n})\n```\n\n> We use Fetch API `Response` class as the middle-ground for mocked response definition. This library then coerces the response instance to the appropriate response format (e.g. to `http.OutgoingMessage` in the case of `http.ClientRequest`).\n\n**The `Response` class is built-in in since Node.js 18. Use a Fetch API-compatible polyfill, like `node-fetch`, for older versions of Node.js.`**\n\nNote that a single request _can only be handled once_. You may want to introduce conditional logic, like routing, in your request listener but it's generally advised to use a higher-level library like [Mock Service Worker](https://github.com/mswjs/msw) that does request matching for you.\n\nRequests must be responded to within the same tick as the request listener. This means you cannot respond to a request using `setTimeout`, as this will delegate the callback to the next tick. If you wish to introduce asynchronous side-effects in the listener, consider making it an `async` function, awaiting any side-effects you need.\n\n```js\n// Respond to all requests with a 500 response\n// delayed by 500ms.\ninterceptor.on('request', async ({ request, requestId }) => {\n  await sleep(500)\n  request.respondWith(new Response(null, { status: 500 }))\n})\n```\n\n## Observing responses\n\nYou can use the \"response\" event to transparently observe any incoming responses in your Node.js process.\n\n```js\ninterceptor.on(\n  'response',\n  ({ response, isMockedResponse, request, requestId }) => {\n    // react to the incoming response...\n  }\n)\n```\n\n> Note that the `isMockedResponse` property will only be set to `true` if you resolved this request in the \"request\" event listener using the `request.respondWith()` method and providing a mocked `Response` instance.\n\n## API\n\n### `Interceptor`\n\nA generic class implemented by all interceptors. You do not interact with this class directly.\n\n```ts\nclass Interceptor {\n  // Applies the interceptor, enabling the interception of requests\n  // in the current process.\n  apply(): void\n\n  // Listens to the public interceptor events.\n  // For HTTP requests, these are \"request' and \"response\" events.\n  on(event, listener): void\n\n  // Cleans up any side-effects introduced by the interceptor\n  // and disables the interception of requests.\n  dispose(): void\n}\n```\n\n**For public consumption, use [interceptors](#interceptors) instead**.\n\n### `BatchInterceptor`\n\nApplies multiple request interceptors at the same time.\n\n```js\nimport { BatchInterceptor } from '@mswjs/interceptors'\nimport nodeInterceptors from '@mswjs/interceptors/presets/node'\n\nconst interceptor = new BatchInterceptor({\n  name: 'my-interceptor',\n  interceptors: nodeInterceptors,\n})\n\ninterceptor.apply()\n\ninterceptor.on('request', ({ request, requestId }) => {\n  // Inspect the intercepted \"request\".\n  // Optionally, return a mocked response.\n})\n```\n\n> Using the `/presets/node` interceptors preset is the recommended way to ensure all requests get intercepted, regardless of their origin.\n\n### `RemoteHttpInterceptor`\n\nEnables request interception in the current process while delegating the response resolution logic to the _parent process_. **Requires the current process to be a child process**. Requires the parent process to establish a resolver by calling the `createRemoteResolver` function.\n\n```js\n// child.js\nimport { RemoteHttpInterceptor } from '@mswjs/interceptors/RemoteHttpInterceptor'\nimport { ClientRequestInterceptor } from '@mswjs/interceptors/ClientRequest'\n\nconst interceptor = new RemoteHttpInterceptor({\n  // Alternatively, you can use presets.\n  interceptors: [new ClientRequestInterceptor()],\n})\n\ninterceptor.apply()\n\nprocess.on('disconnect', () => {\n  interceptor.dispose()\n})\n```\n\nYou can still listen to and handle any requests in the child process via the `request` event listener. Keep in mind that a single request can only be responded to once.\n\n### `RemoteHttpResolver`\n\nResolves an intercepted request in the given child `process`. Requires for that child process to enable request interception by calling the `createRemoteInterceptor` function.\n\n```js\n// parent.js\nimport { spawn } from 'child_process'\nimport { RemoteHttpResolver } from '@mswjs/interceptors/RemoteHttpInterceptor'\n\nconst appProcess = spawn('node', ['app.js'], {\n  stdio: ['inherit', 'inherit', 'inherit', 'ipc'],\n})\n\nconst resolver = new RemoteHttpResolver({\n  process: appProcess,\n})\n\nresolver.on('request', ({ request, requestId }) => {\n  // Optionally, return a mocked response\n  // for a request that occurred in the \"appProcess\".\n})\n```\n\n## Special mention\n\nThe following libraries were used as an inspiration to write this low-level API:\n\n- [`node`](https://github.com/nodejs/node)\n- [`nock`](https://github.com/nock/nock)\n- [`mock-xmlhttprequest`](https://github.com/berniegp/mock-xmlhttprequest)\n","readmeFilename":"README.md"}