msw-fetch-mock 0.2.1 → 0.3.1

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.
@@ -1,140 +0,0 @@
1
- export class MockCallHistoryLog {
2
- body;
3
- method;
4
- headers;
5
- fullUrl;
6
- origin;
7
- path;
8
- searchParams;
9
- protocol;
10
- host;
11
- port;
12
- hash;
13
- constructor(data) {
14
- this.body = data.body;
15
- this.method = data.method;
16
- this.headers = data.headers;
17
- this.fullUrl = data.fullUrl;
18
- this.origin = data.origin;
19
- this.path = data.path;
20
- this.searchParams = data.searchParams;
21
- this.protocol = data.protocol;
22
- this.host = data.host;
23
- this.port = data.port;
24
- this.hash = data.hash;
25
- }
26
- json() {
27
- if (this.body === null)
28
- return null;
29
- return JSON.parse(this.body);
30
- }
31
- toMap() {
32
- return new Map([
33
- ['body', this.body],
34
- ['method', this.method],
35
- ['headers', this.headers],
36
- ['fullUrl', this.fullUrl],
37
- ['origin', this.origin],
38
- ['path', this.path],
39
- ['searchParams', this.searchParams],
40
- ['protocol', this.protocol],
41
- ['host', this.host],
42
- ['port', this.port],
43
- ['hash', this.hash],
44
- ]);
45
- }
46
- toString() {
47
- return [
48
- `method->${this.method}`,
49
- `protocol->${this.protocol}`,
50
- `host->${this.host}`,
51
- `port->${this.port}`,
52
- `origin->${this.origin}`,
53
- `path->${this.path}`,
54
- `hash->${this.hash}`,
55
- `fullUrl->${this.fullUrl}`,
56
- ].join('|');
57
- }
58
- }
59
- export class MockCallHistory {
60
- logs = [];
61
- get length() {
62
- return this.logs.length;
63
- }
64
- record(data) {
65
- this.logs.push(data instanceof MockCallHistoryLog ? data : new MockCallHistoryLog(data));
66
- }
67
- called(criteria) {
68
- if (criteria === undefined)
69
- return this.logs.length > 0;
70
- return this.filterCalls(criteria).length > 0;
71
- }
72
- calls() {
73
- return [...this.logs];
74
- }
75
- firstCall(criteria) {
76
- if (criteria === undefined)
77
- return this.logs[0];
78
- return this.filterCalls(criteria)[0];
79
- }
80
- lastCall(criteria) {
81
- if (criteria === undefined)
82
- return this.logs[this.logs.length - 1];
83
- const filtered = this.filterCalls(criteria);
84
- return filtered[filtered.length - 1];
85
- }
86
- nthCall(n, criteria) {
87
- if (criteria === undefined)
88
- return this.logs[n - 1];
89
- return this.filterCalls(criteria)[n - 1];
90
- }
91
- clear() {
92
- this.logs = [];
93
- }
94
- [Symbol.iterator]() {
95
- return this.logs[Symbol.iterator]();
96
- }
97
- filterCalls(criteria, options) {
98
- if (typeof criteria === 'function') {
99
- return this.logs.filter(criteria);
100
- }
101
- if (criteria instanceof RegExp) {
102
- return this.logs.filter((log) => criteria.test(log.toString()));
103
- }
104
- const operator = options?.operator ?? 'OR';
105
- const keys = Object.keys(criteria);
106
- const predicates = keys
107
- .filter((key) => criteria[key] !== undefined)
108
- .map((key) => (log) => log[key] === criteria[key]);
109
- if (predicates.length === 0)
110
- return [...this.logs];
111
- return this.logs.filter((log) => operator === 'AND' ? predicates.every((p) => p(log)) : predicates.some((p) => p(log)));
112
- }
113
- filterBy(field, filter) {
114
- return this.logs.filter((log) => typeof filter === 'string' ? log[field] === filter : filter.test(String(log[field])));
115
- }
116
- filterCallsByMethod(filter) {
117
- return this.filterBy('method', filter);
118
- }
119
- filterCallsByPath(filter) {
120
- return this.filterBy('path', filter);
121
- }
122
- filterCallsByOrigin(filter) {
123
- return this.filterBy('origin', filter);
124
- }
125
- filterCallsByProtocol(filter) {
126
- return this.filterBy('protocol', filter);
127
- }
128
- filterCallsByHost(filter) {
129
- return this.filterBy('host', filter);
130
- }
131
- filterCallsByPort(filter) {
132
- return this.filterBy('port', filter);
133
- }
134
- filterCallsByHash(filter) {
135
- return this.filterBy('hash', filter);
136
- }
137
- filterCallsByFullUrl(filter) {
138
- return this.filterBy('fullUrl', filter);
139
- }
140
- }
@@ -1,85 +0,0 @@
1
- import { MockCallHistory } from './mock-call-history';
2
- /** Structural type to avoid cross-package nominal type mismatch on MSW's private fields */
3
- interface SetupServerLike {
4
- use(...handlers: Array<unknown>): void;
5
- resetHandlers(...handlers: Array<unknown>): void;
6
- listen(options?: Record<string, unknown>): void;
7
- close(): void;
8
- }
9
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
10
- type PathMatcher = string | RegExp | ((path: string) => boolean);
11
- type HeaderValueMatcher = string | RegExp | ((value: string) => boolean);
12
- type BodyMatcher = string | RegExp | ((body: string) => boolean);
13
- export interface InterceptOptions {
14
- path: PathMatcher;
15
- method?: HttpMethod;
16
- headers?: Record<string, HeaderValueMatcher>;
17
- body?: BodyMatcher;
18
- query?: Record<string, string>;
19
- }
20
- export interface ReplyOptions {
21
- headers?: Record<string, string>;
22
- }
23
- type ReplyCallback = (req: {
24
- body: string | null;
25
- }) => unknown | Promise<unknown>;
26
- export interface MockReplyChain {
27
- times(n: number): void;
28
- persist(): void;
29
- delay(ms: number): void;
30
- }
31
- export interface MockInterceptor {
32
- reply(status: number, body?: unknown, options?: ReplyOptions): MockReplyChain;
33
- reply(status: number, callback: ReplyCallback): MockReplyChain;
34
- replyWithError(error: Error): MockReplyChain;
35
- }
36
- export interface MockPool {
37
- intercept(options: InterceptOptions): MockInterceptor;
38
- }
39
- export interface PendingInterceptor {
40
- origin: string;
41
- path: string;
42
- method: string;
43
- consumed: boolean;
44
- times: number;
45
- timesInvoked: number;
46
- persist: boolean;
47
- }
48
- type PrintAPI = {
49
- warning(): void;
50
- error(): void;
51
- };
52
- type OnUnhandledRequestCallback = (request: Request, print: PrintAPI) => void;
53
- export type OnUnhandledRequest = 'bypass' | 'warn' | 'error' | OnUnhandledRequestCallback;
54
- export interface ActivateOptions {
55
- onUnhandledRequest?: OnUnhandledRequest;
56
- }
57
- export declare class FetchMock {
58
- private readonly _calls;
59
- private server;
60
- private readonly ownsServer;
61
- private interceptors;
62
- private netConnectAllowed;
63
- private mswHandlers;
64
- get calls(): MockCallHistory;
65
- constructor(externalServer?: SetupServerLike);
66
- activate(options?: ActivateOptions): void;
67
- disableNetConnect(): void;
68
- enableNetConnect(matcher?: string | RegExp | ((host: string) => boolean)): void;
69
- private isNetConnectAllowed;
70
- /**
71
- * Remove consumed MSW handlers so future requests to those URLs
72
- * go through MSW's onUnhandledRequest instead of silently passing through.
73
- */
74
- private syncMswHandlers;
75
- getCallHistory(): MockCallHistory;
76
- clearCallHistory(): void;
77
- deactivate(): void;
78
- reset(): void;
79
- assertNoPendingInterceptors(): void;
80
- pendingInterceptors(): PendingInterceptor[];
81
- get(origin: string): MockPool;
82
- }
83
- export declare function createFetchMock(externalServer?: SetupServerLike): FetchMock;
84
- export {};
85
- //# sourceMappingURL=mock-server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../src/mock-server.ts"],"names":[],"mappings":"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"}
@@ -1,304 +0,0 @@
1
- import { http, HttpResponse } from 'msw';
2
- import { setupServer } from 'msw/node';
3
- import { MockCallHistory } from './mock-call-history';
4
- function isPending(p) {
5
- if (p.persist)
6
- return p.timesInvoked === 0;
7
- return p.timesInvoked < p.times;
8
- }
9
- function escapeRegExp(str) {
10
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
11
- }
12
- function matchesValue(value, matcher) {
13
- if (typeof matcher === 'string')
14
- return value === matcher;
15
- if (matcher instanceof RegExp)
16
- return matcher.test(value);
17
- return matcher(value);
18
- }
19
- function getHttpMethod(method) {
20
- const methods = {
21
- GET: http.get,
22
- POST: http.post,
23
- PUT: http.put,
24
- DELETE: http.delete,
25
- PATCH: http.patch,
26
- };
27
- return methods[method];
28
- }
29
- function matchPath(request, origin, pathMatcher) {
30
- if (typeof pathMatcher === 'string')
31
- return true; // string paths are matched by MSW URL pattern
32
- const url = new URL(request.url);
33
- const originPrefix = new URL(origin).pathname.replace(/\/$/, '');
34
- const fullPath = url.pathname + url.search;
35
- const relativePath = fullPath.startsWith(originPrefix)
36
- ? fullPath.slice(originPrefix.length)
37
- : fullPath;
38
- return matchesValue(relativePath, pathMatcher);
39
- }
40
- function matchQuery(request, query) {
41
- if (!query)
42
- return true;
43
- const url = new URL(request.url);
44
- for (const [key, value] of Object.entries(query)) {
45
- if (url.searchParams.get(key) !== value)
46
- return false;
47
- }
48
- return true;
49
- }
50
- function matchHeaders(request, headers) {
51
- if (!headers)
52
- return true;
53
- for (const [key, matcher] of Object.entries(headers)) {
54
- const value = request.headers.get(key);
55
- if (value === null || !matchesValue(value, matcher))
56
- return false;
57
- }
58
- return true;
59
- }
60
- function matchBody(bodyText, bodyMatcher) {
61
- if (!bodyMatcher)
62
- return true;
63
- return matchesValue(bodyText ?? '', bodyMatcher);
64
- }
65
- function recordCall(callHistory, request, bodyText) {
66
- const url = new URL(request.url);
67
- const requestHeaders = {};
68
- request.headers.forEach((value, key) => {
69
- requestHeaders[key] = value;
70
- });
71
- const searchParams = {};
72
- url.searchParams.forEach((value, key) => {
73
- searchParams[key] = value;
74
- });
75
- callHistory.record({
76
- body: bodyText,
77
- method: request.method,
78
- headers: requestHeaders,
79
- fullUrl: url.origin + url.pathname + url.search,
80
- origin: url.origin,
81
- path: url.pathname,
82
- searchParams,
83
- protocol: url.protocol,
84
- host: url.host,
85
- port: url.port,
86
- hash: url.hash,
87
- });
88
- }
89
- function buildResponse(status, responseBody, replyOptions) {
90
- const headers = replyOptions?.headers ? new Headers(replyOptions.headers) : undefined;
91
- if (responseBody === null || responseBody === undefined) {
92
- return new HttpResponse(null, { status, headers });
93
- }
94
- return HttpResponse.json(responseBody, { status, headers });
95
- }
96
- export class FetchMock {
97
- _calls = new MockCallHistory();
98
- server;
99
- ownsServer;
100
- interceptors = [];
101
- netConnectAllowed = false;
102
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
- mswHandlers = new Map();
104
- get calls() {
105
- return this._calls;
106
- }
107
- constructor(externalServer) {
108
- this.server = externalServer ?? null;
109
- this.ownsServer = !externalServer;
110
- }
111
- activate(options) {
112
- if (this.ownsServer) {
113
- const isPatched = Object.getOwnPropertySymbols(globalThis.fetch).some((s) => s.description === 'isPatchedModule');
114
- if (isPatched) {
115
- throw new Error('Another MSW server is already active. ' +
116
- 'Pass your existing server to new FetchMock(server) instead.');
117
- }
118
- const mode = options?.onUnhandledRequest ?? 'error';
119
- this.server = setupServer();
120
- this.server.listen({
121
- onUnhandledRequest: (request, print) => {
122
- if (this.isNetConnectAllowed(request))
123
- return;
124
- if (typeof mode === 'function') {
125
- mode(request, print);
126
- }
127
- else if (mode === 'error') {
128
- print.error();
129
- }
130
- else if (mode === 'warn') {
131
- print.warning();
132
- }
133
- // 'bypass' → do nothing
134
- },
135
- });
136
- }
137
- }
138
- disableNetConnect() {
139
- this.netConnectAllowed = false;
140
- }
141
- enableNetConnect(matcher) {
142
- this.netConnectAllowed = matcher ?? true;
143
- }
144
- isNetConnectAllowed(request) {
145
- if (this.netConnectAllowed === true)
146
- return true;
147
- if (this.netConnectAllowed === false)
148
- return false;
149
- const host = new URL(request.url).host;
150
- if (typeof this.netConnectAllowed === 'string')
151
- return host === this.netConnectAllowed;
152
- if (this.netConnectAllowed instanceof RegExp)
153
- return this.netConnectAllowed.test(host);
154
- return this.netConnectAllowed(host);
155
- }
156
- /**
157
- * Remove consumed MSW handlers so future requests to those URLs
158
- * go through MSW's onUnhandledRequest instead of silently passing through.
159
- */
160
- syncMswHandlers() {
161
- if (!this.server || !this.ownsServer)
162
- return;
163
- const activeHandlers = [...this.mswHandlers.entries()]
164
- .filter(([p]) => !p.consumed || p.persist)
165
- .map(([, handler]) => handler);
166
- this.server.resetHandlers(...activeHandlers);
167
- }
168
- getCallHistory() {
169
- return this._calls;
170
- }
171
- clearCallHistory() {
172
- this._calls.clear();
173
- }
174
- deactivate() {
175
- this.interceptors = [];
176
- this.mswHandlers.clear();
177
- this._calls.clear();
178
- if (this.ownsServer) {
179
- this.server?.close();
180
- this.server = null;
181
- }
182
- }
183
- reset() {
184
- this.interceptors = [];
185
- this.mswHandlers.clear();
186
- this._calls.clear();
187
- if (this.ownsServer) {
188
- this.server?.resetHandlers();
189
- }
190
- }
191
- assertNoPendingInterceptors() {
192
- const unconsumed = this.interceptors.filter(isPending);
193
- if (unconsumed.length > 0) {
194
- const descriptions = unconsumed.map((p) => ` ${p.method} ${p.origin}${p.path}`);
195
- throw new Error(`Pending interceptor(s) not consumed:\n${descriptions.join('\n')}`);
196
- }
197
- }
198
- pendingInterceptors() {
199
- return this.interceptors.filter(isPending).map((p) => ({ ...p }));
200
- }
201
- get(origin) {
202
- return {
203
- intercept: (options) => {
204
- const method = options.method ?? 'GET';
205
- const pathStr = typeof options.path === 'string'
206
- ? options.path
207
- : typeof options.path === 'function'
208
- ? '<function>'
209
- : options.path.toString();
210
- const pending = {
211
- origin,
212
- path: pathStr,
213
- method,
214
- consumed: false,
215
- times: 1,
216
- timesInvoked: 0,
217
- persist: false,
218
- };
219
- this.interceptors.push(pending);
220
- const urlPattern = typeof options.path === 'string'
221
- ? `${origin}${options.path}`
222
- : new RegExp(`^${escapeRegExp(origin)}`);
223
- const matchAndConsume = async (request) => {
224
- if (!pending.persist && pending.timesInvoked >= pending.times)
225
- return;
226
- if (!matchPath(request, origin, options.path))
227
- return;
228
- if (!matchQuery(request, options.query))
229
- return;
230
- if (!matchHeaders(request, options.headers))
231
- return;
232
- const bodyText = (await request.text()) || null;
233
- if (!matchBody(bodyText, options.body))
234
- return;
235
- pending.timesInvoked++;
236
- if (!pending.persist && pending.timesInvoked >= pending.times) {
237
- pending.consumed = true;
238
- this.syncMswHandlers();
239
- }
240
- recordCall(this._calls, request, bodyText);
241
- return bodyText;
242
- };
243
- const registerHandler = (handlerFn) => {
244
- const handler = getHttpMethod(method)(urlPattern, async ({ request }) => handlerFn(request));
245
- if (!this.server) {
246
- throw new Error('FetchMock server is not active. Call activate() before registering interceptors.');
247
- }
248
- this.mswHandlers.set(pending, handler);
249
- this.server.use(handler);
250
- };
251
- const buildChain = (delayRef) => ({
252
- times(n) {
253
- pending.times = n;
254
- pending.consumed = false;
255
- },
256
- persist() {
257
- pending.persist = true;
258
- pending.consumed = false;
259
- },
260
- delay(ms) {
261
- delayRef.ms = ms;
262
- },
263
- });
264
- return {
265
- reply: (status, bodyOrCallback, replyOptions) => {
266
- const delayRef = { ms: 0 };
267
- registerHandler(async (request) => {
268
- const bodyText = await matchAndConsume(request);
269
- if (bodyText === undefined)
270
- return;
271
- if (delayRef.ms > 0) {
272
- await new Promise((resolve) => setTimeout(resolve, delayRef.ms));
273
- }
274
- let responseBody;
275
- if (typeof bodyOrCallback === 'function') {
276
- responseBody = await bodyOrCallback({
277
- body: bodyText || null,
278
- });
279
- }
280
- else {
281
- responseBody = bodyOrCallback;
282
- }
283
- return buildResponse(status, responseBody, replyOptions);
284
- });
285
- return buildChain(delayRef);
286
- },
287
- replyWithError: () => {
288
- const delayRef = { ms: 0 };
289
- registerHandler(async (request) => {
290
- const bodyText = await matchAndConsume(request);
291
- if (bodyText === undefined)
292
- return;
293
- return HttpResponse.error();
294
- });
295
- return buildChain(delayRef);
296
- },
297
- };
298
- },
299
- };
300
- }
301
- }
302
- export function createFetchMock(externalServer) {
303
- return new FetchMock(externalServer);
304
- }