msw-fetch-mock 0.3.3 → 0.4.0

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.
package/README.md CHANGED
@@ -4,16 +4,18 @@
4
4
  [![npm version](https://img.shields.io/npm/v/msw-fetch-mock.svg)](https://www.npmjs.com/package/msw-fetch-mock)
5
5
  [![license](https://img.shields.io/npm/l/msw-fetch-mock.svg)](https://github.com/recca0120/msw-fetch-mock/blob/main/LICENSE.md)
6
6
 
7
+ [English](README.md) | [繁體中文](README.zh-TW.md)
8
+
7
9
  Undici-style fetch mock API built on [MSW](https://mswjs.io/) (Mock Service Worker).
8
10
 
9
11
  If you're familiar with Cloudflare Workers' `fetchMock` (from `cloudflare:test`) or Node.js undici's `MockAgent`, you already know this API.
10
12
 
11
- Supports both **Node.js** (`msw/node`) and **Browser** (`msw/browser`) environments via subpath exports.
13
+ Supports **Node.js** (`msw/node`), **Browser** (`msw/browser`), and **Native** (no MSW dependency) environments via subpath exports.
12
14
 
13
15
  ## Requirements
14
16
 
15
17
  - **Node.js** >= 18
16
- - **MSW** ^1.0.0 (via `/legacy`) or ^2.12.7
18
+ - **MSW** ^1.0.0 (via `/legacy`) or ^2.12.7 — **optional** when using `/native`
17
19
 
18
20
  ## Install
19
21
 
@@ -23,12 +25,18 @@ npm install -D msw-fetch-mock msw
23
25
 
24
26
  `msw` is a peer dependency — you provide your own version.
25
27
 
28
+ For MSW-free usage (patches `globalThis.fetch` directly):
29
+
30
+ ```bash
31
+ npm install -D msw-fetch-mock
32
+ ```
33
+
26
34
  ## Quick Start
27
35
 
28
36
  ### Node.js (Vitest, Jest)
29
37
 
30
38
  ```typescript
31
- // Works with default import or explicit /node subpath
39
+ // Works with root import or explicit /node subpath
32
40
  import { fetchMock } from 'msw-fetch-mock';
33
41
  // import { fetchMock } from 'msw-fetch-mock/node';
34
42
 
@@ -78,11 +86,10 @@ If you already use MSW, pass your server to share a single interceptor:
78
86
  ```typescript
79
87
  import { setupServer } from 'msw/node';
80
88
  import { http, HttpResponse } from 'msw';
81
- import { FetchMock } from 'msw-fetch-mock';
82
- import { NodeMswAdapter } from 'msw-fetch-mock/node';
89
+ import { createFetchMock } from 'msw-fetch-mock';
83
90
 
84
91
  const server = setupServer(http.get('/api/users', () => HttpResponse.json([{ id: 1 }])));
85
- const fetchMock = new FetchMock(new NodeMswAdapter(server));
92
+ const fetchMock = createFetchMock(server);
86
93
 
87
94
  beforeAll(() => server.listen());
88
95
  afterAll(() => server.close());
@@ -92,7 +99,26 @@ afterEach(() => {
92
99
  });
93
100
  ```
94
101
 
95
- > **Note:** Only one MSW server can be active at a time. If another server is already listening, standalone `activate()` will throw an error guiding you to use `new FetchMock(new NodeMswAdapter(server))` instead.
102
+ > **Note:** Only one MSW server can be active at a time. If a server is already listening, standalone `activate()` will throw an error. Use `createFetchMock(server)` to share an existing server.
103
+
104
+ ### Native (no MSW dependency)
105
+
106
+ For environments where you don't want to install MSW, the `/native` subpath patches `globalThis.fetch` directly:
107
+
108
+ ```typescript
109
+ import { fetchMock } from 'msw-fetch-mock/native';
110
+
111
+ beforeAll(async () => {
112
+ await fetchMock.activate({ onUnhandledRequest: 'error' });
113
+ });
114
+ afterAll(() => fetchMock.deactivate());
115
+ afterEach(() => {
116
+ fetchMock.assertNoPendingInterceptors();
117
+ fetchMock.reset();
118
+ });
119
+ ```
120
+
121
+ The API is identical — only the underlying transport changes (no Service Worker, no MSW server).
96
122
 
97
123
  ### Legacy (MSW v1)
98
124
 
@@ -144,12 +170,13 @@ fetchMock.activate({
144
170
 
145
171
  ### Import Paths
146
172
 
147
- | Path | Environment | MSW version |
148
- | ------------------------ | ---------------------------- | ----------- |
149
- | `msw-fetch-mock` | Node.js (re-exports `/node`) | v2 |
150
- | `msw-fetch-mock/node` | Node.js | v2 |
151
- | `msw-fetch-mock/browser` | Browser | v2 |
152
- | `msw-fetch-mock/legacy` | Node.js (MSW v1) | v1 |
173
+ | Path | Environment | MSW version |
174
+ | ------------------------ | ---------------------------- | ------------ |
175
+ | `msw-fetch-mock` | Node.js (re-exports `/node`) | v2 |
176
+ | `msw-fetch-mock/node` | Node.js | v2 |
177
+ | `msw-fetch-mock/browser` | Browser | v2 |
178
+ | `msw-fetch-mock/native` | Any (no MSW) | not required |
179
+ | `msw-fetch-mock/legacy` | Node.js (MSW v1) | v1 |
153
180
 
154
181
  ### `fetchMock` (singleton)
155
182
 
@@ -162,11 +189,12 @@ Factory function that creates a `FetchMock` with the appropriate adapter.
162
189
 
163
190
  - Node: `createFetchMock(server?)` — optionally pass an existing MSW `SetupServer`
164
191
  - Browser: `createFetchMock(worker)` — pass an MSW `SetupWorker` (required)
192
+ - Native: `createFetchMock()` — no arguments, no MSW dependency
165
193
  - Legacy: `createFetchMock(rest, server?)` — pass MSW v1 `rest` object
166
194
 
167
195
  ### `new FetchMock(adapter?)`
168
196
 
169
- Creates a `FetchMock` instance with an explicit `MswAdapter`. Use `NodeMswAdapter` or `BrowserMswAdapter`.
197
+ Creates a `FetchMock` instance with an explicit `MswAdapter`. Use `NodeMswAdapter`, `BrowserMswAdapter`, or `NativeFetchAdapter`.
170
198
 
171
199
  ### Intercepting & Replying
172
200
 
@@ -204,6 +232,9 @@ E2E tests run on every CI push across these environments:
204
232
  | Jest CJS | CJS (require) | Jest |
205
233
  | Node.js Test | ESM (import) | Node test runner |
206
234
  | Node.js CJS | CJS (require) | Node test runner |
235
+ | Native ESM | ESM (import) | Node test runner |
236
+ | Native CJS | CJS (require) | Node test runner |
237
+ | Legacy CJS | CJS (require) | Jest (MSW v1) |
207
238
  | Vitest Browser | ESM (import) | Vitest + Playwright |
208
239
 
209
240
  ## Documentation
@@ -236,7 +267,7 @@ pnpm test:e2e -- node-cjs
236
267
  pnpm test:e2e -- --all
237
268
  ```
238
269
 
239
- Available suites: `jest-esm`, `jest-cjs`, `node-test`, `node-cjs`, `vitest-browser`
270
+ Available suites: `jest-esm`, `jest-cjs`, `node-test`, `node-cjs`, `native-esm`, `native-cjs`, `legacy-cjs`, `vitest-browser`
240
271
 
241
272
  ## License
242
273
 
@@ -0,0 +1,274 @@
1
+ # msw-fetch-mock
2
+
3
+ [![CI](https://github.com/recca0120/msw-fetch-mock/actions/workflows/ci.yml/badge.svg)](https://github.com/recca0120/msw-fetch-mock/actions/workflows/ci.yml)
4
+ [![npm version](https://img.shields.io/npm/v/msw-fetch-mock.svg)](https://www.npmjs.com/package/msw-fetch-mock)
5
+ [![license](https://img.shields.io/npm/l/msw-fetch-mock.svg)](https://github.com/recca0120/msw-fetch-mock/blob/main/LICENSE.md)
6
+
7
+ [English](README.md) | [繁體中文](README.zh-TW.md)
8
+
9
+ 基於 [MSW](https://mswjs.io/)(Mock Service Worker)的 Undici 風格 fetch mock API。
10
+
11
+ 如果你熟悉 Cloudflare Workers 的 `fetchMock`(來自 `cloudflare:test`)或 Node.js undici 的 `MockAgent`,你已經會使用這個 API 了。
12
+
13
+ 透過 subpath exports 支援 **Node.js**(`msw/node`)、**瀏覽器**(`msw/browser`)和**原生**(無 MSW 依賴)環境。
14
+
15
+ ## 系統需求
16
+
17
+ - **Node.js** >= 18
18
+ - **MSW** ^1.0.0(透過 `/legacy`)或 ^2.12.7 — 使用 `/native` 時**可選**
19
+
20
+ ## 安裝
21
+
22
+ ```bash
23
+ npm install -D msw-fetch-mock msw
24
+ ```
25
+
26
+ `msw` 是 peer dependency — 需要自行安裝你的版本。
27
+
28
+ 若不需要 MSW(直接 patch `globalThis.fetch`):
29
+
30
+ ```bash
31
+ npm install -D msw-fetch-mock
32
+ ```
33
+
34
+ ## 快速開始
35
+
36
+ ### Node.js(Vitest、Jest)
37
+
38
+ ```typescript
39
+ // 可使用根路徑匯入或明確的 /node 子路徑
40
+ import { fetchMock } from 'msw-fetch-mock';
41
+ // import { fetchMock } from 'msw-fetch-mock/node';
42
+
43
+ beforeAll(() => fetchMock.activate({ onUnhandledRequest: 'error' }));
44
+ afterAll(() => fetchMock.deactivate());
45
+ afterEach(() => {
46
+ fetchMock.assertNoPendingInterceptors();
47
+ fetchMock.reset();
48
+ });
49
+
50
+ it('模擬 GET 請求', async () => {
51
+ fetchMock
52
+ .get('https://api.example.com')
53
+ .intercept({ path: '/users', method: 'GET' })
54
+ .reply(200, { users: [{ id: '1', name: 'Alice' }] });
55
+
56
+ const res = await fetch('https://api.example.com/users');
57
+ const data = await res.json();
58
+
59
+ expect(data.users).toHaveLength(1);
60
+ });
61
+ ```
62
+
63
+ ### 瀏覽器(Storybook、Vitest Browser Mode)
64
+
65
+ ```typescript
66
+ import { setupWorker } from 'msw/browser';
67
+ import { createFetchMock } from 'msw-fetch-mock/browser';
68
+
69
+ const worker = setupWorker();
70
+ const fetchMock = createFetchMock(worker);
71
+
72
+ beforeAll(async () => {
73
+ await fetchMock.activate({ onUnhandledRequest: 'error' });
74
+ });
75
+ afterAll(() => fetchMock.deactivate());
76
+ afterEach(() => {
77
+ fetchMock.assertNoPendingInterceptors();
78
+ fetchMock.reset();
79
+ });
80
+ ```
81
+
82
+ ### 搭配現有的 MSW server
83
+
84
+ 如果你已經在使用 MSW,可以傳入你的 server 來共用同一個攔截器:
85
+
86
+ ```typescript
87
+ import { setupServer } from 'msw/node';
88
+ import { http, HttpResponse } from 'msw';
89
+ import { createFetchMock } from 'msw-fetch-mock';
90
+
91
+ const server = setupServer(http.get('/api/users', () => HttpResponse.json([{ id: 1 }])));
92
+ const fetchMock = createFetchMock(server);
93
+
94
+ beforeAll(() => server.listen());
95
+ afterAll(() => server.close());
96
+ afterEach(() => {
97
+ server.resetHandlers();
98
+ fetchMock.assertNoPendingInterceptors();
99
+ });
100
+ ```
101
+
102
+ > **注意:** 同一時間只能有一個 MSW server 處於啟動狀態。如果已有 server 在監聽中,獨立模式的 `activate()` 會拋出錯誤。請使用 `createFetchMock(server)` 來共用現有的 server。
103
+
104
+ ### 原生模式(無 MSW 依賴)
105
+
106
+ 若不想安裝 MSW,`/native` 子路徑會直接 patch `globalThis.fetch`:
107
+
108
+ ```typescript
109
+ import { fetchMock } from 'msw-fetch-mock/native';
110
+
111
+ beforeAll(async () => {
112
+ await fetchMock.activate({ onUnhandledRequest: 'error' });
113
+ });
114
+ afterAll(() => fetchMock.deactivate());
115
+ afterEach(() => {
116
+ fetchMock.assertNoPendingInterceptors();
117
+ fetchMock.reset();
118
+ });
119
+ ```
120
+
121
+ API 完全相同 — 只有底層傳輸方式不同(無 Service Worker、無 MSW server)。
122
+
123
+ ### Legacy(MSW v1)
124
+
125
+ ```typescript
126
+ import { rest } from 'msw';
127
+ import { setupServer } from 'msw/node';
128
+ import { createFetchMock } from 'msw-fetch-mock/legacy';
129
+
130
+ const server = setupServer();
131
+ const fetchMock = createFetchMock(rest, server);
132
+
133
+ beforeAll(() => fetchMock.activate());
134
+ afterAll(() => fetchMock.deactivate());
135
+ afterEach(() => {
136
+ fetchMock.assertNoPendingInterceptors();
137
+ fetchMock.reset();
138
+ });
139
+ ```
140
+
141
+ 詳見 [MSW v1 Legacy 指南](docs/msw-v1-legacy.zh-TW.md)。
142
+
143
+ ## 未處理的請求
144
+
145
+ 預設情況下 `activate()` 使用 `'error'` 模式 — 未匹配的請求會導致 `fetch()` 拒絕。這包含對**已消耗**攔截器的請求(一次性攔截器使用後,其 handler 會從 MSW 中移除)。
146
+
147
+ ```typescript
148
+ // 拒絕未匹配的請求(預設行為)
149
+ fetchMock.activate();
150
+ fetchMock.activate({ onUnhandledRequest: 'error' });
151
+
152
+ // 記錄警告但允許通過
153
+ fetchMock.activate({ onUnhandledRequest: 'warn' });
154
+
155
+ // 靜默允許通過
156
+ fetchMock.activate({ onUnhandledRequest: 'bypass' });
157
+
158
+ // 自訂回呼
159
+ fetchMock.activate({
160
+ onUnhandledRequest: (request, print) => {
161
+ if (request.url.includes('/health')) return; // 忽略
162
+ print.error(); // 阻擋其他所有請求
163
+ },
164
+ });
165
+ ```
166
+
167
+ > `enableNetConnect()` 的優先順序高於 `onUnhandledRequest` — 允許的主機一律直接通過。
168
+
169
+ ## API 概覽
170
+
171
+ ### 匯入路徑
172
+
173
+ | 路徑 | 環境 | MSW 版本 |
174
+ | ------------------------ | ----------------------------- | -------- |
175
+ | `msw-fetch-mock` | Node.js(re-exports `/node`) | v2 |
176
+ | `msw-fetch-mock/node` | Node.js | v2 |
177
+ | `msw-fetch-mock/browser` | 瀏覽器 | v2 |
178
+ | `msw-fetch-mock/native` | 任何環境(無 MSW) | 不需要 |
179
+ | `msw-fetch-mock/legacy` | Node.js(MSW v1) | v1 |
180
+
181
+ ### `fetchMock`(單例)
182
+
183
+ 預先建立的 `FetchMock` 實例,適用於獨立使用。匯入後直接呼叫 `activate()` 即可 — 無需額外設定。
184
+ 可從 `msw-fetch-mock` 和 `msw-fetch-mock/node` 匯入。
185
+
186
+ ### `createFetchMock(server?)` / `createFetchMock(worker)`
187
+
188
+ 建立 `FetchMock` 的工廠函式,會自動搭配對應的 adapter。
189
+
190
+ - Node:`createFetchMock(server?)` — 可選擇性傳入現有的 MSW `SetupServer`
191
+ - 瀏覽器:`createFetchMock(worker)` — 傳入 MSW `SetupWorker`(必要)
192
+ - 原生:`createFetchMock()` — 無需參數,無 MSW 依賴
193
+ - Legacy:`createFetchMock(rest, server?)` — 傳入 MSW v1 的 `rest` 物件
194
+
195
+ ### `new FetchMock(adapter?)`
196
+
197
+ 使用明確的 `MswAdapter` 建立 `FetchMock` 實例。可使用 `NodeMswAdapter`、`BrowserMswAdapter` 或 `NativeFetchAdapter`。
198
+
199
+ ### 攔截與回應
200
+
201
+ ```typescript
202
+ fetchMock
203
+ .get(origin) // string、RegExp 或 function
204
+ .intercept({ path, method, headers, body, query }) // 匹配條件
205
+ .reply(status, body, options) // 定義回應
206
+ .times(n) / .persist(); // 重複控制
207
+ ```
208
+
209
+ ### 呼叫歷史
210
+
211
+ ```typescript
212
+ fetchMock.calls.lastCall(); // 最近一次
213
+ fetchMock.calls.firstCall(); // 最早一次
214
+ fetchMock.calls.nthCall(2); // 第 2 次呼叫(1-indexed)
215
+ fetchMock.calls.filterCalls({ method: 'POST', path: '/users' }, { operator: 'AND' });
216
+ ```
217
+
218
+ ### 斷言與清理
219
+
220
+ ```typescript
221
+ fetchMock.assertNoPendingInterceptors(); // 若有未消耗的攔截器則拋出錯誤
222
+ fetchMock.reset(); // 清除攔截器 + 呼叫歷史 + handlers
223
+ ```
224
+
225
+ ## 測試環境
226
+
227
+ 每次 CI 推送都會在以下環境執行 E2E 測試:
228
+
229
+ | 環境 | 模組系統 | 測試框架 |
230
+ | -------------- | ------------- | ------------------- |
231
+ | Jest ESM | ESM (import) | Jest |
232
+ | Jest CJS | CJS (require) | Jest |
233
+ | Node.js Test | ESM (import) | Node test runner |
234
+ | Node.js CJS | CJS (require) | Node test runner |
235
+ | Native ESM | ESM (import) | Node test runner |
236
+ | Native CJS | CJS (require) | Node test runner |
237
+ | Legacy CJS | CJS (require) | Jest (MSW v1) |
238
+ | Vitest Browser | ESM (import) | Vitest + Playwright |
239
+
240
+ ## 文件
241
+
242
+ - [API 參考](docs/api.zh-TW.md) — 完整的 API 細節、匹配選項、回應回呼
243
+ - [Cloudflare Workers 遷移指南](docs/cloudflare-migration.zh-TW.md) — 從 `cloudflare:test` fetchMock 遷移
244
+ - [MSW v1 Legacy 指南](docs/msw-v1-legacy.zh-TW.md) — 搭配 MSW v1 使用 msw-fetch-mock
245
+
246
+ ## 開發
247
+
248
+ ```bash
249
+ pnpm install
250
+ pnpm build # 使用 tsup 建置
251
+ pnpm test # 單元測試(vitest)
252
+ pnpm test:e2e # E2E 測試(jest-esm、jest-cjs、node-test、node-cjs、legacy-cjs)
253
+ ```
254
+
255
+ ### E2E 測試
256
+
257
+ E2E 測試驗證已發佈的套件能在不同 runtime 和模組系統下正常運作。腳本會建置、透過 `npm pack` 打包 tarball,然後安裝到每個 `e2e/` 專案中 — 完全模擬 CI 流程。
258
+
259
+ ```bash
260
+ # 執行預設套組(跳過 vitest-browser)
261
+ pnpm test:e2e
262
+
263
+ # 執行單一套組
264
+ pnpm test:e2e -- node-cjs
265
+
266
+ # 執行所有套組,包含 vitest-browser(會自動安裝 Playwright)
267
+ pnpm test:e2e -- --all
268
+ ```
269
+
270
+ 可用套組:`jest-esm`、`jest-cjs`、`node-test`、`node-cjs`、`native-esm`、`native-cjs`、`legacy-cjs`、`vitest-browser`
271
+
272
+ ## 授權
273
+
274
+ [MIT](LICENSE.md)
package/dist/browser.cjs CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
  var _chunkLVGXTY6Jcjs = require('./chunk-LVGXTY6J.cjs');
4
+ require('./chunk-3RE2WWHX.cjs');
4
5
 
5
6
 
6
7
 
7
8
 
8
- var _chunkN6B7UP6Bcjs = require('./chunk-N6B7UP6B.cjs');
9
+ var _chunkVUNESK75cjs = require('./chunk-VUNESK75.cjs');
9
10
 
10
11
  // src/browser-adapter.ts
11
12
  var BrowserMswAdapter = class {
@@ -30,9 +31,9 @@ var BrowserMswAdapter = class {
30
31
  };
31
32
 
32
33
  // src/browser.ts
33
- _chunkN6B7UP6Bcjs.FetchMock._handlerFactory = _chunkLVGXTY6Jcjs.HandlerFactory;
34
+ _chunkVUNESK75cjs.FetchMock._handlerFactory = _chunkLVGXTY6Jcjs.HandlerFactory;
34
35
  function createFetchMock(worker) {
35
- return new (0, _chunkN6B7UP6Bcjs.FetchMock)(new BrowserMswAdapter(worker));
36
+ return new (0, _chunkVUNESK75cjs.FetchMock)(new BrowserMswAdapter(worker));
36
37
  }
37
38
 
38
39
 
@@ -40,4 +41,4 @@ function createFetchMock(worker) {
40
41
 
41
42
 
42
43
 
43
- exports.BrowserMswAdapter = BrowserMswAdapter; exports.FetchMock = _chunkN6B7UP6Bcjs.FetchMock; exports.MockCallHistory = _chunkN6B7UP6Bcjs.MockCallHistory; exports.MockCallHistoryLog = _chunkN6B7UP6Bcjs.MockCallHistoryLog; exports.createFetchMock = createFetchMock;
44
+ exports.BrowserMswAdapter = BrowserMswAdapter; exports.FetchMock = _chunkVUNESK75cjs.FetchMock; exports.MockCallHistory = _chunkVUNESK75cjs.MockCallHistory; exports.MockCallHistoryLog = _chunkVUNESK75cjs.MockCallHistoryLog; exports.createFetchMock = createFetchMock;
@@ -1,5 +1,5 @@
1
- import { M as MswAdapter, S as SetupWorkerLike, R as ResolvedActivateOptions, F as FetchMock } from './fetch-mock-DhiqmHdF.cjs';
2
- export { A as ActivateOptions, C as CallHistoryFilterCriteria, H as HandlerFactory, I as InterceptOptions, a as MockCallHistory, b as MockCallHistoryLog, c as MockCallHistoryLogData, d as MockInterceptor, e as MockPool, f as MockReplyChain, O as OnUnhandledRequest, P as PendingInterceptor, g as ReplyOptions } from './fetch-mock-DhiqmHdF.cjs';
1
+ import { M as MswAdapter, S as SetupWorkerLike, R as ResolvedActivateOptions, F as FetchMock } from './fetch-mock-1oOS8WUJ.cjs';
2
+ export { A as ActivateOptions, C as CallHistoryFilterCriteria, H as HandlerFactory, I as InterceptOptions, a as MockCallHistory, b as MockCallHistoryLog, c as MockCallHistoryLogData, d as MockInterceptor, e as MockPool, f as MockReplyChain, O as OnUnhandledRequest, P as PendingInterceptor, g as ReplyCallback, h as ReplyOptions, i as SingleReplyCallback, j as SingleReplyResult } from './fetch-mock-1oOS8WUJ.cjs';
3
3
 
4
4
  declare class BrowserMswAdapter implements MswAdapter {
5
5
  private readonly worker;
package/dist/browser.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MswAdapter, S as SetupWorkerLike, R as ResolvedActivateOptions, F as FetchMock } from './fetch-mock-DhiqmHdF.js';
2
- export { A as ActivateOptions, C as CallHistoryFilterCriteria, H as HandlerFactory, I as InterceptOptions, a as MockCallHistory, b as MockCallHistoryLog, c as MockCallHistoryLogData, d as MockInterceptor, e as MockPool, f as MockReplyChain, O as OnUnhandledRequest, P as PendingInterceptor, g as ReplyOptions } from './fetch-mock-DhiqmHdF.js';
1
+ import { M as MswAdapter, S as SetupWorkerLike, R as ResolvedActivateOptions, F as FetchMock } from './fetch-mock-1oOS8WUJ.js';
2
+ export { A as ActivateOptions, C as CallHistoryFilterCriteria, H as HandlerFactory, I as InterceptOptions, a as MockCallHistory, b as MockCallHistoryLog, c as MockCallHistoryLogData, d as MockInterceptor, e as MockPool, f as MockReplyChain, O as OnUnhandledRequest, P as PendingInterceptor, g as ReplyCallback, h as ReplyOptions, i as SingleReplyCallback, j as SingleReplyResult } from './fetch-mock-1oOS8WUJ.js';
3
3
 
4
4
  declare class BrowserMswAdapter implements MswAdapter {
5
5
  private readonly worker;
package/dist/browser.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  HandlerFactory
3
3
  } from "./chunk-KGCQG4D2.js";
4
+ import "./chunk-GZFGTCZB.js";
4
5
  import {
5
6
  FetchMock,
6
7
  MockCallHistory,
7
8
  MockCallHistoryLog
8
- } from "./chunk-3RAWYKAG.js";
9
+ } from "./chunk-3XFP4NAO.js";
9
10
 
10
11
  // src/browser-adapter.ts
11
12
  var BrowserMswAdapter = class {
@@ -3,7 +3,7 @@
3
3
  var _chunkLVGXTY6Jcjs = require('./chunk-LVGXTY6J.cjs');
4
4
 
5
5
 
6
- var _chunkN6B7UP6Bcjs = require('./chunk-N6B7UP6B.cjs');
6
+ var _chunkVUNESK75cjs = require('./chunk-VUNESK75.cjs');
7
7
 
8
8
  // src/node-adapter.ts
9
9
  var _node = require('msw/node');
@@ -44,10 +44,10 @@ var NodeMswAdapter = class {
44
44
  };
45
45
 
46
46
  // src/node.ts
47
- _chunkN6B7UP6Bcjs.FetchMock._defaultAdapterFactory = () => new NodeMswAdapter();
48
- _chunkN6B7UP6Bcjs.FetchMock._handlerFactory = _chunkLVGXTY6Jcjs.HandlerFactory;
47
+ _chunkVUNESK75cjs.FetchMock._defaultAdapterFactory = () => new NodeMswAdapter();
48
+ _chunkVUNESK75cjs.FetchMock._handlerFactory = _chunkLVGXTY6Jcjs.HandlerFactory;
49
49
  function createFetchMock(server) {
50
- return new (0, _chunkN6B7UP6Bcjs.FetchMock)(new NodeMswAdapter(server));
50
+ return new (0, _chunkVUNESK75cjs.FetchMock)(new NodeMswAdapter(server));
51
51
  }
52
52
  var fetchMock = createFetchMock();
53
53
 
@@ -0,0 +1 @@
1
+ "use strict";
@@ -28,6 +28,10 @@ var MockCallHistoryLog = class {
28
28
  if (this.body === null) return null;
29
29
  return JSON.parse(this.body);
30
30
  }
31
+ /**
32
+ * Returns a Map representation of this call log.
33
+ * Provided for compatibility with the `cloudflare:test` fetchMock API.
34
+ */
31
35
  toMap() {
32
36
  return /* @__PURE__ */ new Map([
33
37
  ["body", this.body],
@@ -43,6 +47,10 @@ var MockCallHistoryLog = class {
43
47
  ["hash", this.hash]
44
48
  ]);
45
49
  }
50
+ /**
51
+ * Returns a pipe-separated string representation of this call log.
52
+ * Provided for compatibility with the `cloudflare:test` fetchMock API.
53
+ */
46
54
  toString() {
47
55
  return [
48
56
  `method->${this.method}`,
@@ -105,32 +113,47 @@ var MockCallHistory = class {
105
113
  (log) => operator === "AND" ? predicates.every((p) => p(log)) : predicates.some((p) => p(log))
106
114
  );
107
115
  }
116
+ /**
117
+ * Filter helper — matches a single field by exact string or RegExp.
118
+ *
119
+ * The `filterCallsByXxx` methods below mirror the `cloudflare:test` fetchMock
120
+ * API so that tests written for Cloudflare Workers can be reused with this library
121
+ * without modification.
122
+ */
108
123
  filterBy(field, filter) {
109
124
  return this.logs.filter(
110
125
  (log) => typeof filter === "string" ? log[field] === filter : filter.test(String(log[field]))
111
126
  );
112
127
  }
128
+ /** Filter calls by HTTP method. Mirrors `cloudflare:test` fetchMock API. */
113
129
  filterCallsByMethod(filter) {
114
130
  return this.filterBy("method", filter);
115
131
  }
132
+ /** Filter calls by path. Mirrors `cloudflare:test` fetchMock API. */
116
133
  filterCallsByPath(filter) {
117
134
  return this.filterBy("path", filter);
118
135
  }
136
+ /** Filter calls by origin. Mirrors `cloudflare:test` fetchMock API. */
119
137
  filterCallsByOrigin(filter) {
120
138
  return this.filterBy("origin", filter);
121
139
  }
140
+ /** Filter calls by protocol. Mirrors `cloudflare:test` fetchMock API. */
122
141
  filterCallsByProtocol(filter) {
123
142
  return this.filterBy("protocol", filter);
124
143
  }
144
+ /** Filter calls by host. Mirrors `cloudflare:test` fetchMock API. */
125
145
  filterCallsByHost(filter) {
126
146
  return this.filterBy("host", filter);
127
147
  }
148
+ /** Filter calls by port. Mirrors `cloudflare:test` fetchMock API. */
128
149
  filterCallsByPort(filter) {
129
150
  return this.filterBy("port", filter);
130
151
  }
152
+ /** Filter calls by URL hash. Mirrors `cloudflare:test` fetchMock API. */
131
153
  filterCallsByHash(filter) {
132
154
  return this.filterBy("hash", filter);
133
155
  }
156
+ /** Filter calls by full URL. Mirrors `cloudflare:test` fetchMock API. */
134
157
  filterCallsByFullUrl(filter) {
135
158
  return this.filterBy("fullUrl", filter);
136
159
  }
@@ -327,12 +350,19 @@ var FetchMock = class _FetchMock {
327
350
  const activeHandlers = [...this.mswHandlers.entries()].filter(([p]) => !p.consumed || p.persist).map(([, handler]) => handler);
328
351
  this.adapter.resetHandlers(...activeHandlers);
329
352
  }
353
+ /**
354
+ * Returns the call history instance.
355
+ * Provided for compatibility with the `cloudflare:test` fetchMock API.
356
+ * Equivalent to the `calls` getter.
357
+ */
330
358
  getCallHistory() {
331
359
  return this._calls;
332
360
  }
361
+ /** Clears recorded call history. Mirrors `cloudflare:test` fetchMock API. */
333
362
  clearCallHistory() {
334
363
  this._calls.clear();
335
364
  }
365
+ /** Alias for `clearCallHistory()`. Mirrors `cloudflare:test` fetchMock API. */
336
366
  clearAllCallHistory() {
337
367
  this.clearCallHistory();
338
368
  }
File without changes
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-KGCQG4D2.js";
4
4
  import {
5
5
  FetchMock
6
- } from "./chunk-3RAWYKAG.js";
6
+ } from "./chunk-3XFP4NAO.js";
7
7
 
8
8
  // src/node-adapter.ts
9
9
  import { setupServer } from "msw/node";