msw-fetch-mock 0.1.1 → 0.1.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.
package/README.md CHANGED
@@ -18,12 +18,10 @@ npm install -D msw-fetch-mock msw
18
18
 
19
19
  ## Quick Start
20
20
 
21
- ```typescript
22
- import { setupServer } from 'msw/node';
23
- import { FetchMock } from 'msw-fetch-mock';
21
+ ### Standalone (Cloudflare migration)
24
22
 
25
- const server = setupServer();
26
- const fetchMock = new FetchMock(server);
23
+ ```typescript
24
+ import { fetchMock } from 'msw-fetch-mock';
27
25
 
28
26
  beforeAll(() => fetchMock.activate());
29
27
  afterAll(() => fetchMock.deactivate());
@@ -42,11 +40,37 @@ it('mocks a GET request', async () => {
42
40
  });
43
41
  ```
44
42
 
43
+ ### With an existing MSW server
44
+
45
+ If you already use MSW, pass your server to share a single interceptor:
46
+
47
+ ```typescript
48
+ import { setupServer } from 'msw/node';
49
+ import { http, HttpResponse } from 'msw';
50
+ import { FetchMock } from 'msw-fetch-mock';
51
+
52
+ const server = setupServer(http.get('/api/users', () => HttpResponse.json([{ id: 1 }])));
53
+ const fetchMock = new FetchMock(server);
54
+
55
+ beforeAll(() => server.listen());
56
+ afterAll(() => server.close());
57
+ afterEach(() => {
58
+ server.resetHandlers();
59
+ fetchMock.assertNoPendingInterceptors();
60
+ });
61
+ ```
62
+
63
+ > **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(server)` instead.
64
+
45
65
  ## API Overview
46
66
 
67
+ ### `fetchMock` (singleton)
68
+
69
+ A pre-built `FetchMock` instance for standalone use. Import and call `activate()` — no setup needed.
70
+
47
71
  ### `new FetchMock(server?)`
48
72
 
49
- Creates a `FetchMock` instance. Optionally accepts an existing MSW `SetupServer`; creates one internally if omitted.
73
+ Creates a `FetchMock` instance. Pass an existing MSW `SetupServer` to share interceptors; omit to create one internally.
50
74
 
51
75
  ### Intercepting & Replying
52
76
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
+ import { FetchMock } from './mock-server';
1
2
  export { createFetchMock, FetchMock } from './mock-server';
3
+ /** Pre-built singleton for quick standalone use (Cloudflare migration compatible). */
4
+ export declare const fetchMock: FetchMock;
2
5
  export type { InterceptOptions, MockPool, MockInterceptor, MockReplyChain, ReplyOptions, PendingInterceptor, } from './mock-server';
3
6
  export { MockCallHistory, MockCallHistoryLog } from './mock-call-history';
4
7
  export type { MockCallHistoryLogData, CallHistoryFilterCriteria } from './mock-call-history';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE3D,sFAAsF;AACtF,eAAO,MAAM,SAAS,WAAkB,CAAC;AACzC,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,5 @@
1
+ import { FetchMock } from './mock-server';
1
2
  export { createFetchMock, FetchMock } from './mock-server';
3
+ /** Pre-built singleton for quick standalone use (Cloudflare migration compatible). */
4
+ export const fetchMock = new FetchMock();
2
5
  export { MockCallHistory, MockCallHistoryLog } from './mock-call-history';
