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.
- package/lib/browser/index.d.mts +0 -3
- package/lib/browser/index.d.ts +0 -3
- package/lib/browser/index.js +503 -294
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/index.mjs +503 -294
- package/lib/browser/index.mjs.map +1 -1
- package/lib/core/{HttpResponse-DiuKTgC7.d.mts → HttpResponse-B4YmE-GJ.d.mts} +1 -1
- package/lib/core/{HttpResponse-DlQEvD4q.d.ts → HttpResponse-BbwAqLE_.d.ts} +1 -1
- package/lib/core/HttpResponse.d.mts +1 -1
- package/lib/core/HttpResponse.d.ts +1 -1
- package/lib/core/HttpResponse.js.map +1 -1
- package/lib/core/HttpResponse.mjs.map +1 -1
- package/lib/core/SetupApi.d.mts +1 -1
- package/lib/core/SetupApi.d.ts +1 -1
- package/lib/core/getResponse.d.mts +1 -1
- package/lib/core/getResponse.d.ts +1 -1
- package/lib/core/graphql.d.mts +1 -1
- package/lib/core/graphql.d.ts +1 -1
- package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
- package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
- package/lib/core/handlers/GraphQLHandler.js.map +1 -1
- package/lib/core/handlers/GraphQLHandler.mjs.map +1 -1
- package/lib/core/handlers/HttpHandler.d.mts +1 -1
- package/lib/core/handlers/HttpHandler.d.ts +1 -1
- package/lib/core/handlers/HttpHandler.js.map +1 -1
- package/lib/core/handlers/HttpHandler.mjs.map +1 -1
- package/lib/core/handlers/RequestHandler.d.mts +1 -1
- package/lib/core/handlers/RequestHandler.d.ts +1 -1
- package/lib/core/http.d.mts +1 -1
- package/lib/core/http.d.ts +1 -1
- package/lib/core/index.d.mts +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/passthrough.d.mts +1 -1
- package/lib/core/passthrough.d.ts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
- package/lib/core/utils/cookieStore.d.mts +10 -2
- package/lib/core/utils/cookieStore.d.ts +10 -2
- package/lib/core/utils/cookieStore.js +49 -146
- package/lib/core/utils/cookieStore.js.map +1 -1
- package/lib/core/utils/cookieStore.mjs +53 -136
- package/lib/core/utils/cookieStore.mjs.map +1 -1
- package/lib/core/utils/executeHandlers.d.mts +1 -1
- package/lib/core/utils/executeHandlers.d.ts +1 -1
- package/lib/core/utils/handleRequest.d.mts +1 -1
- package/lib/core/utils/handleRequest.d.ts +1 -1
- package/lib/core/utils/handleRequest.js +1 -1
- package/lib/core/utils/handleRequest.js.map +1 -1
- package/lib/core/utils/handleRequest.mjs +1 -1
- package/lib/core/utils/handleRequest.mjs.map +1 -1
- package/lib/core/utils/internal/devUtils.js.map +1 -1
- package/lib/core/utils/internal/devUtils.mjs.map +1 -1
- package/lib/core/utils/internal/getCallFrame.js +2 -2
- package/lib/core/utils/internal/getCallFrame.js.map +1 -1
- package/lib/core/utils/internal/getCallFrame.mjs +2 -2
- package/lib/core/utils/internal/getCallFrame.mjs.map +1 -1
- package/lib/core/utils/internal/isHandlerKind.d.mts +1 -1
- package/lib/core/utils/internal/isHandlerKind.d.ts +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.js +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.js.map +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.mjs +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.mjs.map +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/core/utils/matching/matchRequestUrl.js +1 -1
- package/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
- package/lib/core/utils/matching/matchRequestUrl.mjs +1 -1
- package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -1
- package/lib/core/utils/request/getRequestCookies.js +1 -1
- package/lib/core/utils/request/getRequestCookies.js.map +1 -1
- package/lib/core/utils/request/getRequestCookies.mjs +1 -1
- package/lib/core/utils/request/getRequestCookies.mjs.map +1 -1
- package/lib/core/utils/request/storeResponseCookies.d.mts +1 -1
- package/lib/core/utils/request/storeResponseCookies.d.ts +1 -1
- package/lib/core/utils/request/storeResponseCookies.js +2 -2
- package/lib/core/utils/request/storeResponseCookies.js.map +1 -1
- package/lib/core/utils/request/storeResponseCookies.mjs +2 -2
- package/lib/core/utils/request/storeResponseCookies.mjs.map +1 -1
- package/lib/core/utils/url/cleanUrl.js +1 -1
- package/lib/core/utils/url/cleanUrl.js.map +1 -1
- package/lib/core/utils/url/cleanUrl.mjs +1 -1
- package/lib/core/utils/url/cleanUrl.mjs.map +1 -1
- package/lib/core/utils/url/isAbsoluteUrl.js +1 -1
- package/lib/core/utils/url/isAbsoluteUrl.js.map +1 -1
- package/lib/core/utils/url/isAbsoluteUrl.mjs +1 -1
- package/lib/core/utils/url/isAbsoluteUrl.mjs.map +1 -1
- package/lib/core/ws/WebSocketIndexedDBClientStore.js.map +1 -1
- package/lib/core/ws/WebSocketIndexedDBClientStore.mjs.map +1 -1
- package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
- package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
- package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -1
- package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -1
- package/lib/iife/index.js +6885 -16153
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +16 -12
- package/lib/node/index.js.map +1 -1
- package/lib/node/index.mjs.map +1 -1
- package/package.json +22 -15
- package/src/browser/setupWorker/glossary.ts +9 -114
- package/src/browser/setupWorker/setupWorker.ts +83 -120
- package/src/browser/setupWorker/start/createRequestListener.ts +20 -24
- package/src/browser/setupWorker/start/createResponseListener.ts +15 -22
- package/src/browser/setupWorker/start/createStartHandler.ts +24 -18
- package/src/browser/setupWorker/start/utils/enableMocking.ts +18 -21
- package/src/browser/setupWorker/start/utils/printStartMessage.ts +0 -2
- package/src/browser/utils/checkWorkerIntegrity.ts +22 -14
- package/src/browser/utils/workerChannel.ts +146 -0
- package/src/core/HttpResponse.ts +3 -3
- package/src/core/handlers/GraphQLHandler.test.ts +1 -1
- package/src/core/handlers/GraphQLHandler.ts +0 -3
- package/src/core/handlers/HttpHandler.ts +0 -2
- package/src/core/utils/cookieStore.ts +56 -198
- package/src/core/utils/handleRequest.ts +1 -1
- package/src/core/utils/internal/devUtils.ts +0 -2
- package/src/core/utils/internal/getCallFrame.ts +2 -2
- package/src/core/utils/internal/parseGraphQLRequest.ts +1 -0
- package/src/core/utils/matching/matchRequestUrl.ts +2 -2
- package/src/core/utils/request/getRequestCookies.ts +1 -1
- package/src/core/utils/request/onUnhandledRequest.test.ts +1 -1
- package/src/core/utils/request/storeResponseCookies.ts +3 -3
- package/src/core/utils/request/toPublicUrl.test.ts +1 -1
- package/src/core/utils/url/cleanUrl.ts +1 -1
- package/src/core/utils/url/isAbsoluteUrl.ts +1 -1
- package/src/core/ws/WebSocketClientManager.test.ts +1 -1
- package/src/core/ws/WebSocketIndexedDBClientStore.ts +0 -4
- package/src/core/ws/utils/attachWebSocketLogger.ts +0 -14
- package/src/mockServiceWorker.js +14 -10
- package/src/node/SetupServerApi.ts +1 -1
- package/src/browser/setupWorker/start/createFallbackStart.ts +0 -21
- package/src/browser/setupWorker/start/utils/createMessageChannel.ts +0 -32
- package/src/browser/setupWorker/stop/createFallbackStop.ts +0 -11
- 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
|
+
}
|
package/src/core/HttpResponse.ts
CHANGED
|
@@ -161,10 +161,10 @@ export class HttpResponse<
|
|
|
161
161
|
*
|
|
162
162
|
* HttpResponse.arrayBuffer(buffer)
|
|
163
163
|
*/
|
|
164
|
-
static arrayBuffer(
|
|
165
|
-
body?:
|
|
164
|
+
static arrayBuffer<BodyType extends ArrayBuffer | SharedArrayBuffer>(
|
|
165
|
+
body?: BodyType,
|
|
166
166
|
init?: HttpResponseInit,
|
|
167
|
-
): HttpResponse<
|
|
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
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
164
|
-
try {
|
|
165
|
-
const json = this.storage.getItem(this.storageKey)
|
|
53
|
+
const cookies: MemoryCookieStoreIndex = {}
|
|
166
54
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
55
|
+
for (const rawCookie of rawCookies) {
|
|
56
|
+
const cookie = Cookie.fromJSON(rawCookie)
|
|
170
57
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
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
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
73
|
+
const data = []
|
|
74
|
+
const { idx } = this.#memoryStore
|
|
206
75
|
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
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
|
|
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 = /[
|
|
2
|
+
const SOURCE_FRAME = /[/\\]msw[/\\]src[/\\](.+)/
|
|
3
3
|
|
|
4
4
|
const BUILD_FRAME =
|
|
5
|
-
/(node_modules)?[
|
|
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.
|
|
@@ -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(/([
|
|
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(/^([
|
|
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.
|
|
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: {
|
|
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
|
|
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
|
)
|
|
@@ -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
|
|
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(
|