msw 2.11.0 → 2.11.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 (136) hide show
  1. package/lib/browser/index.d.mts +0 -3
  2. package/lib/browser/index.d.ts +0 -3
  3. package/lib/browser/index.js +503 -294
  4. package/lib/browser/index.js.map +1 -1
  5. package/lib/browser/index.mjs +503 -294
  6. package/lib/browser/index.mjs.map +1 -1
  7. package/lib/core/{HttpResponse-DiuKTgC7.d.mts → HttpResponse-B4YmE-GJ.d.mts} +1 -1
  8. package/lib/core/{HttpResponse-DlQEvD4q.d.ts → HttpResponse-BbwAqLE_.d.ts} +1 -1
  9. package/lib/core/HttpResponse.d.mts +1 -1
  10. package/lib/core/HttpResponse.d.ts +1 -1
  11. package/lib/core/HttpResponse.js.map +1 -1
  12. package/lib/core/HttpResponse.mjs.map +1 -1
  13. package/lib/core/SetupApi.d.mts +1 -1
  14. package/lib/core/SetupApi.d.ts +1 -1
  15. package/lib/core/getResponse.d.mts +1 -1
  16. package/lib/core/getResponse.d.ts +1 -1
  17. package/lib/core/graphql.d.mts +1 -1
  18. package/lib/core/graphql.d.ts +1 -1
  19. package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
  20. package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
  21. package/lib/core/handlers/GraphQLHandler.js.map +1 -1
  22. package/lib/core/handlers/GraphQLHandler.mjs.map +1 -1
  23. package/lib/core/handlers/HttpHandler.d.mts +1 -1
  24. package/lib/core/handlers/HttpHandler.d.ts +1 -1
  25. package/lib/core/handlers/HttpHandler.js.map +1 -1
  26. package/lib/core/handlers/HttpHandler.mjs.map +1 -1
  27. package/lib/core/handlers/RequestHandler.d.mts +1 -1
  28. package/lib/core/handlers/RequestHandler.d.ts +1 -1
  29. package/lib/core/http.d.mts +1 -1
  30. package/lib/core/http.d.ts +1 -1
  31. package/lib/core/index.d.mts +1 -1
  32. package/lib/core/index.d.ts +1 -1
  33. package/lib/core/passthrough.d.mts +1 -1
  34. package/lib/core/passthrough.d.ts +1 -1
  35. package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
  36. package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
  37. package/lib/core/utils/cookieStore.d.mts +10 -2
  38. package/lib/core/utils/cookieStore.d.ts +10 -2
  39. package/lib/core/utils/cookieStore.js +49 -146
  40. package/lib/core/utils/cookieStore.js.map +1 -1
  41. package/lib/core/utils/cookieStore.mjs +53 -136
  42. package/lib/core/utils/cookieStore.mjs.map +1 -1
  43. package/lib/core/utils/executeHandlers.d.mts +1 -1
  44. package/lib/core/utils/executeHandlers.d.ts +1 -1
  45. package/lib/core/utils/handleRequest.d.mts +1 -1
  46. package/lib/core/utils/handleRequest.d.ts +1 -1
  47. package/lib/core/utils/handleRequest.js +1 -1
  48. package/lib/core/utils/handleRequest.js.map +1 -1
  49. package/lib/core/utils/handleRequest.mjs +1 -1
  50. package/lib/core/utils/handleRequest.mjs.map +1 -1
  51. package/lib/core/utils/internal/devUtils.js.map +1 -1
  52. package/lib/core/utils/internal/devUtils.mjs.map +1 -1
  53. package/lib/core/utils/internal/getCallFrame.js +2 -2
  54. package/lib/core/utils/internal/getCallFrame.js.map +1 -1
  55. package/lib/core/utils/internal/getCallFrame.mjs +2 -2
  56. package/lib/core/utils/internal/getCallFrame.mjs.map +1 -1
  57. package/lib/core/utils/internal/isHandlerKind.d.mts +1 -1
  58. package/lib/core/utils/internal/isHandlerKind.d.ts +1 -1
  59. package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
  60. package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
  61. package/lib/core/utils/internal/parseGraphQLRequest.js +1 -0
  62. package/lib/core/utils/internal/parseGraphQLRequest.js.map +1 -1
  63. package/lib/core/utils/internal/parseGraphQLRequest.mjs +1 -0
  64. package/lib/core/utils/internal/parseGraphQLRequest.mjs.map +1 -1
  65. package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
  66. package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
  67. package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
  68. package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
  69. package/lib/core/utils/matching/matchRequestUrl.js +1 -1
  70. package/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
  71. package/lib/core/utils/matching/matchRequestUrl.mjs +1 -1
  72. package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -1
  73. package/lib/core/utils/request/getRequestCookies.js +1 -1
  74. package/lib/core/utils/request/getRequestCookies.js.map +1 -1
  75. package/lib/core/utils/request/getRequestCookies.mjs +1 -1
  76. package/lib/core/utils/request/getRequestCookies.mjs.map +1 -1
  77. package/lib/core/utils/request/storeResponseCookies.d.mts +1 -1
  78. package/lib/core/utils/request/storeResponseCookies.d.ts +1 -1
  79. package/lib/core/utils/request/storeResponseCookies.js +2 -2
  80. package/lib/core/utils/request/storeResponseCookies.js.map +1 -1
  81. package/lib/core/utils/request/storeResponseCookies.mjs +2 -2
  82. package/lib/core/utils/request/storeResponseCookies.mjs.map +1 -1
  83. package/lib/core/utils/url/cleanUrl.js +1 -1
  84. package/lib/core/utils/url/cleanUrl.js.map +1 -1
  85. package/lib/core/utils/url/cleanUrl.mjs +1 -1
  86. package/lib/core/utils/url/cleanUrl.mjs.map +1 -1
  87. package/lib/core/utils/url/isAbsoluteUrl.js +1 -1
  88. package/lib/core/utils/url/isAbsoluteUrl.js.map +1 -1
  89. package/lib/core/utils/url/isAbsoluteUrl.mjs +1 -1
  90. package/lib/core/utils/url/isAbsoluteUrl.mjs.map +1 -1
  91. package/lib/core/ws/WebSocketIndexedDBClientStore.js.map +1 -1
  92. package/lib/core/ws/WebSocketIndexedDBClientStore.mjs.map +1 -1
  93. package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
  94. package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
  95. package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -1
  96. package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -1
  97. package/lib/iife/index.js +6885 -16153
  98. package/lib/iife/index.js.map +1 -1
  99. package/lib/mockServiceWorker.js +16 -12
  100. package/lib/node/index.js.map +1 -1
  101. package/lib/node/index.mjs.map +1 -1
  102. package/package.json +22 -15
  103. package/src/browser/setupWorker/glossary.ts +9 -114
  104. package/src/browser/setupWorker/setupWorker.ts +83 -120
  105. package/src/browser/setupWorker/start/createRequestListener.ts +20 -24
  106. package/src/browser/setupWorker/start/createResponseListener.ts +15 -22
  107. package/src/browser/setupWorker/start/createStartHandler.ts +24 -18
  108. package/src/browser/setupWorker/start/utils/enableMocking.ts +18 -21
  109. package/src/browser/setupWorker/start/utils/printStartMessage.ts +0 -2
  110. package/src/browser/utils/checkWorkerIntegrity.ts +22 -14
  111. package/src/browser/utils/workerChannel.ts +146 -0
  112. package/src/core/HttpResponse.ts +3 -3
  113. package/src/core/handlers/GraphQLHandler.test.ts +1 -1
  114. package/src/core/handlers/GraphQLHandler.ts +0 -3
  115. package/src/core/handlers/HttpHandler.ts +0 -2
  116. package/src/core/utils/cookieStore.ts +56 -198
  117. package/src/core/utils/handleRequest.ts +1 -1
  118. package/src/core/utils/internal/devUtils.ts +0 -2
  119. package/src/core/utils/internal/getCallFrame.ts +2 -2
  120. package/src/core/utils/internal/parseGraphQLRequest.ts +1 -0
  121. package/src/core/utils/matching/matchRequestUrl.ts +2 -2
  122. package/src/core/utils/request/getRequestCookies.ts +1 -1
  123. package/src/core/utils/request/onUnhandledRequest.test.ts +1 -1
  124. package/src/core/utils/request/storeResponseCookies.ts +3 -3
  125. package/src/core/utils/request/toPublicUrl.test.ts +1 -1
  126. package/src/core/utils/url/cleanUrl.ts +1 -1
  127. package/src/core/utils/url/isAbsoluteUrl.ts +1 -1
  128. package/src/core/ws/WebSocketClientManager.test.ts +1 -1
  129. package/src/core/ws/WebSocketIndexedDBClientStore.ts +0 -4
  130. package/src/core/ws/utils/attachWebSocketLogger.ts +0 -14
  131. package/src/mockServiceWorker.js +14 -10
  132. package/src/node/SetupServerApi.ts +1 -1
  133. package/src/browser/setupWorker/start/createFallbackStart.ts +0 -21
  134. package/src/browser/setupWorker/start/utils/createMessageChannel.ts +0 -32
  135. package/src/browser/setupWorker/stop/createFallbackStop.ts +0 -11
  136. package/src/browser/setupWorker/stop/createStop.ts +0 -35
