@mswjs/interceptors 0.15.1 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +68 -49
  3. package/lib/BatchInterceptor.d.ts +18 -0
  4. package/lib/BatchInterceptor.js +79 -0
  5. package/lib/BatchInterceptor.js.map +1 -0
  6. package/lib/Interceptor.d.ts +49 -0
  7. package/lib/Interceptor.js +197 -0
  8. package/lib/Interceptor.js.map +1 -0
  9. package/lib/RemoteInterceptor.d.ts +24 -0
  10. package/lib/RemoteInterceptor.js +216 -0
  11. package/lib/RemoteInterceptor.js.map +1 -0
  12. package/lib/glossary.d.ts +32 -0
  13. package/lib/glossary.js +3 -0
  14. package/lib/glossary.js.map +1 -0
  15. package/lib/index.d.ts +2 -2
  16. package/lib/index.js +2 -2
  17. package/lib/index.js.map +1 -1
  18. package/lib/interceptors/ClientRequest/NodeClientRequest.d.ts +5 -5
  19. package/lib/interceptors/ClientRequest/NodeClientRequest.js +56 -15
  20. package/lib/interceptors/ClientRequest/NodeClientRequest.js.map +1 -1
  21. package/lib/interceptors/ClientRequest/http.get.d.ts +2 -3
  22. package/lib/interceptors/ClientRequest/http.get.js +2 -5
  23. package/lib/interceptors/ClientRequest/http.get.js.map +1 -1
  24. package/lib/interceptors/ClientRequest/http.request.d.ts +2 -3
  25. package/lib/interceptors/ClientRequest/http.request.js +3 -6
  26. package/lib/interceptors/ClientRequest/http.request.js.map +1 -1
  27. package/lib/interceptors/ClientRequest/index.d.ts +14 -4
  28. package/lib/interceptors/ClientRequest/index.js +59 -46
  29. package/lib/interceptors/ClientRequest/index.js.map +1 -1
  30. package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js +7 -2
  31. package/lib/interceptors/ClientRequest/utils/getIncomingMessageBody.js.map +1 -1
  32. package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.d.ts +11 -4
  33. package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js +110 -58
  34. package/lib/interceptors/XMLHttpRequest/XMLHttpRequestOverride.js.map +1 -1
  35. package/lib/interceptors/XMLHttpRequest/index.d.ts +11 -5
  36. package/lib/interceptors/XMLHttpRequest/index.js +43 -25
  37. package/lib/interceptors/XMLHttpRequest/index.js.map +1 -1
  38. package/lib/interceptors/fetch/index.d.ts +8 -2
  39. package/lib/interceptors/fetch/index.js +120 -68
  40. package/lib/interceptors/fetch/index.js.map +1 -1
  41. package/lib/presets/browser.d.ts +3 -1
  42. package/lib/presets/browser.js +2 -2
  43. package/lib/presets/browser.js.map +1 -1
  44. package/lib/presets/node.d.ts +3 -1
  45. package/lib/presets/node.js +1 -1
  46. package/lib/presets/node.js.map +1 -1
  47. package/lib/utils/AsyncEventEmitter.d.ts +29 -0
  48. package/lib/utils/AsyncEventEmitter.js +241 -0
  49. package/lib/utils/AsyncEventEmitter.js.map +1 -0
  50. package/lib/utils/createLazyCallback.d.ts +11 -0
  51. package/lib/utils/createLazyCallback.js +75 -0
  52. package/lib/utils/createLazyCallback.js.map +1 -0
  53. package/lib/utils/nextTick.d.ts +2 -0
  54. package/lib/utils/nextTick.js +16 -0
  55. package/lib/utils/nextTick.js.map +1 -0
  56. package/lib/utils/toIsoResponse.d.ts +1 -1
  57. package/package.json +6 -6
  58. package/src/BatchInterceptor.test.ts +113 -0
  59. package/src/BatchInterceptor.ts +60 -0
  60. package/src/Interceptor.test.ts +166 -0
  61. package/src/Interceptor.ts +226 -0
  62. package/src/RemoteInterceptor.ts +176 -0
  63. package/src/glossary.ts +42 -0
  64. package/src/index.ts +2 -2
  65. package/src/interceptors/ClientRequest/NodeClientRequest.test.ts +87 -70
  66. package/src/interceptors/ClientRequest/NodeClientRequest.ts +139 -100
  67. package/src/interceptors/ClientRequest/http.get.ts +7 -11
  68. package/src/interceptors/ClientRequest/http.request.ts +8 -12
  69. package/src/interceptors/ClientRequest/index.test.ts +43 -0
  70. package/src/interceptors/ClientRequest/index.ts +46 -46
  71. package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.test.ts +9 -0
  72. package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts +9 -2
  73. package/src/interceptors/XMLHttpRequest/XMLHttpRequestOverride.ts +215 -159
  74. package/src/interceptors/XMLHttpRequest/index.ts +41 -23
  75. package/src/interceptors/fetch/index.ts +81 -55
  76. package/src/presets/browser.ts +3 -3
  77. package/src/presets/node.ts +3 -3
  78. package/src/utils/AsyncEventEmitter.test.ts +68 -0
  79. package/src/utils/AsyncEventEmitter.ts +171 -0
  80. package/src/utils/createLazyCallback.ts +49 -0
  81. package/src/utils/nextTick.ts +11 -0
  82. package/src/utils/toIsoResponse.ts +1 -1
  83. package/lib/createInterceptor.d.ts +0 -54
  84. package/lib/createInterceptor.js +0 -27
  85. package/lib/createInterceptor.js.map +0 -1
  86. package/lib/remote.d.ts +0 -21
  87. package/lib/remote.js +0 -178
  88. package/lib/remote.js.map +0 -1
  89. package/src/createInterceptor.ts +0 -100
  90. package/src/remote.ts +0 -174