@@ -1 +1 @@
1
- {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../src/mock-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../src/mock-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,2FAA2F;AAC3F,UAAU,eAAe;IACvB,GAAG,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACvC,aAAa,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACjD,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChD,KAAK,IAAI,IAAI,CAAC;CACf;AAED,KAAK,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC9D,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;AACjE,KAAK,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;AACzE,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,KAAK,aAAa,GAAG,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC;IAC9E,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,cAAc,CAAC;IAC/D,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,CAAC;CAC9C;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAAC;CACvD;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAiGD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,iBAAiB,CAA4B;IAErD,IAAI,KAAK,IAAI,eAAe,CAE3B;gBAEW,cAAc,CAAC,EAAE,eAAe;IAK5C,QAAQ,IAAI,IAAI;IAqBhB,iBAAiB,IAAI,IAAI;IAIzB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI;IAI/E,OAAO,CAAC,mBAAmB;IAS3B,cAAc,IAAI,eAAe;IAIjC,gBAAgB,IAAI,IAAI;IAIxB,UAAU,IAAI,IAAI;IASlB,2BAA2B,IAAI,IAAI;IAcnC,mBAAmB,IAAI,kBAAkB,EAAE;IAI3C,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;CAwH9B;AAED,wBAAgB,eAAe,CAAC,cAAc,CAAC,EAAE,eAAe,GAAG,SAAS,CAE3E"}
@@ -108,6 +108,11 @@ export class FetchMock {
108
108
  }
109
109
  activate() {
110
110
  if (this.ownsServer) {
111
+ const isPatched = Object.getOwnPropertySymbols(globalThis.fetch).some((s) => s.description === 'isPatchedModule');
112
+ if (isPatched) {
113
+ throw new Error('Another MSW server is already active. ' +
114
+ 'Pass your existing server to new FetchMock(server) instead.');
115
+ }
111
116
  this.server = setupServer();
112
117
  this.server.listen({
113
118
  onUnhandledRequest: (request, print) => {
package/docs/api.md CHANGED
@@ -1,8 +1,20 @@
1
1
  # API Reference
2
2
 
3
+ ## `fetchMock` (singleton)
4
+
5
+ A pre-built `FetchMock` instance for standalone use. No setup required — just import and call `activate()`.
6
+
7
+ ```typescript
8
+ import { fetchMock } from 'msw-fetch-mock';
9
+
10
+ beforeAll(() => fetchMock.activate());
11
+ afterAll(() => fetchMock.deactivate());
12
+ afterEach(() => fetchMock.assertNoPendingInterceptors());
13
+ ```
14
+
3
15
  ## `new FetchMock(server?)`
4
16
 
5
- Creates a `FetchMock` instance.
17
+ Creates a `FetchMock` instance. Pass an existing MSW `SetupServer` to share interceptors; omit to create one internally.
6
18
 
7
19
  ```typescript
8
20
  import { FetchMock } from 'msw-fetch-mock';
@@ -34,6 +46,8 @@ fetchMock.deactivate(); // stop intercepting (calls server.close())
34
46
  ```
35
47
 
36
48
  > If you pass an external server that you manage yourself, `activate()` / `deactivate()` are no-ops.
49
+ >
50
+ > **Conflict detection:** In standalone mode, `activate()` checks whether `globalThis.fetch` is already patched by MSW. If so, it throws an error guiding you to pass your existing server via `new FetchMock(server)` instead.
37
51
 
38
52
  ### `fetchMock.calls`
39
53
 
@@ -6,7 +6,7 @@ If you're migrating tests from Cloudflare Workers' `cloudflare:test` to a standa
6
6
 
7
7
  | cloudflare:test | msw-fetch-mock |
8
8
  | -------------------------------------------------- | ----------------------------------------------------------- |
9
- | `import { fetchMock } from 'cloudflare:test'` | `const fetchMock = new FetchMock(server)` |
9
+ | `import { fetchMock } from 'cloudflare:test'` | `import { fetchMock } from 'msw-fetch-mock'` |
10
10
  | `fetchMock.activate()` | `fetchMock.activate()` |
11
11
  | `fetchMock.disableNetConnect()` | `fetchMock.disableNetConnect()` |
12
12
  | `fetchMock.enableNetConnect(matcher?)` | `fetchMock.enableNetConnect(matcher?)` |
@@ -44,11 +44,7 @@ it('calls API', async () => {
44
44
  ## After (msw-fetch-mock)
45
45
 
46
46
  ```typescript
47
- import { setupServer } from 'msw/node';
48
- import { FetchMock } from 'msw-fetch-mock';
49
-
50
- const server = setupServer();
51
- const fetchMock = new FetchMock(server);
47
+ import { fetchMock } from 'msw-fetch-mock';
52
48
 
53
49
  beforeAll(() => fetchMock.activate());
54
50
  afterAll(() => fetchMock.deactivate());
@@ -67,12 +63,13 @@ it('calls API', async () => {
67
63
 
68
64
  ## Key Differences
69
65
 
70
- | Aspect | cloudflare:test | msw-fetch-mock |
71
- | -------------------- | ------------------------------------ | ------------------------------------------------- |
72
- | Server lifecycle | Implicit (managed by test framework) | Explicit (`activate()` / `deactivate()`) |
73
- | Call history access | `fetchMock.getCallHistory()` | `fetchMock.getCallHistory()` or `fetchMock.calls` |
74
- | Call history cleanup | Automatic per test | Automatic via `assertNoPendingInterceptors()` |
75
- | Network connect | Must call `disableNetConnect()` | MSW blocks unhandled requests by default |
76
- | Runtime | Cloudflare Workers (workerd) | Node.js |
66
+ | Aspect | cloudflare:test | msw-fetch-mock |
67
+ | -------------------- | --------------------------------------------- | ------------------------------------------------- |
68
+ | Import | `import { fetchMock } from 'cloudflare:test'` | `import { fetchMock } from 'msw-fetch-mock'` |
69
+ | Server lifecycle | Implicit (managed by test framework) | Explicit (`activate()` / `deactivate()`) |
70
+ | Call history access | `fetchMock.getCallHistory()` | `fetchMock.getCallHistory()` or `fetchMock.calls` |
71
+ | Call history cleanup | Automatic per test | Automatic via `assertNoPendingInterceptors()` |
72
+ | Network connect | Must call `disableNetConnect()` | MSW blocks unhandled requests by default |
73
+ | Runtime | Cloudflare Workers (workerd) | Node.js |
77
74
 
78
75
  > **Note:** `getCallHistory()` and `clearCallHistory()` are provided as Cloudflare-compatible aliases. You can use either the Cloudflare-style methods or the `fetchMock.calls` getter — they are equivalent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "msw-fetch-mock",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Undici-style fetch mock API built on MSW (Mock Service Worker)",
5
5
  "type": "module",
6
6
  "license": "MIT",