@@ -0,0 +1,146 @@
1
+ import { Emitter, TypedEvent } from 'rettime'
2
+ import { isObject } from '~/core/utils/internal/isObject'
3
+ import type { StringifiedResponse } from '../setupWorker/glossary'
4
+
5
+ export interface WorkerChannelOptions {
6
+ worker: Promise<ServiceWorker>
7
+ }
8
+
9
+ export type WorkerChannelEventMap = {
10
+ REQUEST: WorkerEvent<IncomingWorkerRequest>
11
+ RESPONSE: WorkerEvent<IncomingWorkerResponse>
12
+ MOCKING_ENABLED: WorkerEvent<{
13
+ client: {
14
+ id: string
15
+ frameType: string
16
+ }
17
+ }>
18
+ INTEGRITY_CHECK_RESPONSE: WorkerEvent<{
19
+ packageVersion: string
20
+ checksum: string
21
+ }>
22
+ KEEPALIVE_RESPONSE: TypedEvent<never>
23
+ }
24
+
25
+ /**
26
+ * Request representation received from the worker message event.
27
+ */
28
+ export interface IncomingWorkerRequest
29
+ extends Omit<
30
+ Request,
31
+ | 'text'
32
+ | 'body'
33
+ | 'json'
34
+ | 'blob'
35
+ | 'arrayBuffer'
36
+ | 'formData'
37
+ | 'clone'
38
+ | 'signal'
39
+ | 'isHistoryNavigation'
40
+ | 'isReloadNavigation'
41
+ > {
42
+ /**
43
+ * Unique ID of the request generated once the request is
44
+ * intercepted by the "fetch" event in the Service Worker.
45
+ */
46
+ id: string
47
+ interceptedAt: number
48
+ body?: ArrayBuffer | null
49
+ }
50
+
51
+ type IncomingWorkerResponse = {
52
+ isMockedResponse: boolean
53
+ request: IncomingWorkerRequest
54
+ response: Pick<
55
+ Response,
56
+ 'type' | 'ok' | 'status' | 'statusText' | 'body' | 'headers' | 'redirected'
57
+ >
58
+ }
59
+
60
+ export type WorkerEventResponse = {
61
+ MOCK_RESPONSE: [
62
+ data: StringifiedResponse,
63
+ transfer?: [ReadableStream<Uint8Array>],
64
+ ]
65
+ PASSTHROUGH: []
66
+ }
67
+
68
+ export class WorkerEvent<
69
+ DataType,
70
+ ReturnType = any,
71
+ EventType extends string = string,
72
+ > extends TypedEvent<DataType, ReturnType, EventType> {
73
+ #workerEvent: MessageEvent
74
+
75
+ constructor(workerEvent: MessageEvent) {
76
+ const type = workerEvent.data.type as EventType
77
+ const data = workerEvent.data.payload as DataType
78
+
79
+ /**
80
+ * @note This is the only place we're mapping { type, payload }
81
+ * message structure of the worker. The client references the
82
+ * payload via `event.data`.
83
+ */
84
+ super(
85
+ // @ts-expect-error Troublesome `TypedEvent` extension.
86
+ type,
87
+ { data },
88
+ )
89
+ this.#workerEvent = workerEvent
90
+ }
91
+
92
+ get ports() {
93
+ return this.#workerEvent.ports
94
+ }
95
+
96
+ /**
97
+ * Reply directly to this event using its `MessagePort`.
98
+ */
99
+ public postMessage<Type extends keyof WorkerEventResponse>(
100
+ type: Type,
101
+ ...rest: WorkerEventResponse[Type]
102
+ ): void {
103
+ this.#workerEvent.ports[0].postMessage(
104
+ { type, data: rest[0] },
105
+ { transfer: rest[1] },
106
+ )
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Map of the events that can be sent to the Service Worker
112
+ * from any execution context.
113
+ */
114
+ type OutgoingWorkerEvents =
115
+ | 'MOCK_ACTIVATE'
116
+ | 'INTEGRITY_CHECK_REQUEST'
117
+ | 'KEEPALIVE_REQUEST'
118
+ | 'CLIENT_CLOSED'
119
+
120
+ export class WorkerChannel extends Emitter<WorkerChannelEventMap> {
121
+ constructor(protected readonly options: WorkerChannelOptions) {
122
+ super()
123
+
124
+ navigator.serviceWorker.addEventListener('message', async (event) => {
125
+ const worker = await this.options.worker
126
+
127
+ if (event.source != null && event.source !== worker) {
128
+ return
129
+ }
130
+
131
+ if (event.data && isObject(event.data) && 'type' in event.data) {
132
+ this.emit(new WorkerEvent<any, any, any>(event))
133
+ }
134
+ })
135
+ }
136
+
137
+ /**
138
+ * Send data to the Service Worker controlling this client.
139
+ * This triggers the `message` event listener on ServiceWorkerGlobalScope.
140
+ */
141
+ public postMessage(type: OutgoingWorkerEvents): void {
142
+ this.options.worker.then((worker) => {
143
+ worker.postMessage(type)
144
+ })
145
+ }
146
+ }
@@ -161,10 +161,10 @@ export class HttpResponse<
161
161
  *
162
162
  * HttpResponse.arrayBuffer(buffer)
163
163
  */
164
- static arrayBuffer(
165
- body?: ArrayBuffer | SharedArrayBuffer,
164
+ static arrayBuffer<BodyType extends ArrayBuffer | SharedArrayBuffer>(
165
+ body?: BodyType,
166
166
  init?: HttpResponseInit,
167
- ): HttpResponse<ArrayBuffer | SharedArrayBuffer> {
167
+ ): HttpResponse<BodyType> {
168
168
  const responseInit = normalizeResponseInit(init)
169
169
 
170
170
  if (!responseInit.headers.has('Content-Type')) {
@@ -602,7 +602,7 @@ describe('predicate', () => {
602
602
  ).resolves.toBe(false)
603
603
  })
604
604
 
605
- it('allows anonymous GraphQL opertaions when using "all" expected operation type', async () => {
605
+ it('allows anonymous GraphQL operations when using "all" expected operation type', async () => {
606
606
  const handler = new GraphQLHandler('all', new RegExp('.*'), '*', resolver)
607
607
  const request = createPostGraphQLRequest({
608
608
  query: `
@@ -176,7 +176,6 @@ export class GraphQLHandler extends RequestHandler<
176
176
  GraphQLHandler.parsedRequestCache.set(
177
177
  request,
178
178
  await parseGraphQLRequest(request).catch((error) => {
179
- // eslint-disable-next-line no-console
180
179
  console.error(error)
181
180
  return undefined
182
181
  }),
@@ -318,7 +317,6 @@ Consider naming this operation or using "graphql.operation()" request handler to
318
317
  ? `${args.parsedResult.operationType} ${args.parsedResult.operationName}`
319
318
  : `anonymous ${args.parsedResult.operationType}`
320
319
 
321
- // eslint-disable-next-line no-console
322
320
  console.groupCollapsed(
323
321
  devUtils.formatMessage(
324
322
  `${getTimestamp()} ${requestInfo} (%c${loggedResponse.status} ${
@@ -334,7 +332,6 @@ Consider naming this operation or using "graphql.operation()" request handler to
334
332
  console.log('Handler:', this)
335
333
  // eslint-disable-next-line no-console
336
334
  console.log('Response:', loggedResponse)
337
- // eslint-disable-next-line no-console
338
335
  console.groupEnd()
339
336
  }
340
337
  }
@@ -201,7 +201,6 @@ export class HttpHandler extends RequestHandler<
201
201
  const loggedResponse = await serializeResponse(args.response)
202
202
  const statusColor = getStatusCodeColor(loggedResponse.status)
203
203
 
204
- // eslint-disable-next-line no-console
205
204
  console.groupCollapsed(
206
205
  devUtils.formatMessage(
207
206
  `${getTimestamp()} ${args.request.method} ${publicUrl} (%c${
@@ -217,7 +216,6 @@ export class HttpHandler extends RequestHandler<
217
216
  console.log('Handler:', this)
218
217
  // eslint-disable-next-line no-console
219
218
  console.log('Response', loggedResponse)
220
- // eslint-disable-next-line no-console
221
219
  console.groupEnd()
222
220
  }
223
221
  }
@@ -1,230 +1,88 @@
1
- import { invariant } from 'outvariant'
2
1
  import { isNodeProcess } from 'is-node-process'
3
- import toughCookie, {
4
- type Cookie as CookieInstance,
5
- } from '@bundled-es-modules/tough-cookie'
6
-
7
- const { Cookie, CookieJar, Store, MemoryCookieStore, domainMatch, pathMatch } =
8
- toughCookie
9
-
10
- /**
11
- * Custom cookie store that uses the Web Storage API.
12
- * @see https://github.com/expo/tough-cookie-web-storage-store
13
- */
14
- class WebStorageCookieStore extends Store {
15
- private storage: Storage
16
- private storageKey: string
2
+ import { invariant } from 'outvariant'
3
+ import {
4
+ Cookie,
5
+ CookieJar,
6
+ MemoryCookieStore,
7
+ type MemoryCookieStoreIndex,
8
+ } from 'tough-cookie'
9
+ import { jsonParse } from './internal/jsonParse'
10
+
11
+ class CookieStore {
12
+ #storageKey = '__msw-cookie-store__'
13
+ #jar: CookieJar
14
+ #memoryStore: MemoryCookieStore
17
15
 
18
16
  constructor() {
19
- super()
20
-
21
- invariant(
22
- typeof localStorage !== 'undefined',
23
- 'Failed to create a WebStorageCookieStore: `localStorage` is not available in this environment. This is likely an issue with MSW. Please report it on GitHub: https://github.com/mswjs/msw/issues',
24
- )
25
-
26
- this.synchronous = true
27
- this.storage = localStorage
28
- this.storageKey = '__msw-cookie-store__'
29
- }
30
-
31
- findCookie(
32
- domain: string,
33
- path: string,
34
- key: string,
35
- callback: (error: Error | null, cookie: CookieInstance | null) => void,
36
- ): void {
37
- try {
38
- const store = this.getStore()
39
- const cookies = this.filterCookiesFromList(store, { domain, path, key })
40
- callback(null, cookies[0] || null)
41
- } catch (error) {
42
- if (error instanceof Error) {
43
- callback(error, null)
44
- }
45
- }
46
- }
47
-
48
- findCookies(
49
- domain: string,
50
- path: string,
51
- allowSpecialUseDomain: boolean,
52
- callback: (error: Error | null, cookie: Array<CookieInstance>) => void,
53
- ): void {
54
- if (!domain) {
55
- callback(null, [])
56
- return
17
+ if (!isNodeProcess()) {
18
+ invariant(
19
+ typeof localStorage !== 'undefined',
20
+ 'Failed to create a CookieStore: `localStorage` is not available in this environment. This is likely an issue with your environment, which has been detected as browser (or browser-like) environment and must implement global browser APIs correctly.',
21
+ )
57
22
  }
58
23
 
59
- try {
60
- const store = this.getStore()
61
- const results = this.filterCookiesFromList(store, {
62
- domain,
63
- path,
64
- })
65
- callback(null, results)
66
- } catch (error) {
67
- if (error instanceof Error) {
68
- callback(error, [])
69
- }
70
- }
24
+ this.#memoryStore = new MemoryCookieStore()
25
+ this.#memoryStore.idx = this.getCookieStoreIndex()
26
+ this.#jar = new CookieJar(this.#memoryStore)
71
27
  }
72
28
 
73
- putCookie(
74
- cookie: CookieInstance,
75
- callback: (error: Error | null) => void,
76
- ): void {
77
- try {
78
- // Never set cookies with `maxAge` of `0`.
79
- if (cookie.maxAge === 0) {
80
- return
81
- }
82
-
83
- const store = this.getStore()
84
- store.push(cookie)
85
- this.updateStore(store)
86
- } catch (error) {
87
- if (error instanceof Error) {
88
- callback(error)
89
- }
90
- }
29
+ public getCookies(url: string): Array<Cookie> {
30
+ return this.#jar.getCookiesSync(url)
91
31
  }
92
32
 
93
- updateCookie(
94
- oldCookie: CookieInstance,
95
- newCookie: CookieInstance,
96
- callback: (error: Error | null) => void,
97
- ): void {
98
- /**
99
- * If updating a cookie with `maxAge` of `0`, remove it from the store.
100
- * Otherwise, two cookie entries will be created.
101
- * @see https://github.com/mswjs/msw/issues/2272
102
- */
103
- if (newCookie.maxAge === 0) {
104
- this.removeCookie(
105
- newCookie.domain || '',
106
- newCookie.path || '',
107
- newCookie.key,
108
- callback,
109
- )
110
- return
111
- }
112
-
113
- this.putCookie(newCookie, callback)
33
+ public async setCookie(cookieName: string, url: string): Promise<void> {
34
+ await this.#jar.setCookie(cookieName, url)
35
+ this.persist()
114
36
  }
115
37
 
116
- removeCookie(
117
- domain: string,
118
- path: string,
119
- key: string,
120
- callback: (error: Error | null) => void,
121
- ): void {
122
- try {
123
- const store = this.getStore()
124
- const nextStore = this.deleteCookiesFromList(store, { domain, path, key })
125
- this.updateStore(nextStore)
126
- callback(null)
127
- } catch (error) {
128
- if (error instanceof Error) {
129
- callback(error)
130
- }
38
+ private getCookieStoreIndex(): MemoryCookieStoreIndex {
39
+ if (typeof localStorage === 'undefined') {
40
+ return {}
131
41
  }
132
- }
133
42
 
134
- removeCookies(
135
- domain: string,
136
- path: string,
137
- callback: (error: Error | null) => void,
138
- ): void {
139
- try {
140
- const store = this.getStore()
141
- const nextStore = this.deleteCookiesFromList(store, { domain, path })
142
- this.updateStore(nextStore)
143
- callback(null)
144
- } catch (error) {
145
- if (error instanceof Error) {
146
- callback(error)
147
- }
43
+ const cookiesString = localStorage.getItem(this.#storageKey)
44
+ if (cookiesString == null) {
45
+ return {}
148
46
  }
149
- }
150
47
 
151
- getAllCookies(
152
- callback: (error: Error | null, cookie: Array<CookieInstance>) => void,
153
- ): void {
154
- try {
155
- callback(null, this.getStore())
156
- } catch (error) {
157
- if (error instanceof Error) {
158
- callback(error, [])
159
- }
48
+ const rawCookies = jsonParse<Array<Record<string, unknown>>>(cookiesString)
49
+ if (rawCookies == null) {
50
+ return {}
160
51
  }
161
- }
162
52
 
163
- private getStore(): Array<CookieInstance> {
164
- try {
165
- const json = this.storage.getItem(this.storageKey)
53
+ const cookies: MemoryCookieStoreIndex = {}
166
54
 
167
- if (json == null) {
168
- return []
169
- }
55
+ for (const rawCookie of rawCookies) {
56
+ const cookie = Cookie.fromJSON(rawCookie)
170
57
 
171
- const rawCookies = JSON.parse(json) as Array<Record<string, any>>
172
- const cookies: Array<CookieInstance> = []
173
- for (const rawCookie of rawCookies) {
174
- const cookie = Cookie.fromJSON(rawCookie)
175
- if (cookie != null) {
176
- cookies.push(cookie)
177
- }
58
+ if (cookie != null && cookie.domain != null && cookie.path != null) {
59
+ cookies[cookie.domain] ||= {}
60
+ cookies[cookie.domain][cookie.path] ||= {}
61
+ cookies[cookie.domain][cookie.path][cookie.key] = cookie
178
62
  }
179
- return cookies
180
- } catch {
181
- return []
182
63
  }
183
- }
184
64
 
185
- private updateStore(nextStore: Array<CookieInstance>) {
186
- this.storage.setItem(
187
- this.storageKey,
188
- JSON.stringify(nextStore.map((cookie) => cookie.toJSON())),
189
- )
65
+ return cookies
190
66
  }
191
67
 
192
- private filterCookiesFromList(
193
- cookies: Array<CookieInstance>,
194
- matches: { domain?: string; path?: string; key?: string },
195
- ): Array<CookieInstance> {
196
- const result: Array<CookieInstance> = []
197
-
198
- for (const cookie of cookies) {
199
- if (matches.domain && !domainMatch(matches.domain, cookie.domain || '')) {
200
- continue
201
- }
68
+ private persist(): void {
69
+ if (typeof localStorage === 'undefined') {
70
+ return
71
+ }
202
72
 
203
- if (matches.path && !pathMatch(matches.path, cookie.path || '')) {
204
- continue
205
- }
73
+ const data = []
74
+ const { idx } = this.#memoryStore
206
75
 
207
- if (matches.key && cookie.key !== matches.key) {
208
- continue
76
+ for (const domain in idx) {
77
+ for (const path in idx[domain]) {
78
+ for (const key in idx[domain][path]) {
79
+ data.push(idx[domain][path][key].toJSON())
80
+ }
209
81
  }
210
-
211
- result.push(cookie)
212
82
  }
213
83
 
214
- return result
215
- }
216
-
217
- private deleteCookiesFromList(
218
- cookies: Array<CookieInstance>,
219
- matches: { domain?: string; path?: string; key?: string },
220
- ) {
221
- const matchingCookies = this.filterCookiesFromList(cookies, matches)
222
- return cookies.filter((cookie) => !matchingCookies.includes(cookie))
84
+ localStorage.setItem(this.#storageKey, JSON.stringify(data))
223
85
  }
224
86
  }
225
87
 
226
- const store = isNodeProcess()
227
- ? new MemoryCookieStore()
228
- : new WebStorageCookieStore()
229
-
230
- export const cookieStore = new CookieJar(store)
88
+ export const cookieStore = new CookieStore()
@@ -105,7 +105,7 @@ export async function handleRequest(
105
105
  }
106
106
 
107
107
  // Store all the received response cookies in the cookie jar.
108
- storeResponseCookies(request, response)
108
+ await storeResponseCookies(request, response)
109
109
 
110
110
  emitter.emit('request:match', { request, requestId })
111
111
 
@@ -14,7 +14,6 @@ function formatMessage(message: string, ...positionals: any[]): string {
14
14
  * Prints a library-specific warning.
15
15
  */
16
16
  function warn(message: string, ...positionals: any[]): void {
17
- // eslint-disable-next-line no-console
18
17
  console.warn(formatMessage(message, ...positionals))
19
18
  }
20
19
 
@@ -22,7 +21,6 @@ function warn(message: string, ...positionals: any[]): void {
22
21
  * Prints a library-specific error.
23
22
  */
24
23
  function error(message: string, ...positionals: any[]): void {
25
- // eslint-disable-next-line no-console
26
24
  console.error(formatMessage(message, ...positionals))
27
25
  }
28
26
 
@@ -1,8 +1,8 @@
1
1
  // Ignore the source files traces for local testing.
2
- const SOURCE_FRAME = /[\/\\]msw[\/\\]src[\/\\](.+)/
2
+ const SOURCE_FRAME = /[/\\]msw[/\\]src[/\\](.+)/
3
3
 
4
4
  const BUILD_FRAME =
5
- /(node_modules)?[\/\\]lib[\/\\](core|browser|node|native|iife)[\/\\]|^[^\/\\]*$/
5
+ /(node_modules)?[/\\]lib[/\\](core|browser|node|native|iife)[/\\]|^[^/\\]*$/
6
6
 
7
7
  /**
8
8
  * Return the stack trace frame of a function's invocation.
@@ -168,6 +168,7 @@ async function getGraphQLInput(request: Request): Promise<GraphQLInput | null> {
168
168
  variables,
169
169
  }
170
170
  }
171
+ return null
171
172
  }
172
173
 
173
174
  default:
@@ -42,13 +42,13 @@ export function coercePath(path: string): string {
42
42
  * Escape the port so that "path-to-regexp" can match
43
43
  * absolute URLs including port numbers.
44
44
  */
45
- .replace(/([^\/])(:)(?=\d+)/, '$1\\$2')
45
+ .replace(/([^/])(:)(?=\d+)/, '$1\\$2')
46
46
  /**
47
47
  * Escape the protocol so that "path-to-regexp" could match
48
48
  * absolute URL.
49
49
  * @see https://github.com/pillarjs/path-to-regexp/issues/259
50
50
  */
51
- .replace(/^([^\/]+)(:)(?=\/\/)/, '$1\\$2')
51
+ .replace(/^([^/]+)(:)(?=\/\/)/, '$1\\$2')
52
52
  )
53
53
  }
54
54
 
@@ -66,7 +66,7 @@ export function getAllRequestCookies(request: Request): Record<string, string> {
66
66
  )
67
67
  }
68
68
 
69
- const cookiesFromStore = cookieStore.getCookiesSync(request.url)
69
+ const cookiesFromStore = cookieStore.getCookies(request.url)
70
70
  const storedCookiesObject = Object.fromEntries(
71
71
  cookiesFromStore.map((cookie) => [cookie.key, cookie.value]),
72
72
  )
@@ -17,7 +17,7 @@ Read more: https://mswjs.io/docs/http/intercepting-requests`,
17
17
 
18
18
  • POST ${url}
19
19
 
20
- • Request body: {\"variables\":{\"id\":\"abc-123\"},\"query\":\"query UserName($id: String!) { user(id: $id) { name } }\"}
20
+ • Request body: {"variables":{"id":"abc-123"},"query":"query UserName($id: String!) { user(id: $id) { name } }"}
21
21
 
22
22
  If you still wish to intercept this unhandled request, please create a request handler for it.
23
23
  Read more: https://mswjs.io/docs/http/intercepting-requests`,
@@ -1,10 +1,10 @@
1
1
  import { cookieStore } from '../cookieStore'
2
2
  import { kSetCookie } from '../HttpResponse/decorators'
3
3
 
4
- export function storeResponseCookies(
4
+ export async function storeResponseCookies(
5
5
  request: Request,
6
6
  response: Response,
7
- ): void {
7
+ ): Promise<void> {
8
8
  // Grab the raw "Set-Cookie" response header provided
9
9
  // in the HeadersInit for this mocked response.
10
10
  const responseCookies = Reflect.get(response, kSetCookie) as
@@ -12,6 +12,6 @@ export function storeResponseCookies(
12
12
  | undefined
13
13
 
14
14
  if (responseCookies) {
15
- cookieStore.setCookie(responseCookies, request.url)
15
+ await cookieStore.setCookie(responseCookies, request.url)
16
16
  }
17
17
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { toPublicUrl } from './toPublicUrl'
5
5
 
6
- test('returns an absolute request URL withouth search params', () => {
6
+ test('returns an absolute request URL without search params', () => {
7
7
  expect(toPublicUrl(new URL('https://test.mswjs.io/path'))).toBe(
8
8
  'https://test.mswjs.io/path',
9
9
  )
@@ -1,4 +1,4 @@
1
- const REDUNDANT_CHARACTERS_EXP = /[\?|#].*$/g
1
+ const REDUNDANT_CHARACTERS_EXP = /[?|#].*$/g
2
2
 
3
3
  export function getSearchParams(path: string) {
4
4
  return new URL(`/${path}`, 'http://localhost').searchParams
@@ -2,5 +2,5 @@
2
2
  * Determines if the given URL string is an absolute URL.
3
3
  */
4
4
  export function isAbsoluteUrl(url: string): boolean {
5
- return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
5
+ return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
6
6
  }
@@ -62,7 +62,7 @@ it('adds multiple clients from this runtime to the list of clients', async () =>
62
62
  )
63
63
  await manager.addConnection(connectionTwo)
64
64
 
65
- // Must add the new cilent to the list as well.
65
+ // Must add the new client to the list as well.
66
66
  expect(Array.from(manager.clients.values())).toEqual([
67
67
  connectionOne,
68
68
  connectionTwo,
@@ -34,7 +34,6 @@ export class WebSocketIndexedDBClientStore implements WebSocketClientStore {
34
34
  promise.resolve()
35
35
  }
36
36
  request.onerror = () => {
37
- // eslint-disable-next-line no-console
38
37
  console.error(request.error)
39
38
  promise.reject(
40
39
  new Error(
@@ -81,7 +80,6 @@ export class WebSocketIndexedDBClientStore implements WebSocketClientStore {
81
80
  promise.resolve()
82
81
  }
83
82
  store.transaction.onerror = () => {
84
- // eslint-disable-next-line no-console
85
83
  console.error(store.transaction.error)
86
84
  promise.reject(
87
85
  new Error(
@@ -116,7 +114,6 @@ export class WebSocketIndexedDBClientStore implements WebSocketClientStore {
116
114
  promise.resolve(db)
117
115
  }
118
116
  store.transaction.onerror = () => {
119
- // eslint-disable-next-line no-console
120
117
  console.error(store.transaction.error)
121
118
  promise.reject(
122
119
  new Error(
@@ -126,7 +123,6 @@ export class WebSocketIndexedDBClientStore implements WebSocketClientStore {
126
123
  }
127
124
  }
128
125
  request.onerror = () => {
129
- // eslint-disable-next-line no-console
130
126
  console.error(request.error)
131
127
  promise.reject(
132
128
  new Error(