package/lib/remote.js DELETED
@@ -1,178 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (_) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __read = (this && this.__read) || function (o, n) {
50
- var m = typeof Symbol === "function" && o[Symbol.iterator];
51
- if (!m) return o;
52
- var i = m.call(o), r, ar = [], e;
53
- try {
54
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
55
- }
56
- catch (error) { e = { error: error }; }
57
- finally {
58
- try {
59
- if (r && !r.done && (m = i["return"])) m.call(i);
60
- }
61
- finally { if (e) throw e.error; }
62
- }
63
- return ar;
64
- };
65
- Object.defineProperty(exports, "__esModule", { value: true });
66
- exports.createRemoteResolver = exports.createRemoteInterceptor = void 0;
67
- var headers_polyfill_1 = require("headers-polyfill");
68
- var outvariant_1 = require("outvariant");
69
- var strict_event_emitter_1 = require("strict-event-emitter");
70
- var createInterceptor_1 = require("./createInterceptor");
71
- var toIsoResponse_1 = require("./utils/toIsoResponse");
72
- function requestReviver(key, value) {
73
- switch (key) {
74
- case 'url':
75
- return new URL(value);
76
- case 'headers':
77
- return new headers_polyfill_1.Headers(value);
78
- default:
79
- return value;
80
- }
81
- }
82
- /**
83
- * Creates a remote request interceptor that delegates
84
- * the mocked response resolution to the parent process.
85
- * The parent process must establish a remote resolver
86
- * by calling `createRemoteResolver` function.
87
- */
88
- function createRemoteInterceptor(options) {
89
- outvariant_1.invariant(process.connected, "Failed to create a remote interceptor: the current process (%s) does not have a parent. Please make sure you're spawning this process as a child process in order to use remote request interception.", process.pid);
90
- if (typeof process.send === 'undefined') {
91
- throw new Error("Failed to create a remote interceptor: the current process (" + process.pid + ") does not have the IPC enabled. Please make sure you're spawning this process with the \"ipc\" stdio value set:\n\nspawn('node', ['module.js'], { stdio: ['ipc'] })");
92
- }
93
- var handleParentMessage;
94
- var interceptor = createInterceptor_1.createInterceptor(__assign(__assign({}, options), { resolver: function (request) {
95
- var _a;
96
- var serializedRequest = JSON.stringify(request);
97
- (_a = process.send) === null || _a === void 0 ? void 0 : _a.call(process, "request:" + serializedRequest);
98
- return new Promise(function (resolve) {
99
- handleParentMessage = function (message) {
100
- if (typeof message !== 'string') {
101
- return;
102
- }
103
- if (message.startsWith("response:" + request.id)) {
104
- var _a = __read(message.match(/^response:.+?:(.+)$/) || [], 2), responseString = _a[1];
105
- if (!responseString) {
106
- return resolve();
107
- }
108
- var mockedResponse = JSON.parse(responseString);
109
- return resolve(mockedResponse);
110
- }
111
- };
112
- process.addListener('message', handleParentMessage);
113
- });
114
- } }));
115
- return __assign(__assign({}, interceptor), { restore: function () {
116
- interceptor.restore();
117
- process.removeListener('message', handleParentMessage);
118
- } });
119
- }
120
- exports.createRemoteInterceptor = createRemoteInterceptor;
121
- /**
122
- * Creates a response resolver function attached to the given `ChildProcess`.
123
- * The child process must establish a remote interceptor by calling `createRemoteInterceptor` function.
124
- */
125
- function createRemoteResolver(options) {
126
- var _this = this;
127
- var observer = new strict_event_emitter_1.StrictEventEmitter();
128
- var handleChildMessage = function (message) { return __awaiter(_this, void 0, void 0, function () {
129
- var _a, requestString, isoRequest_1, mockedResponse_1, serializedResponse;
130
- return __generator(this, function (_b) {
131
- switch (_b.label) {
132
- case 0:
133
- if (typeof message !== 'string') {
134
- return [2 /*return*/];
135
- }
136
- if (!message.startsWith('request:')) return [3 /*break*/, 2];
137
- _a = __read(message.match(/^request:(.+)$/) || [], 2), requestString = _a[1];
138
- if (!requestString) {
139
- return [2 /*return*/];
140
- }
141
- isoRequest_1 = JSON.parse(requestString, requestReviver);
142
- observer.emit('request', isoRequest_1);
143
- return [4 /*yield*/, options.resolver(isoRequest_1, undefined)
144
- // Send the mocked response to the child process.
145
- ];
146
- case 1:
147
- mockedResponse_1 = _b.sent();
148
- serializedResponse = JSON.stringify(mockedResponse_1);
149
- options.process.send("response:" + isoRequest_1.id + ":" + serializedResponse, function (error) {
150
- if (error) {
151
- return;
152
- }
153
- if (mockedResponse_1) {
154
- // Emit an optimisting "response" event at this point,
155
- // not to rely on the back-and-forth signaling for the sake of the event.
156
- observer.emit('response', isoRequest_1, toIsoResponse_1.toIsoResponse(mockedResponse_1));
157
- }
158
- });
159
- _b.label = 2;
160
- case 2: return [2 /*return*/];
161
- }
162
- });
163
- }); };
164
- var cleanup = function () {
165
- options.process.removeListener('message', handleChildMessage);
166
- };
167
- options.process.addListener('message', handleChildMessage);
168
- options.process.addListener('disconnect', cleanup);
169
- options.process.addListener('error', cleanup);
170
- options.process.addListener('exit', cleanup);
171
- return {
172
- on: function (event, listener) {
173
- observer.addListener(event, listener);
174
- },
175
- };
176
- }
177
- exports.createRemoteResolver = createRemoteResolver;
178
- //# sourceMappingURL=remote.js.map
package/lib/remote.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
@@ -1,100 +0,0 @@
1
- import { IncomingMessage } from 'http'
2
- import { HeadersObject, Headers } from 'headers-polyfill'
3
- import { StrictEventEmitter } from 'strict-event-emitter'
4
-
5
- export type Interceptor = (
6
- observer: Observer,
7
- resolver: Resolver
8
- ) => InterceptorCleanupFn
9
-
10
- export type Observer = StrictEventEmitter<InterceptorEventsMap>
11
-
12
- /**
13
- * A side-effect function to restore all the patched modules.
14
- */
15
- export type InterceptorCleanupFn = () => void
16
-
17
- export type RequestCredentials = 'omit' | 'include' | 'same-origin'
18
-
19
- export interface IsomorphicRequest {
20
- id: string
21
- url: URL
22
- method: string
23
- headers: Headers
24
- /**
25
- * The value of the request client's "credentials" option
26
- * or a compatible alternative (i.e. `withCredentials` for `XMLHttpRequest`).
27
- * Always equals to "omit" in Node.js.
28
- */
29
- credentials: RequestCredentials
30
- body?: string
31
- }
32
-
33
- export interface IsomorphicResponse {
34
- status: number
35
- statusText: string
36
- headers: Headers
37
- body?: string
38
- }
39
-
40
- export interface MockedResponse
41
- extends Omit<Partial<IsomorphicResponse>, 'headers'> {
42
- headers?: HeadersObject
43
- }
44
-
45
- export interface InterceptorEventsMap {
46
- request(request: IsomorphicRequest): void
47
- response(request: IsomorphicRequest, response: IsomorphicResponse): void
48
- }
49
-
50
- export type Resolver = (
51
- request: IsomorphicRequest,
52
- ref: IncomingMessage | XMLHttpRequest | Request
53
- ) => MockedResponse | Promise<MockedResponse | void> | void
54
-
55
- export interface InterceptorOptions {
56
- modules: Interceptor[]
57
- resolver: Resolver
58
- }
59
-
60
- export interface InterceptorApi {
61
- /**
62
- * Apply necessary module patches to provision the interception of requests.
63
- */
64
- apply(): void
65
- on<Event extends keyof InterceptorEventsMap>(
66
- event: Event,
67
- listener: InterceptorEventsMap[Event]
68
- ): void
69
- /**
70
- * Restore all applied module patches and disable the interception.
71
- */
72
- restore(): void
73
- }
74
-
75
- export function createInterceptor(options: InterceptorOptions): InterceptorApi {
76
- const observer = new StrictEventEmitter<InterceptorEventsMap>()
77
- let cleanupFns: InterceptorCleanupFn[] = []
78
-
79
- return {
80
- apply() {
81
- cleanupFns = options.modules.map((interceptor) => {
82
- return interceptor(observer, options.resolver)
83
- })
84
- },
85
- on(event, listener) {
86
- observer.addListener(event, listener)
87
- },
88
- restore() {
89
- observer.removeAllListeners()
90
-
91
- if (cleanupFns.length === 0) {
92
- throw new Error(
93
- `Failed to restore patched modules: no patches found. Did you forget to run ".apply()"?`
94
- )
95
- }
96
-
97
- cleanupFns.forEach((restore) => restore())
98
- },
99
- }
100
- }
package/src/remote.ts DELETED
@@ -1,174 +0,0 @@
1
- import { ChildProcess } from 'child_process'
2
- import { Headers } from 'headers-polyfill'
3
- import { invariant } from 'outvariant'
4
- import { StrictEventEmitter } from 'strict-event-emitter'
5
- import {
6
- createInterceptor,
7
- InterceptorApi,
8
- InterceptorEventsMap,
9
- InterceptorOptions,
10
- IsomorphicRequest,
11
- Resolver,
12
- } from './createInterceptor'
13
- import { toIsoResponse } from './utils/toIsoResponse'
14
-
15
- export type CreateRemoteInterceptorOptions = Omit<
16
- InterceptorOptions,
17
- 'resolver'
18
- >
19
-
20
- export type RemoteResolverApi = Pick<InterceptorApi, 'on'>
21
-
22
- export interface CreateRemoteResolverOptions {
23
- process: ChildProcess
24
- resolver: Resolver
25
- }
26
-
27
- function requestReviver(key: string, value: any) {
28
- switch (key) {
29
- case 'url':
30
- return new URL(value)
31
-
32
- case 'headers':
33
- return new Headers(value)
34
-
35
- default:
36
- return value
37
- }
38
- }
39
-
40
- /**
41
- * Creates a remote request interceptor that delegates
42
- * the mocked response resolution to the parent process.
43
- * The parent process must establish a remote resolver
44
- * by calling `createRemoteResolver` function.
45
- */
46
- export function createRemoteInterceptor(
47
- options: CreateRemoteInterceptorOptions
48
- ): InterceptorApi {
49
- invariant(
50
- process.connected,
51
- `Failed to create a remote interceptor: the current process (%s) does not have a parent. Please make sure you're spawning this process as a child process in order to use remote request interception.`,
52
- process.pid
53
- )
54
-
55
- if (typeof process.send === 'undefined') {
56
- throw new Error(
57
- `\
58
- Failed to create a remote interceptor: the current process (${process.pid}) does not have the IPC enabled. Please make sure you're spawning this process with the "ipc" stdio value set:
59
-
60
- spawn('node', ['module.js'], { stdio: ['ipc'] })\
61
- `
62
- )
63
- }
64
-
65
- let handleParentMessage: NodeJS.MessageListener
66
-
67
- const interceptor = createInterceptor({
68
- ...options,
69
- resolver(request) {
70
- const serializedRequest = JSON.stringify(request)
71
- process.send?.(`request:${serializedRequest}`)
72
-
73
- return new Promise((resolve) => {
74
- handleParentMessage = (message) => {
75
- if (typeof message !== 'string') {
76
- return
77
- }
78
-
79
- if (message.startsWith(`response:${request.id}`)) {
80
- const [, responseString] =
81
- message.match(/^response:.+?:(.+)$/) || []
82
-
83
- if (!responseString) {
84
- return resolve()
85
- }
86
-
87
- const mockedResponse = JSON.parse(responseString)
88
-
89
- return resolve(mockedResponse)
90
- }
91
- }
92
-
93
- process.addListener('message', handleParentMessage)
94
- })
95
- },
96
- })
97
-
98
- return {
99
- ...interceptor,
100
- restore() {
101
- interceptor.restore()
102
- process.removeListener('message', handleParentMessage)
103
- },
104
- }
105
- }
106
-
107
- /**
108
- * Creates a response resolver function attached to the given `ChildProcess`.
109
- * The child process must establish a remote interceptor by calling `createRemoteInterceptor` function.
110
- */
111
- export function createRemoteResolver(
112
- options: CreateRemoteResolverOptions
113
- ): RemoteResolverApi {
114
- const observer = new StrictEventEmitter<InterceptorEventsMap>()
115
-
116
- const handleChildMessage: NodeJS.MessageListener = async (message) => {
117
- if (typeof message !== 'string') {
118
- return
119
- }
120
-
121
- if (message.startsWith('request:')) {
122
- const [, requestString] = message.match(/^request:(.+)$/) || []
123
-
124
- if (!requestString) {
125
- return
126
- }
127
-
128
- const isoRequest: IsomorphicRequest = JSON.parse(
129
- requestString,
130
- requestReviver
131
- )
132
-
133
- observer.emit('request', isoRequest)
134
-
135
- // Retrieve the mocked response.
136
- const mockedResponse = await options.resolver(
137
- isoRequest,
138
- undefined as any
139
- )
140
-
141
- // Send the mocked response to the child process.
142
- const serializedResponse = JSON.stringify(mockedResponse)
143
- options.process.send(
144
- `response:${isoRequest.id}:${serializedResponse}`,
145
- (error) => {
146
- if (error) {
147
- return
148
- }
149
-
150
- if (mockedResponse) {
151
- // Emit an optimisting "response" event at this point,
152
- // not to rely on the back-and-forth signaling for the sake of the event.
153
- observer.emit('response', isoRequest, toIsoResponse(mockedResponse))
154
- }
155
- }
156
- )
157
- }
158
- }
159
-
160
- const cleanup = () => {
161
- options.process.removeListener('message', handleChildMessage)
162
- }
163
-
164
- options.process.addListener('message', handleChildMessage)
165
- options.process.addListener('disconnect', cleanup)
166
- options.process.addListener('error', cleanup)
167
- options.process.addListener('exit', cleanup)
168
-
169
- return {
170
- on(event, listener) {
171
- observer.addListener(event, listener)
172
- },
173
- }
174
- }