msw 0.38.2 → 0.39.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/esm/index.js +48 -20
- package/lib/esm/mockServiceWorker.js +1 -1
- package/lib/iife/index.js +2 -2
- package/lib/iife/mockServiceWorker.js +1 -1
- package/lib/types/setupWorker/glossary.d.ts +8 -2
- package/lib/types/utils/request/setRequestCookies.d.ts +7 -0
- package/lib/umd/index.js +48 -20
- package/lib/umd/mockServiceWorker.js +1 -1
- package/native/lib/index.js +229 -217
- package/node/lib/index.js +229 -217
- package/package.json +12 -6
|
@@ -85,20 +85,26 @@ export declare type ServiceWorkerInstanceTuple = [
|
|
|
85
85
|
export declare type FindWorker = (scriptUrl: string, mockServiceWorkerUrl: string) => boolean;
|
|
86
86
|
export interface StartOptions extends SharedOptions {
|
|
87
87
|
/**
|
|
88
|
-
* Service Worker
|
|
88
|
+
* Service Worker registration options.
|
|
89
89
|
*/
|
|
90
90
|
serviceWorker?: {
|
|
91
|
+
/**
|
|
92
|
+
* Custom url to the worker script.
|
|
93
|
+
* @default "./mockServiceWorker.js"
|
|
94
|
+
*/
|
|
91
95
|
url?: string;
|
|
92
96
|
options?: RegistrationOptions;
|
|
93
97
|
};
|
|
94
98
|
/**
|
|
95
99
|
* Disables the logging of captured requests
|
|
96
100
|
* into browser's console.
|
|
101
|
+
* @default false
|
|
97
102
|
*/
|
|
98
103
|
quiet?: boolean;
|
|
99
104
|
/**
|
|
100
105
|
* Defers any network requests until the Service Worker
|
|
101
|
-
* instance is
|
|
106
|
+
* instance is activated.
|
|
107
|
+
* @default true
|
|
102
108
|
*/
|
|
103
109
|
waitUntilReady?: boolean;
|
|
104
110
|
/**
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
import { MockedRequest } from '../../handlers/RequestHandler';
|
|
2
|
+
/**
|
|
3
|
+
* Sets relevant cookies on the request.
|
|
4
|
+
* Request cookies are taken from the following sources:
|
|
5
|
+
* - Immediate (own) request cookies (those in the "Cookie" request header);
|
|
6
|
+
* - From the `document.cookie` based on the request's `credentials` value;
|
|
7
|
+
* - From the internal cookie store that persists/hydrates cookies in Node.js
|
|
8
|
+
*/
|
|
2
9
|
export declare function setRequestCookies(request: MockedRequest): void;
|
package/lib/umd/index.js
CHANGED
|
@@ -2463,13 +2463,36 @@ Invalid value has been removed from localStorage to prevent subsequent failed pa
|
|
|
2463
2463
|
}
|
|
2464
2464
|
}
|
|
2465
2465
|
|
|
2466
|
+
/**
|
|
2467
|
+
* Sets relevant cookies on the request.
|
|
2468
|
+
* Request cookies are taken from the following sources:
|
|
2469
|
+
* - Immediate (own) request cookies (those in the "Cookie" request header);
|
|
2470
|
+
* - From the `document.cookie` based on the request's `credentials` value;
|
|
2471
|
+
* - From the internal cookie store that persists/hydrates cookies in Node.js
|
|
2472
|
+
*/
|
|
2466
2473
|
function setRequestCookies(request) {
|
|
2467
2474
|
var _a;
|
|
2475
|
+
// Set mocked request cookies from the `cookie` header of the original request.
|
|
2476
|
+
// No need to take `credentials` into account, because in Node.js requests are intercepted
|
|
2477
|
+
// _after_ they happen. Request issuer should have already taken care of sending relevant cookies.
|
|
2478
|
+
// Unlike browser, where interception is on the worker level, _before_ the request happens.
|
|
2479
|
+
const requestCookiesString = request.headers.get('cookie');
|
|
2468
2480
|
lib$2.store.hydrate();
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2481
|
+
const cookiesFromStore = Array.from((_a = lib$2.store.get(Object.assign(Object.assign({}, request), { url: request.url.toString() }))) === null || _a === void 0 ? void 0 : _a.entries()).reduce((cookies, [name, { value }]) => {
|
|
2482
|
+
return Object.assign(cookies, { [name.trim()]: value });
|
|
2483
|
+
}, {});
|
|
2484
|
+
const cookiesFromDocument = getRequestCookies(request);
|
|
2485
|
+
const forwardedCookies = Object.assign(Object.assign({}, cookiesFromDocument), cookiesFromStore);
|
|
2486
|
+
// Ensure the persisted (document) cookies are propagated to the request.
|
|
2487
|
+
// Propagated the cookies persisted in the Cookuie Store to the request headers.
|
|
2488
|
+
// This forwards relevant request cookies based on the request's credentials.
|
|
2489
|
+
for (const [name, value] of Object.entries(forwardedCookies)) {
|
|
2490
|
+
request.headers.append('cookie', `${name}=${value}`);
|
|
2491
|
+
}
|
|
2492
|
+
const ownCookies = requestCookiesString
|
|
2493
|
+
? parse_1(requestCookiesString)
|
|
2494
|
+
: {};
|
|
2495
|
+
request.cookies = Object.assign(Object.assign(Object.assign({}, request.cookies), forwardedCookies), ownCookies);
|
|
2473
2496
|
}
|
|
2474
2497
|
|
|
2475
2498
|
function parseContentHeaders(headersString) {
|
|
@@ -26536,16 +26559,32 @@ This is necessary to ensure that the Service Worker is in sync with the library
|
|
|
26536
26559
|
If this message still persists after updating, please report an issue: https://github.com/open-draft/msw/issues\
|
|
26537
26560
|
`);
|
|
26538
26561
|
}
|
|
26539
|
-
yield enableMocking(context, options).catch((err) => {
|
|
26540
|
-
throw new Error(`Failed to enable mocking: ${err === null || err === void 0 ? void 0 : err.message}`);
|
|
26541
|
-
});
|
|
26542
26562
|
context.keepAliveInterval = window.setInterval(() => context.workerChannel.send('KEEPALIVE_REQUEST'), 5000);
|
|
26543
26563
|
// Warn the user when loading the page that lies outside
|
|
26544
26564
|
// of the worker's scope.
|
|
26545
26565
|
validateWorkerScope(registration, context.startOptions);
|
|
26546
26566
|
return registration;
|
|
26547
26567
|
});
|
|
26548
|
-
const workerRegistration = startWorkerInstance()
|
|
26568
|
+
const workerRegistration = startWorkerInstance().then((registration) => __awaiter$3(this, void 0, void 0, function* () {
|
|
26569
|
+
const pendingInstance = registration.installing || registration.waiting;
|
|
26570
|
+
// Wait until the worker is activated.
|
|
26571
|
+
// Assume the worker is already activated if there's no pending registration
|
|
26572
|
+
// (i.e. when reloading the page after a successful activation).
|
|
26573
|
+
if (pendingInstance) {
|
|
26574
|
+
yield new Promise((resolve) => {
|
|
26575
|
+
pendingInstance.addEventListener('statechange', () => {
|
|
26576
|
+
if (pendingInstance.state === 'activated') {
|
|
26577
|
+
return resolve();
|
|
26578
|
+
}
|
|
26579
|
+
});
|
|
26580
|
+
});
|
|
26581
|
+
}
|
|
26582
|
+
// Print the activation message only after the worker has been activated.
|
|
26583
|
+
yield enableMocking(context, options).catch((error) => {
|
|
26584
|
+
throw new Error(`Failed to enable mocking: ${error === null || error === void 0 ? void 0 : error.message}`);
|
|
26585
|
+
});
|
|
26586
|
+
return registration;
|
|
26587
|
+
}));
|
|
26549
26588
|
// Defer any network requests until the Service Worker instance is ready.
|
|
26550
26589
|
// This prevents a race condition between the Service Worker registration
|
|
26551
26590
|
// and application's runtime requests (i.e. requests on mount).
|
|
@@ -31217,6 +31256,7 @@ If this message still persists after updating, please report an issue: https://g
|
|
|
31217
31256
|
url: request.url,
|
|
31218
31257
|
method: request.method,
|
|
31219
31258
|
body: parseBody(request.body, request.headers),
|
|
31259
|
+
credentials: request.credentials || 'same-origin',
|
|
31220
31260
|
headers: request.headers,
|
|
31221
31261
|
cookies: {},
|
|
31222
31262
|
redirect: 'manual',
|
|
@@ -31228,21 +31268,9 @@ If this message still persists after updating, please report an issue: https://g
|
|
|
31228
31268
|
integrity: '',
|
|
31229
31269
|
destination: 'document',
|
|
31230
31270
|
bodyUsed: false,
|
|
31231
|
-
credentials: 'same-origin',
|
|
31232
31271
|
};
|
|
31233
|
-
// Set mocked request cookies from the `cookie` header of the original request.
|
|
31234
|
-
// No need to take `credentials` into account, because in Node.js requests are intercepted
|
|
31235
|
-
// _after_ they happen. Request issuer should have already taken care of sending relevant cookies.
|
|
31236
|
-
// Unlike browser, where interception is on the worker level, _before_ the request happens.
|
|
31237
|
-
const requestCookiesString = request.headers.get('cookie');
|
|
31238
31272
|
// Attach all the cookies from the virtual cookie store.
|
|
31239
31273
|
setRequestCookies(mockedRequest);
|
|
31240
|
-
const requestCookies = requestCookiesString
|
|
31241
|
-
? parse_1(requestCookiesString)
|
|
31242
|
-
: {};
|
|
31243
|
-
// Merge both direct request cookies and the cookies inherited
|
|
31244
|
-
// from other same-origin requests in the cookie store.
|
|
31245
|
-
mockedRequest.cookies = Object.assign(Object.assign({}, mockedRequest.cookies), requestCookies);
|
|
31246
31274
|
return mockedRequest;
|
|
31247
31275
|
}
|
|
31248
31276
|
|
package/native/lib/index.js
CHANGED
|
@@ -161,207 +161,6 @@ function resetHandlers(initialHandlers, ...nextHandlers) {
|
|
|
161
161
|
return nextHandlers.length > 0 ? [...nextHandlers] : [...initialHandlers];
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
/*!
|
|
165
|
-
* cookie
|
|
166
|
-
* Copyright(c) 2012-2014 Roman Shtylman
|
|
167
|
-
* Copyright(c) 2015 Douglas Christopher Wilson
|
|
168
|
-
* MIT Licensed
|
|
169
|
-
*/
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Module exports.
|
|
173
|
-
* @public
|
|
174
|
-
*/
|
|
175
|
-
|
|
176
|
-
var parse_1 = parse$2;
|
|
177
|
-
var serialize_1 = serialize;
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Module variables.
|
|
181
|
-
* @private
|
|
182
|
-
*/
|
|
183
|
-
|
|
184
|
-
var decode = decodeURIComponent;
|
|
185
|
-
var encode = encodeURIComponent;
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* RegExp to match field-content in RFC 7230 sec 3.2
|
|
189
|
-
*
|
|
190
|
-
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
|
191
|
-
* field-vchar = VCHAR / obs-text
|
|
192
|
-
* obs-text = %x80-FF
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
|
-
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Parse a cookie header.
|
|
199
|
-
*
|
|
200
|
-
* Parse the given cookie header string into an object
|
|
201
|
-
* The object has the various cookies as keys(names) => values
|
|
202
|
-
*
|
|
203
|
-
* @param {string} str
|
|
204
|
-
* @param {object} [options]
|
|
205
|
-
* @return {object}
|
|
206
|
-
* @public
|
|
207
|
-
*/
|
|
208
|
-
|
|
209
|
-
function parse$2(str, options) {
|
|
210
|
-
if (typeof str !== 'string') {
|
|
211
|
-
throw new TypeError('argument str must be a string');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
var obj = {};
|
|
215
|
-
var opt = options || {};
|
|
216
|
-
var pairs = str.split(';');
|
|
217
|
-
var dec = opt.decode || decode;
|
|
218
|
-
|
|
219
|
-
for (var i = 0; i < pairs.length; i++) {
|
|
220
|
-
var pair = pairs[i];
|
|
221
|
-
var index = pair.indexOf('=');
|
|
222
|
-
|
|
223
|
-
// skip things that don't look like key=value
|
|
224
|
-
if (index < 0) {
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
var key = pair.substring(0, index).trim();
|
|
229
|
-
|
|
230
|
-
// only assign once
|
|
231
|
-
if (undefined == obj[key]) {
|
|
232
|
-
var val = pair.substring(index + 1, pair.length).trim();
|
|
233
|
-
|
|
234
|
-
// quoted values
|
|
235
|
-
if (val[0] === '"') {
|
|
236
|
-
val = val.slice(1, -1);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
obj[key] = tryDecode(val, dec);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return obj;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Serialize data into a cookie header.
|
|
248
|
-
*
|
|
249
|
-
* Serialize the a name value pair into a cookie string suitable for
|
|
250
|
-
* http headers. An optional options object specified cookie parameters.
|
|
251
|
-
*
|
|
252
|
-
* serialize('foo', 'bar', { httpOnly: true })
|
|
253
|
-
* => "foo=bar; httpOnly"
|
|
254
|
-
*
|
|
255
|
-
* @param {string} name
|
|
256
|
-
* @param {string} val
|
|
257
|
-
* @param {object} [options]
|
|
258
|
-
* @return {string}
|
|
259
|
-
* @public
|
|
260
|
-
*/
|
|
261
|
-
|
|
262
|
-
function serialize(name, val, options) {
|
|
263
|
-
var opt = options || {};
|
|
264
|
-
var enc = opt.encode || encode;
|
|
265
|
-
|
|
266
|
-
if (typeof enc !== 'function') {
|
|
267
|
-
throw new TypeError('option encode is invalid');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (!fieldContentRegExp.test(name)) {
|
|
271
|
-
throw new TypeError('argument name is invalid');
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
var value = enc(val);
|
|
275
|
-
|
|
276
|
-
if (value && !fieldContentRegExp.test(value)) {
|
|
277
|
-
throw new TypeError('argument val is invalid');
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
var str = name + '=' + value;
|
|
281
|
-
|
|
282
|
-
if (null != opt.maxAge) {
|
|
283
|
-
var maxAge = opt.maxAge - 0;
|
|
284
|
-
|
|
285
|
-
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
286
|
-
throw new TypeError('option maxAge is invalid')
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
str += '; Max-Age=' + Math.floor(maxAge);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (opt.domain) {
|
|
293
|
-
if (!fieldContentRegExp.test(opt.domain)) {
|
|
294
|
-
throw new TypeError('option domain is invalid');
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
str += '; Domain=' + opt.domain;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (opt.path) {
|
|
301
|
-
if (!fieldContentRegExp.test(opt.path)) {
|
|
302
|
-
throw new TypeError('option path is invalid');
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
str += '; Path=' + opt.path;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (opt.expires) {
|
|
309
|
-
if (typeof opt.expires.toUTCString !== 'function') {
|
|
310
|
-
throw new TypeError('option expires is invalid');
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
str += '; Expires=' + opt.expires.toUTCString();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (opt.httpOnly) {
|
|
317
|
-
str += '; HttpOnly';
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (opt.secure) {
|
|
321
|
-
str += '; Secure';
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (opt.sameSite) {
|
|
325
|
-
var sameSite = typeof opt.sameSite === 'string'
|
|
326
|
-
? opt.sameSite.toLowerCase() : opt.sameSite;
|
|
327
|
-
|
|
328
|
-
switch (sameSite) {
|
|
329
|
-
case true:
|
|
330
|
-
str += '; SameSite=Strict';
|
|
331
|
-
break;
|
|
332
|
-
case 'lax':
|
|
333
|
-
str += '; SameSite=Lax';
|
|
334
|
-
break;
|
|
335
|
-
case 'strict':
|
|
336
|
-
str += '; SameSite=Strict';
|
|
337
|
-
break;
|
|
338
|
-
case 'none':
|
|
339
|
-
str += '; SameSite=None';
|
|
340
|
-
break;
|
|
341
|
-
default:
|
|
342
|
-
throw new TypeError('option sameSite is invalid');
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return str;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Try decoding a string using a decoding function.
|
|
351
|
-
*
|
|
352
|
-
* @param {string} str
|
|
353
|
-
* @param {function} decode
|
|
354
|
-
* @private
|
|
355
|
-
*/
|
|
356
|
-
|
|
357
|
-
function tryDecode(str, decode) {
|
|
358
|
-
try {
|
|
359
|
-
return decode(str);
|
|
360
|
-
} catch (e) {
|
|
361
|
-
return str;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
164
|
/**
|
|
366
165
|
* Parses a given value into a JSON.
|
|
367
166
|
* Does not throw an exception on an invalid JSON string.
|
|
@@ -1002,6 +801,207 @@ function parseBody(body, headers) {
|
|
|
1002
801
|
return body;
|
|
1003
802
|
}
|
|
1004
803
|
|
|
804
|
+
/*!
|
|
805
|
+
* cookie
|
|
806
|
+
* Copyright(c) 2012-2014 Roman Shtylman
|
|
807
|
+
* Copyright(c) 2015 Douglas Christopher Wilson
|
|
808
|
+
* MIT Licensed
|
|
809
|
+
*/
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Module exports.
|
|
813
|
+
* @public
|
|
814
|
+
*/
|
|
815
|
+
|
|
816
|
+
var parse_1 = parse$2;
|
|
817
|
+
var serialize_1 = serialize;
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Module variables.
|
|
821
|
+
* @private
|
|
822
|
+
*/
|
|
823
|
+
|
|
824
|
+
var decode = decodeURIComponent;
|
|
825
|
+
var encode = encodeURIComponent;
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* RegExp to match field-content in RFC 7230 sec 3.2
|
|
829
|
+
*
|
|
830
|
+
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
|
831
|
+
* field-vchar = VCHAR / obs-text
|
|
832
|
+
* obs-text = %x80-FF
|
|
833
|
+
*/
|
|
834
|
+
|
|
835
|
+
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Parse a cookie header.
|
|
839
|
+
*
|
|
840
|
+
* Parse the given cookie header string into an object
|
|
841
|
+
* The object has the various cookies as keys(names) => values
|
|
842
|
+
*
|
|
843
|
+
* @param {string} str
|
|
844
|
+
* @param {object} [options]
|
|
845
|
+
* @return {object}
|
|
846
|
+
* @public
|
|
847
|
+
*/
|
|
848
|
+
|
|
849
|
+
function parse$2(str, options) {
|
|
850
|
+
if (typeof str !== 'string') {
|
|
851
|
+
throw new TypeError('argument str must be a string');
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
var obj = {};
|
|
855
|
+
var opt = options || {};
|
|
856
|
+
var pairs = str.split(';');
|
|
857
|
+
var dec = opt.decode || decode;
|
|
858
|
+
|
|
859
|
+
for (var i = 0; i < pairs.length; i++) {
|
|
860
|
+
var pair = pairs[i];
|
|
861
|
+
var index = pair.indexOf('=');
|
|
862
|
+
|
|
863
|
+
// skip things that don't look like key=value
|
|
864
|
+
if (index < 0) {
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
var key = pair.substring(0, index).trim();
|
|
869
|
+
|
|
870
|
+
// only assign once
|
|
871
|
+
if (undefined == obj[key]) {
|
|
872
|
+
var val = pair.substring(index + 1, pair.length).trim();
|
|
873
|
+
|
|
874
|
+
// quoted values
|
|
875
|
+
if (val[0] === '"') {
|
|
876
|
+
val = val.slice(1, -1);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
obj[key] = tryDecode(val, dec);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
return obj;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* Serialize data into a cookie header.
|
|
888
|
+
*
|
|
889
|
+
* Serialize the a name value pair into a cookie string suitable for
|
|
890
|
+
* http headers. An optional options object specified cookie parameters.
|
|
891
|
+
*
|
|
892
|
+
* serialize('foo', 'bar', { httpOnly: true })
|
|
893
|
+
* => "foo=bar; httpOnly"
|
|
894
|
+
*
|
|
895
|
+
* @param {string} name
|
|
896
|
+
* @param {string} val
|
|
897
|
+
* @param {object} [options]
|
|
898
|
+
* @return {string}
|
|
899
|
+
* @public
|
|
900
|
+
*/
|
|
901
|
+
|
|
902
|
+
function serialize(name, val, options) {
|
|
903
|
+
var opt = options || {};
|
|
904
|
+
var enc = opt.encode || encode;
|
|
905
|
+
|
|
906
|
+
if (typeof enc !== 'function') {
|
|
907
|
+
throw new TypeError('option encode is invalid');
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
if (!fieldContentRegExp.test(name)) {
|
|
911
|
+
throw new TypeError('argument name is invalid');
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
var value = enc(val);
|
|
915
|
+
|
|
916
|
+
if (value && !fieldContentRegExp.test(value)) {
|
|
917
|
+
throw new TypeError('argument val is invalid');
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
var str = name + '=' + value;
|
|
921
|
+
|
|
922
|
+
if (null != opt.maxAge) {
|
|
923
|
+
var maxAge = opt.maxAge - 0;
|
|
924
|
+
|
|
925
|
+
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
926
|
+
throw new TypeError('option maxAge is invalid')
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
str += '; Max-Age=' + Math.floor(maxAge);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (opt.domain) {
|
|
933
|
+
if (!fieldContentRegExp.test(opt.domain)) {
|
|
934
|
+
throw new TypeError('option domain is invalid');
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
str += '; Domain=' + opt.domain;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (opt.path) {
|
|
941
|
+
if (!fieldContentRegExp.test(opt.path)) {
|
|
942
|
+
throw new TypeError('option path is invalid');
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
str += '; Path=' + opt.path;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (opt.expires) {
|
|
949
|
+
if (typeof opt.expires.toUTCString !== 'function') {
|
|
950
|
+
throw new TypeError('option expires is invalid');
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
str += '; Expires=' + opt.expires.toUTCString();
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
if (opt.httpOnly) {
|
|
957
|
+
str += '; HttpOnly';
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
if (opt.secure) {
|
|
961
|
+
str += '; Secure';
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (opt.sameSite) {
|
|
965
|
+
var sameSite = typeof opt.sameSite === 'string'
|
|
966
|
+
? opt.sameSite.toLowerCase() : opt.sameSite;
|
|
967
|
+
|
|
968
|
+
switch (sameSite) {
|
|
969
|
+
case true:
|
|
970
|
+
str += '; SameSite=Strict';
|
|
971
|
+
break;
|
|
972
|
+
case 'lax':
|
|
973
|
+
str += '; SameSite=Lax';
|
|
974
|
+
break;
|
|
975
|
+
case 'strict':
|
|
976
|
+
str += '; SameSite=Strict';
|
|
977
|
+
break;
|
|
978
|
+
case 'none':
|
|
979
|
+
str += '; SameSite=None';
|
|
980
|
+
break;
|
|
981
|
+
default:
|
|
982
|
+
throw new TypeError('option sameSite is invalid');
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
return str;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Try decoding a string using a decoding function.
|
|
991
|
+
*
|
|
992
|
+
* @param {string} str
|
|
993
|
+
* @param {function} decode
|
|
994
|
+
* @private
|
|
995
|
+
*/
|
|
996
|
+
|
|
997
|
+
function tryDecode(str, decode) {
|
|
998
|
+
try {
|
|
999
|
+
return decode(str);
|
|
1000
|
+
} catch (e) {
|
|
1001
|
+
return str;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
1005
|
function getAllCookies() {
|
|
1006
1006
|
return parse_1(document.cookie);
|
|
1007
1007
|
}
|
|
@@ -1031,13 +1031,36 @@ function getRequestCookies(request) {
|
|
|
1031
1031
|
}
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
/**
|
|
1035
|
+
* Sets relevant cookies on the request.
|
|
1036
|
+
* Request cookies are taken from the following sources:
|
|
1037
|
+
* - Immediate (own) request cookies (those in the "Cookie" request header);
|
|
1038
|
+
* - From the `document.cookie` based on the request's `credentials` value;
|
|
1039
|
+
* - From the internal cookie store that persists/hydrates cookies in Node.js
|
|
1040
|
+
*/
|
|
1034
1041
|
function setRequestCookies(request) {
|
|
1035
1042
|
var _a;
|
|
1043
|
+
// Set mocked request cookies from the `cookie` header of the original request.
|
|
1044
|
+
// No need to take `credentials` into account, because in Node.js requests are intercepted
|
|
1045
|
+
// _after_ they happen. Request issuer should have already taken care of sending relevant cookies.
|
|
1046
|
+
// Unlike browser, where interception is on the worker level, _before_ the request happens.
|
|
1047
|
+
const requestCookiesString = request.headers.get('cookie');
|
|
1036
1048
|
cookies.store.hydrate();
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1049
|
+
const cookiesFromStore = Array.from((_a = cookies.store.get(Object.assign(Object.assign({}, request), { url: request.url.toString() }))) === null || _a === void 0 ? void 0 : _a.entries()).reduce((cookies, [name, { value }]) => {
|
|
1050
|
+
return Object.assign(cookies, { [name.trim()]: value });
|
|
1051
|
+
}, {});
|
|
1052
|
+
const cookiesFromDocument = getRequestCookies(request);
|
|
1053
|
+
const forwardedCookies = Object.assign(Object.assign({}, cookiesFromDocument), cookiesFromStore);
|
|
1054
|
+
// Ensure the persisted (document) cookies are propagated to the request.
|
|
1055
|
+
// Propagated the cookies persisted in the Cookuie Store to the request headers.
|
|
1056
|
+
// This forwards relevant request cookies based on the request's credentials.
|
|
1057
|
+
for (const [name, value] of Object.entries(forwardedCookies)) {
|
|
1058
|
+
request.headers.append('cookie', `${name}=${value}`);
|
|
1059
|
+
}
|
|
1060
|
+
const ownCookies = requestCookiesString
|
|
1061
|
+
? parse_1(requestCookiesString)
|
|
1062
|
+
: {};
|
|
1063
|
+
request.cookies = Object.assign(Object.assign(Object.assign({}, request.cookies), forwardedCookies), ownCookies);
|
|
1041
1064
|
}
|
|
1042
1065
|
|
|
1043
1066
|
/**
|
|
@@ -1049,6 +1072,7 @@ function parseIsomorphicRequest(request) {
|
|
|
1049
1072
|
url: request.url,
|
|
1050
1073
|
method: request.method,
|
|
1051
1074
|
body: parseBody(request.body, request.headers),
|
|
1075
|
+
credentials: request.credentials || 'same-origin',
|
|
1052
1076
|
headers: request.headers,
|
|
1053
1077
|
cookies: {},
|
|
1054
1078
|
redirect: 'manual',
|
|
@@ -1060,21 +1084,9 @@ function parseIsomorphicRequest(request) {
|
|
|
1060
1084
|
integrity: '',
|
|
1061
1085
|
destination: 'document',
|
|
1062
1086
|
bodyUsed: false,
|
|
1063
|
-
credentials: 'same-origin',
|
|
1064
1087
|
};
|
|
1065
|
-
// Set mocked request cookies from the `cookie` header of the original request.
|
|
1066
|
-
// No need to take `credentials` into account, because in Node.js requests are intercepted
|
|
1067
|
-
// _after_ they happen. Request issuer should have already taken care of sending relevant cookies.
|
|
1068
|
-
// Unlike browser, where interception is on the worker level, _before_ the request happens.
|
|
1069
|
-
const requestCookiesString = request.headers.get('cookie');
|
|
1070
1088
|
// Attach all the cookies from the virtual cookie store.
|
|
1071
1089
|
setRequestCookies(mockedRequest);
|
|
1072
|
-
const requestCookies = requestCookiesString
|
|
1073
|
-
? parse_1(requestCookiesString)
|
|
1074
|
-
: {};
|
|
1075
|
-
// Merge both direct request cookies and the cookies inherited
|
|
1076
|
-
// from other same-origin requests in the cookie store.
|
|
1077
|
-
mockedRequest.cookies = Object.assign(Object.assign({}, mockedRequest.cookies), requestCookies);
|
|
1078
1090
|
return mockedRequest;
|
|
1079
1091
|
}
|
|
1080
1092
|
|