msw 0.39.1 → 0.40.1

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 (34) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/esm/graphql-deps.js +4 -10
  3. package/lib/esm/graphql.js +2 -2
  4. package/lib/esm/index.js +82 -26
  5. package/lib/esm/{RequestHandler-deps.js → matchRequestUrl-deps.js} +192 -173
  6. package/lib/esm/mockServiceWorker.js +1 -1
  7. package/lib/esm/rest-deps.js +4 -10
  8. package/lib/esm/rest.js +1 -1
  9. package/lib/iife/index.js +2 -2
  10. package/lib/iife/mockServiceWorker.js +1 -1
  11. package/lib/types/handlers/GraphQLHandler.d.ts +2 -10
  12. package/lib/types/handlers/RequestHandler.d.ts +18 -8
  13. package/lib/types/handlers/RestHandler.d.ts +5 -9
  14. package/lib/types/index.d.ts +1 -1
  15. package/lib/types/native/index.d.ts +1 -1
  16. package/lib/types/node/setupServer.d.ts +1 -1
  17. package/lib/types/response.d.ts +4 -2
  18. package/lib/types/rest.d.ts +9 -9
  19. package/lib/types/setupWorker/glossary.d.ts +1 -0
  20. package/lib/types/setupWorker/start/utils/printStartMessage.d.ts +3 -2
  21. package/lib/types/sharedOptions.d.ts +1 -0
  22. package/lib/types/utils/getResponse.d.ts +1 -1
  23. package/lib/types/utils/handleRequest.d.ts +2 -2
  24. package/lib/types/utils/internal/requestHandlerUtils.d.ts +1 -1
  25. package/lib/types/utils/logging/prepareRequest.d.ts +2 -1
  26. package/lib/types/utils/matching/matchRequestUrl.d.ts +3 -1
  27. package/lib/types/utils/request/setRequestCookies.d.ts +7 -0
  28. package/lib/umd/index.js +274 -211
  29. package/lib/umd/mockServiceWorker.js +1 -1
  30. package/native/lib/index.js +789 -729
  31. package/native/package.json +1 -1
  32. package/node/lib/index.js +789 -729
  33. package/node/package.json +1 -1
  34. package/package.json +19 -9
package/node/lib/index.js CHANGED
@@ -1938,7 +1938,7 @@ chalk.stderr.supportsColor = stderrColor;
1938
1938
 
1939
1939
  var source = chalk;
1940
1940
 
1941
- var lib$3 = {exports: {}};
1941
+ var lib$4 = {exports: {}};
1942
1942
 
1943
1943
  (function (module, exports) {
1944
1944
  (function (global, factory) {
@@ -1961,9 +1961,9 @@ var lib$3 = {exports: {}};
1961
1961
  Object.defineProperty(exports, '__esModule', { value: true });
1962
1962
 
1963
1963
  })));
1964
- }(lib$3, lib$3.exports));
1964
+ }(lib$4, lib$4.exports));
1965
1965
 
1966
- var lib$2 = {};
1966
+ var lib$3 = {};
1967
1967
 
1968
1968
  var StrictEventEmitter$1 = {};
1969
1969
 
@@ -2033,7 +2033,7 @@ exports.__esModule = true;
2033
2033
  exports.StrictEventEmitter = void 0;
2034
2034
  var StrictEventEmitter_1 = StrictEventEmitter$1;
2035
2035
  __createBinding(exports, StrictEventEmitter_1, "StrictEventEmitter");
2036
- }(lib$2));
2036
+ }(lib$3));
2037
2037
 
2038
2038
  function use(currentHandlers, ...handlers) {
2039
2039
  currentHandlers.unshift(...handlers);
@@ -2047,221 +2047,7 @@ function resetHandlers(initialHandlers, ...nextHandlers) {
2047
2047
  return nextHandlers.length > 0 ? [...nextHandlers] : [...initialHandlers];
2048
2048
  }
2049
2049
 
2050
- /*!
2051
- * cookie
2052
- * Copyright(c) 2012-2014 Roman Shtylman
2053
- * Copyright(c) 2015 Douglas Christopher Wilson
2054
- * MIT Licensed
2055
- */
2056
-
2057
- /**
2058
- * Module exports.
2059
- * @public
2060
- */
2061
-
2062
- var parse_1 = parse$2;
2063
- var serialize_1 = serialize;
2064
-
2065
- /**
2066
- * Module variables.
2067
- * @private
2068
- */
2069
-
2070
- var decode = decodeURIComponent;
2071
- var encode = encodeURIComponent;
2072
-
2073
- /**
2074
- * RegExp to match field-content in RFC 7230 sec 3.2
2075
- *
2076
- * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
2077
- * field-vchar = VCHAR / obs-text
2078
- * obs-text = %x80-FF
2079
- */
2080
-
2081
- var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
2082
-
2083
- /**
2084
- * Parse a cookie header.
2085
- *
2086
- * Parse the given cookie header string into an object
2087
- * The object has the various cookies as keys(names) => values
2088
- *
2089
- * @param {string} str
2090
- * @param {object} [options]
2091
- * @return {object}
2092
- * @public
2093
- */
2094
-
2095
- function parse$2(str, options) {
2096
- if (typeof str !== 'string') {
2097
- throw new TypeError('argument str must be a string');
2098
- }
2099
-
2100
- var obj = {};
2101
- var opt = options || {};
2102
- var pairs = str.split(';');
2103
- var dec = opt.decode || decode;
2104
-
2105
- for (var i = 0; i < pairs.length; i++) {
2106
- var pair = pairs[i];
2107
- var index = pair.indexOf('=');
2108
-
2109
- // skip things that don't look like key=value
2110
- if (index < 0) {
2111
- continue;
2112
- }
2113
-
2114
- var key = pair.substring(0, index).trim();
2115
-
2116
- // only assign once
2117
- if (undefined == obj[key]) {
2118
- var val = pair.substring(index + 1, pair.length).trim();
2119
-
2120
- // quoted values
2121
- if (val[0] === '"') {
2122
- val = val.slice(1, -1);
2123
- }
2124
-
2125
- obj[key] = tryDecode(val, dec);
2126
- }
2127
- }
2128
-
2129
- return obj;
2130
- }
2131
-
2132
- /**
2133
- * Serialize data into a cookie header.
2134
- *
2135
- * Serialize the a name value pair into a cookie string suitable for
2136
- * http headers. An optional options object specified cookie parameters.
2137
- *
2138
- * serialize('foo', 'bar', { httpOnly: true })
2139
- * => "foo=bar; httpOnly"
2140
- *
2141
- * @param {string} name
2142
- * @param {string} val
2143
- * @param {object} [options]
2144
- * @return {string}
2145
- * @public
2146
- */
2147
-
2148
- function serialize(name, val, options) {
2149
- var opt = options || {};
2150
- var enc = opt.encode || encode;
2151
-
2152
- if (typeof enc !== 'function') {
2153
- throw new TypeError('option encode is invalid');
2154
- }
2155
-
2156
- if (!fieldContentRegExp.test(name)) {
2157
- throw new TypeError('argument name is invalid');
2158
- }
2159
-
2160
- var value = enc(val);
2161
-
2162
- if (value && !fieldContentRegExp.test(value)) {
2163
- throw new TypeError('argument val is invalid');
2164
- }
2165
-
2166
- var str = name + '=' + value;
2167
-
2168
- if (null != opt.maxAge) {
2169
- var maxAge = opt.maxAge - 0;
2170
-
2171
- if (isNaN(maxAge) || !isFinite(maxAge)) {
2172
- throw new TypeError('option maxAge is invalid')
2173
- }
2174
-
2175
- str += '; Max-Age=' + Math.floor(maxAge);
2176
- }
2177
-
2178
- if (opt.domain) {
2179
- if (!fieldContentRegExp.test(opt.domain)) {
2180
- throw new TypeError('option domain is invalid');
2181
- }
2182
-
2183
- str += '; Domain=' + opt.domain;
2184
- }
2185
-
2186
- if (opt.path) {
2187
- if (!fieldContentRegExp.test(opt.path)) {
2188
- throw new TypeError('option path is invalid');
2189
- }
2190
-
2191
- str += '; Path=' + opt.path;
2192
- }
2193
-
2194
- if (opt.expires) {
2195
- if (typeof opt.expires.toUTCString !== 'function') {
2196
- throw new TypeError('option expires is invalid');
2197
- }
2198
-
2199
- str += '; Expires=' + opt.expires.toUTCString();
2200
- }
2201
-
2202
- if (opt.httpOnly) {
2203
- str += '; HttpOnly';
2204
- }
2205
-
2206
- if (opt.secure) {
2207
- str += '; Secure';
2208
- }
2209
-
2210
- if (opt.sameSite) {
2211
- var sameSite = typeof opt.sameSite === 'string'
2212
- ? opt.sameSite.toLowerCase() : opt.sameSite;
2213
-
2214
- switch (sameSite) {
2215
- case true:
2216
- str += '; SameSite=Strict';
2217
- break;
2218
- case 'lax':
2219
- str += '; SameSite=Lax';
2220
- break;
2221
- case 'strict':
2222
- str += '; SameSite=Strict';
2223
- break;
2224
- case 'none':
2225
- str += '; SameSite=None';
2226
- break;
2227
- default:
2228
- throw new TypeError('option sameSite is invalid');
2229
- }
2230
- }
2231
-
2232
- return str;
2233
- }
2234
-
2235
- /**
2236
- * Try decoding a string using a decoding function.
2237
- *
2238
- * @param {string} str
2239
- * @param {function} decode
2240
- * @private
2241
- */
2242
-
2243
- function tryDecode(str, decode) {
2244
- try {
2245
- return decode(str);
2246
- } catch (e) {
2247
- return str;
2248
- }
2249
- }
2250
-
2251
- /**
2252
- * Parses a given value into a JSON.
2253
- * Does not throw an exception on an invalid JSON string.
2254
- */
2255
- function jsonParse(value) {
2256
- try {
2257
- return JSON.parse(value);
2258
- }
2259
- catch (error) {
2260
- return undefined;
2261
- }
2262
- }
2263
-
2264
- var lib$1 = {};
2050
+ var lib$2 = {};
2265
2051
 
2266
2052
  var Headers = {};
2267
2053
 
@@ -2788,46 +2574,457 @@ var flattenHeadersList_1 = flattenHeadersList$1;
2788
2574
  Object.defineProperty(exports, "flattenHeadersList", { enumerable: true, get: function () { return flattenHeadersList_1.flattenHeadersList; } });
2789
2575
  var flattenHeadersObject_1 = flattenHeadersObject$1;
2790
2576
  Object.defineProperty(exports, "flattenHeadersObject", { enumerable: true, get: function () { return flattenHeadersObject_1.flattenHeadersObject; } });
2791
- }(lib$1));
2577
+ }(lib$2));
2792
2578
 
2793
- function parseContentHeaders(headersString) {
2794
- var _a, _b;
2795
- const headers = lib$1.stringToHeaders(headersString);
2796
- const contentType = headers.get('content-type') || 'text/plain';
2797
- const disposition = headers.get('content-disposition');
2798
- if (!disposition) {
2799
- throw new Error('"Content-Disposition" header is required.');
2800
- }
2801
- const directives = disposition.split(';').reduce((acc, chunk) => {
2802
- const [name, ...rest] = chunk.trim().split('=');
2803
- acc[name] = rest.join('=');
2804
- return acc;
2805
- }, {});
2806
- const name = (_a = directives.name) === null || _a === void 0 ? void 0 : _a.slice(1, -1);
2807
- const filename = (_b = directives.filename) === null || _b === void 0 ? void 0 : _b.slice(1, -1);
2808
- return {
2809
- name,
2810
- filename,
2811
- contentType,
2812
- };
2813
- }
2814
2579
  /**
2815
- * Parses a given string as a multipart/form-data.
2816
- * Does not throw an exception on an invalid multipart string.
2580
+ * Composes a given list of functions into a new function that
2581
+ * executes from right to left.
2817
2582
  */
2818
- function parseMultipartData(data, headers) {
2819
- const contentType = headers === null || headers === void 0 ? void 0 : headers.get('content-type');
2820
- if (!contentType) {
2821
- return undefined;
2822
- }
2823
- const [, ...directives] = contentType.split(/; */);
2824
- const boundary = directives
2825
- .filter((d) => d.startsWith('boundary='))
2826
- .map((s) => s.replace(/^boundary=/, ''))[0];
2827
- if (!boundary) {
2828
- return undefined;
2829
- }
2830
- const boundaryRegExp = new RegExp(`--+${boundary}`);
2583
+ function compose(...fns) {
2584
+ return (...args) => {
2585
+ return fns.reduceRight((leftFn, rightFn) => {
2586
+ return leftFn instanceof Promise
2587
+ ? Promise.resolve(leftFn).then(rightFn)
2588
+ : rightFn(leftFn);
2589
+ }, args[0]);
2590
+ };
2591
+ }
2592
+
2593
+ class NetworkError extends Error {
2594
+ constructor(message) {
2595
+ super(message);
2596
+ this.name = 'NetworkError';
2597
+ }
2598
+ }
2599
+
2600
+ const defaultResponse = {
2601
+ status: 200,
2602
+ statusText: 'OK',
2603
+ body: null,
2604
+ delay: 0,
2605
+ once: false,
2606
+ passthrough: false,
2607
+ };
2608
+ const defaultResponseTransformers = [];
2609
+ function createResponseComposition(responseOverrides, defaultTransformers = defaultResponseTransformers) {
2610
+ return (...transformers) => __awaiter(this, void 0, void 0, function* () {
2611
+ const initialResponse = Object.assign({}, defaultResponse, {
2612
+ headers: new lib$2.Headers({
2613
+ 'x-powered-by': 'msw',
2614
+ }),
2615
+ }, responseOverrides);
2616
+ const resolvedTransformers = [
2617
+ ...defaultTransformers,
2618
+ ...transformers,
2619
+ ].filter(Boolean);
2620
+ const resolvedResponse = resolvedTransformers.length > 0
2621
+ ? compose(...resolvedTransformers)(initialResponse)
2622
+ : initialResponse;
2623
+ return resolvedResponse;
2624
+ });
2625
+ }
2626
+ const response = Object.assign(createResponseComposition(), {
2627
+ once: createResponseComposition({ once: true }),
2628
+ networkError(message) {
2629
+ throw new NetworkError(message);
2630
+ },
2631
+ });
2632
+
2633
+ const BUILD_FRAME = /(node_modules)?[\/\\]lib[\/\\](umd|esm|iief|cjs)[\/\\]|^[^\/\\]*$/;
2634
+ /**
2635
+ * Return the stack trace frame of a function's invocation.
2636
+ */
2637
+ function getCallFrame(error) {
2638
+ // In <IE11, new Error may return an undefined stack
2639
+ const stack = error.stack;
2640
+ if (!stack) {
2641
+ return;
2642
+ }
2643
+ const frames = stack.split('\n').slice(1);
2644
+ // Get the first frame that doesn't reference the library's internal trace.
2645
+ // Assume that frame is the invocation frame.
2646
+ const declarationFrame = frames.find((frame) => {
2647
+ return !BUILD_FRAME.test(frame);
2648
+ });
2649
+ if (!declarationFrame) {
2650
+ return;
2651
+ }
2652
+ // Extract file reference from the stack frame.
2653
+ const declarationPath = declarationFrame
2654
+ .replace(/\s*at [^()]*\(([^)]+)\)/, '$1')
2655
+ .replace(/^@/, '');
2656
+ return declarationPath;
2657
+ }
2658
+
2659
+ /**
2660
+ * Determines if the given function is an iterator.
2661
+ */
2662
+ function isIterable(fn) {
2663
+ if (!fn) {
2664
+ return false;
2665
+ }
2666
+ return typeof fn[Symbol.iterator] == 'function';
2667
+ }
2668
+
2669
+ var statuses = {
2670
+ "100": "Continue",
2671
+ "101": "Switching Protocols",
2672
+ "102": "Processing",
2673
+ "103": "Early Hints",
2674
+ "200": "OK",
2675
+ "201": "Created",
2676
+ "202": "Accepted",
2677
+ "203": "Non-Authoritative Information",
2678
+ "204": "No Content",
2679
+ "205": "Reset Content",
2680
+ "206": "Partial Content",
2681
+ "207": "Multi-Status",
2682
+ "208": "Already Reported",
2683
+ "226": "IM Used",
2684
+ "300": "Multiple Choices",
2685
+ "301": "Moved Permanently",
2686
+ "302": "Found",
2687
+ "303": "See Other",
2688
+ "304": "Not Modified",
2689
+ "305": "Use Proxy",
2690
+ "307": "Temporary Redirect",
2691
+ "308": "Permanent Redirect",
2692
+ "400": "Bad Request",
2693
+ "401": "Unauthorized",
2694
+ "402": "Payment Required",
2695
+ "403": "Forbidden",
2696
+ "404": "Not Found",
2697
+ "405": "Method Not Allowed",
2698
+ "406": "Not Acceptable",
2699
+ "407": "Proxy Authentication Required",
2700
+ "408": "Request Timeout",
2701
+ "409": "Conflict",
2702
+ "410": "Gone",
2703
+ "411": "Length Required",
2704
+ "412": "Precondition Failed",
2705
+ "413": "Payload Too Large",
2706
+ "414": "URI Too Long",
2707
+ "415": "Unsupported Media Type",
2708
+ "416": "Range Not Satisfiable",
2709
+ "417": "Expectation Failed",
2710
+ "418": "I'm a Teapot",
2711
+ "421": "Misdirected Request",
2712
+ "422": "Unprocessable Entity",
2713
+ "423": "Locked",
2714
+ "424": "Failed Dependency",
2715
+ "425": "Too Early",
2716
+ "426": "Upgrade Required",
2717
+ "428": "Precondition Required",
2718
+ "429": "Too Many Requests",
2719
+ "431": "Request Header Fields Too Large",
2720
+ "451": "Unavailable For Legal Reasons",
2721
+ "500": "Internal Server Error",
2722
+ "501": "Not Implemented",
2723
+ "502": "Bad Gateway",
2724
+ "503": "Service Unavailable",
2725
+ "504": "Gateway Timeout",
2726
+ "505": "HTTP Version Not Supported",
2727
+ "506": "Variant Also Negotiates",
2728
+ "507": "Insufficient Storage",
2729
+ "508": "Loop Detected",
2730
+ "509": "Bandwidth Limit Exceeded",
2731
+ "510": "Not Extended",
2732
+ "511": "Network Authentication Required"
2733
+ };
2734
+
2735
+ /**
2736
+ * Sets a response status code and text.
2737
+ * @example
2738
+ * res(ctx.status(301))
2739
+ * res(ctx.status(400, 'Custom status text'))
2740
+ * @see {@link https://mswjs.io/docs/api/context/status `ctx.status()`}
2741
+ */
2742
+ const status = (statusCode, statusText) => {
2743
+ return (res) => {
2744
+ res.status = statusCode;
2745
+ res.statusText =
2746
+ statusText || statuses[String(statusCode)];
2747
+ return res;
2748
+ };
2749
+ };
2750
+
2751
+ /**
2752
+ * Sets one or multiple response headers.
2753
+ * @example
2754
+ * ctx.set('Content-Type', 'text/plain')
2755
+ * ctx.set({
2756
+ * 'Accept': 'application/javascript',
2757
+ * 'Content-Type': "text/plain"
2758
+ * })
2759
+ * @see {@link https://mswjs.io/docs/api/context/set `ctx.set()`}
2760
+ */
2761
+ function set(...args) {
2762
+ return (res) => {
2763
+ const [name, value] = args;
2764
+ if (typeof name === 'string') {
2765
+ res.headers.append(name, value);
2766
+ }
2767
+ else {
2768
+ const headers = lib$2.objectToHeaders(name);
2769
+ headers.forEach((value, name) => {
2770
+ res.headers.append(name, value);
2771
+ });
2772
+ }
2773
+ return res;
2774
+ };
2775
+ }
2776
+
2777
+ const SET_TIMEOUT_MAX_ALLOWED_INT = 2147483647;
2778
+ const MIN_SERVER_RESPONSE_TIME = 100;
2779
+ const MAX_SERVER_RESPONSE_TIME = 400;
2780
+ const NODE_SERVER_RESPONSE_TIME = 5;
2781
+ const getRandomServerResponseTime = () => {
2782
+ if (lib$4.exports.isNodeProcess()) {
2783
+ return NODE_SERVER_RESPONSE_TIME;
2784
+ }
2785
+ return Math.floor(Math.random() * (MAX_SERVER_RESPONSE_TIME - MIN_SERVER_RESPONSE_TIME) +
2786
+ MIN_SERVER_RESPONSE_TIME);
2787
+ };
2788
+ /**
2789
+ * Delays the response by the given duration (ms).
2790
+ * @example
2791
+ * res(ctx.delay(1200)) // delay response by 1200ms
2792
+ * res(ctx.delay()) // emulate realistic server response time
2793
+ * res(ctx.delay('infinite')) // delay response infinitely
2794
+ * @see {@link https://mswjs.io/docs/api/context/delay `ctx.delay()`}
2795
+ */
2796
+ const delay = (durationOrMode) => {
2797
+ return (res) => {
2798
+ let delayTime;
2799
+ if (typeof durationOrMode === 'string') {
2800
+ switch (durationOrMode) {
2801
+ case 'infinite': {
2802
+ // Using `Infinity` as a delay value executes the response timeout immediately.
2803
+ // Instead, use the maximum allowed integer for `setTimeout`.
2804
+ delayTime = SET_TIMEOUT_MAX_ALLOWED_INT;
2805
+ break;
2806
+ }
2807
+ case 'real': {
2808
+ delayTime = getRandomServerResponseTime();
2809
+ break;
2810
+ }
2811
+ default: {
2812
+ throw new Error(`Failed to delay a response: unknown delay mode "${durationOrMode}". Please make sure you provide one of the supported modes ("real", "infinite") or a number to "ctx.delay".`);
2813
+ }
2814
+ }
2815
+ }
2816
+ else if (typeof durationOrMode === 'undefined') {
2817
+ // Use random realistic server response time when no explicit delay duration was provided.
2818
+ delayTime = getRandomServerResponseTime();
2819
+ }
2820
+ else {
2821
+ // Guard against passing values like `Infinity` or `Number.MAX_VALUE`
2822
+ // as the response delay duration. They don't produce the result you may expect.
2823
+ if (durationOrMode > SET_TIMEOUT_MAX_ALLOWED_INT) {
2824
+ throw new Error(`Failed to delay a response: provided delay duration (${durationOrMode}) exceeds the maximum allowed duration for "setTimeout" (${SET_TIMEOUT_MAX_ALLOWED_INT}). This will cause the response to be returned immediately. Please use a number within the allowed range to delay the response by exact duration, or consider the "infinite" delay mode to delay the response indefinitely.`);
2825
+ }
2826
+ delayTime = durationOrMode;
2827
+ }
2828
+ res.delay = delayTime;
2829
+ return res;
2830
+ };
2831
+ };
2832
+
2833
+ const useFetch = lib$4.exports.isNodeProcess() ? require('node-fetch') : window.fetch;
2834
+ const augmentRequestInit = (requestInit) => {
2835
+ const headers = new lib$2.Headers(requestInit.headers);
2836
+ headers.set('x-msw-bypass', 'true');
2837
+ return Object.assign(Object.assign({}, requestInit), { headers: headers.all() });
2838
+ };
2839
+ const createFetchRequestParameters = (input) => {
2840
+ const { body, method } = input;
2841
+ const requestParameters = Object.assign(Object.assign({}, input), { body: undefined });
2842
+ if (['GET', 'HEAD'].includes(method)) {
2843
+ return requestParameters;
2844
+ }
2845
+ if (typeof body === 'object' ||
2846
+ typeof body === 'number' ||
2847
+ typeof body === 'boolean') {
2848
+ requestParameters.body = JSON.stringify(body);
2849
+ }
2850
+ else {
2851
+ requestParameters.body = body;
2852
+ }
2853
+ return requestParameters;
2854
+ };
2855
+ /**
2856
+ * Performs a bypassed request inside a request handler.
2857
+ * @example
2858
+ * const originalResponse = await ctx.fetch(req)
2859
+ * @see {@link https://mswjs.io/docs/api/context/fetch `ctx.fetch()`}
2860
+ */
2861
+ const fetch = (input, requestInit = {}) => {
2862
+ if (typeof input === 'string') {
2863
+ return useFetch(input, augmentRequestInit(requestInit));
2864
+ }
2865
+ const requestParameters = createFetchRequestParameters(input);
2866
+ const derivedRequestInit = augmentRequestInit(requestParameters);
2867
+ return useFetch(input.url.href, derivedRequestInit);
2868
+ };
2869
+
2870
+ const defaultContext = {
2871
+ status,
2872
+ set,
2873
+ delay,
2874
+ fetch,
2875
+ };
2876
+ class RequestHandler {
2877
+ constructor(options) {
2878
+ this.shouldSkip = false;
2879
+ this.ctx = options.ctx || defaultContext;
2880
+ this.resolver = options.resolver;
2881
+ const callFrame = getCallFrame(new Error());
2882
+ this.info = Object.assign(Object.assign({}, options.info), { callFrame });
2883
+ }
2884
+ /**
2885
+ * Parse the captured request to extract additional information from it.
2886
+ * Parsed result is then exposed to other methods of this request handler.
2887
+ */
2888
+ parse(_request, _resolutionContext) {
2889
+ return null;
2890
+ }
2891
+ /**
2892
+ * Test if this handler matches the given request.
2893
+ */
2894
+ test(request, resolutionContext) {
2895
+ return this.predicate(request, this.parse(request, resolutionContext), resolutionContext);
2896
+ }
2897
+ /**
2898
+ * Derive the publicly exposed request (`req`) instance of the response resolver
2899
+ * from the captured request and its parsed result.
2900
+ */
2901
+ getPublicRequest(request, _parsedResult) {
2902
+ return request;
2903
+ }
2904
+ markAsSkipped(shouldSkip = true) {
2905
+ this.shouldSkip = shouldSkip;
2906
+ }
2907
+ /**
2908
+ * Execute this request handler and produce a mocked response
2909
+ * using the given resolver function.
2910
+ */
2911
+ run(request, resolutionContext) {
2912
+ return __awaiter(this, void 0, void 0, function* () {
2913
+ if (this.shouldSkip) {
2914
+ return null;
2915
+ }
2916
+ const parsedResult = this.parse(request, resolutionContext);
2917
+ const shouldIntercept = this.predicate(request, parsedResult, resolutionContext);
2918
+ if (!shouldIntercept) {
2919
+ return null;
2920
+ }
2921
+ const publicRequest = this.getPublicRequest(request, parsedResult);
2922
+ // Create a response extraction wrapper around the resolver
2923
+ // since it can be both an async function and a generator.
2924
+ const executeResolver = this.wrapResolver(this.resolver);
2925
+ const mockedResponse = yield executeResolver(publicRequest, response, this.ctx);
2926
+ return this.createExecutionResult(parsedResult, publicRequest, mockedResponse);
2927
+ });
2928
+ }
2929
+ wrapResolver(resolver) {
2930
+ return (req, res, ctx) => __awaiter(this, void 0, void 0, function* () {
2931
+ const result = this.resolverGenerator || (yield resolver(req, res, ctx));
2932
+ if (isIterable(result)) {
2933
+ const { value, done } = result[Symbol.iterator]().next();
2934
+ const nextResponse = yield value;
2935
+ // If the generator is done and there is no next value,
2936
+ // return the previous generator's value.
2937
+ if (!nextResponse && done) {
2938
+ return this.resolverGeneratorResult;
2939
+ }
2940
+ if (!this.resolverGenerator) {
2941
+ this.resolverGenerator = result;
2942
+ }
2943
+ this.resolverGeneratorResult = nextResponse;
2944
+ return nextResponse;
2945
+ }
2946
+ return result;
2947
+ });
2948
+ }
2949
+ createExecutionResult(parsedResult, request, response) {
2950
+ return {
2951
+ handler: this,
2952
+ parsedResult: parsedResult || null,
2953
+ request,
2954
+ response: response || null,
2955
+ };
2956
+ }
2957
+ }
2958
+ /**
2959
+ * Bypass this intercepted request.
2960
+ * This will make a call to the actual endpoint requested.
2961
+ */
2962
+ function passthrough() {
2963
+ // Constructing a dummy "101 Continue" mocked response
2964
+ // to keep the return type of the resolver consistent.
2965
+ return {
2966
+ status: 101,
2967
+ statusText: 'Continue',
2968
+ headers: new lib$2.Headers(),
2969
+ body: null,
2970
+ // Setting "passthrough" to true will signal the response pipeline
2971
+ // to perform this intercepted request as-is.
2972
+ passthrough: true,
2973
+ once: false,
2974
+ };
2975
+ }
2976
+
2977
+ /**
2978
+ * Parses a given value into a JSON.
2979
+ * Does not throw an exception on an invalid JSON string.
2980
+ */
2981
+ function jsonParse(value) {
2982
+ try {
2983
+ return JSON.parse(value);
2984
+ }
2985
+ catch (error) {
2986
+ return undefined;
2987
+ }
2988
+ }
2989
+
2990
+ function parseContentHeaders(headersString) {
2991
+ var _a, _b;
2992
+ const headers = lib$2.stringToHeaders(headersString);
2993
+ const contentType = headers.get('content-type') || 'text/plain';
2994
+ const disposition = headers.get('content-disposition');
2995
+ if (!disposition) {
2996
+ throw new Error('"Content-Disposition" header is required.');
2997
+ }
2998
+ const directives = disposition.split(';').reduce((acc, chunk) => {
2999
+ const [name, ...rest] = chunk.trim().split('=');
3000
+ acc[name] = rest.join('=');
3001
+ return acc;
3002
+ }, {});
3003
+ const name = (_a = directives.name) === null || _a === void 0 ? void 0 : _a.slice(1, -1);
3004
+ const filename = (_b = directives.filename) === null || _b === void 0 ? void 0 : _b.slice(1, -1);
3005
+ return {
3006
+ name,
3007
+ filename,
3008
+ contentType,
3009
+ };
3010
+ }
3011
+ /**
3012
+ * Parses a given string as a multipart/form-data.
3013
+ * Does not throw an exception on an invalid multipart string.
3014
+ */
3015
+ function parseMultipartData(data, headers) {
3016
+ const contentType = headers === null || headers === void 0 ? void 0 : headers.get('content-type');
3017
+ if (!contentType) {
3018
+ return undefined;
3019
+ }
3020
+ const [, ...directives] = contentType.split(/; */);
3021
+ const boundary = directives
3022
+ .filter((d) => d.startsWith('boundary='))
3023
+ .map((s) => s.replace(/^boundary=/, ''))[0];
3024
+ if (!boundary) {
3025
+ return undefined;
3026
+ }
3027
+ const boundaryRegExp = new RegExp(`--+${boundary}`);
2831
3028
  const fields = data
2832
3029
  .split(boundaryRegExp)
2833
3030
  .filter((chunk) => chunk.startsWith('\r\n') && chunk.endsWith('\r\n'))
@@ -2862,30 +3059,231 @@ function parseMultipartData(data, headers) {
2862
3059
  }
2863
3060
  }
2864
3061
 
2865
- /**
2866
- * Parses a given request/response body based on the "Content-Type" header.
2867
- */
2868
- function parseBody(body, headers) {
2869
- var _a;
2870
- // Return whatever falsey body value is given.
2871
- if (!body) {
2872
- return body;
2873
- }
2874
- const contentType = ((_a = headers === null || headers === void 0 ? void 0 : headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
2875
- // If the body has a Multipart Content-Type
2876
- // parse it into an object.
2877
- const hasMultipartContent = contentType.startsWith('multipart/form-data');
2878
- if (hasMultipartContent && typeof body !== 'object') {
2879
- return parseMultipartData(body.toString(), headers) || body;
2880
- }
2881
- // If the intercepted request's body has a JSON Content-Type
2882
- // parse it into an object.
2883
- const hasJsonContent = contentType.includes('json');
2884
- if (hasJsonContent && typeof body !== 'object') {
2885
- return jsonParse(body.toString()) || body;
2886
- }
2887
- // Otherwise leave as-is.
2888
- return body;
3062
+ /**
3063
+ * Parses a given request/response body based on the "Content-Type" header.
3064
+ */
3065
+ function parseBody(body, headers) {
3066
+ var _a;
3067
+ // Return whatever falsey body value is given.
3068
+ if (!body) {
3069
+ return body;
3070
+ }
3071
+ const contentType = ((_a = headers === null || headers === void 0 ? void 0 : headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
3072
+ // If the body has a Multipart Content-Type
3073
+ // parse it into an object.
3074
+ const hasMultipartContent = contentType.startsWith('multipart/form-data');
3075
+ if (hasMultipartContent && typeof body !== 'object') {
3076
+ return parseMultipartData(body.toString(), headers) || body;
3077
+ }
3078
+ // If the intercepted request's body has a JSON Content-Type
3079
+ // parse it into an object.
3080
+ const hasJsonContent = contentType.includes('json');
3081
+ if (hasJsonContent && typeof body !== 'object') {
3082
+ return jsonParse(body.toString()) || body;
3083
+ }
3084
+ // Otherwise leave as-is.
3085
+ return body;
3086
+ }
3087
+
3088
+ /*!
3089
+ * cookie
3090
+ * Copyright(c) 2012-2014 Roman Shtylman
3091
+ * Copyright(c) 2015 Douglas Christopher Wilson
3092
+ * MIT Licensed
3093
+ */
3094
+
3095
+ /**
3096
+ * Module exports.
3097
+ * @public
3098
+ */
3099
+
3100
+ var parse_1 = parse$2;
3101
+ var serialize_1 = serialize;
3102
+
3103
+ /**
3104
+ * Module variables.
3105
+ * @private
3106
+ */
3107
+
3108
+ var decode = decodeURIComponent;
3109
+ var encode = encodeURIComponent;
3110
+
3111
+ /**
3112
+ * RegExp to match field-content in RFC 7230 sec 3.2
3113
+ *
3114
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
3115
+ * field-vchar = VCHAR / obs-text
3116
+ * obs-text = %x80-FF
3117
+ */
3118
+
3119
+ var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
3120
+
3121
+ /**
3122
+ * Parse a cookie header.
3123
+ *
3124
+ * Parse the given cookie header string into an object
3125
+ * The object has the various cookies as keys(names) => values
3126
+ *
3127
+ * @param {string} str
3128
+ * @param {object} [options]
3129
+ * @return {object}
3130
+ * @public
3131
+ */
3132
+
3133
+ function parse$2(str, options) {
3134
+ if (typeof str !== 'string') {
3135
+ throw new TypeError('argument str must be a string');
3136
+ }
3137
+
3138
+ var obj = {};
3139
+ var opt = options || {};
3140
+ var pairs = str.split(';');
3141
+ var dec = opt.decode || decode;
3142
+
3143
+ for (var i = 0; i < pairs.length; i++) {
3144
+ var pair = pairs[i];
3145
+ var index = pair.indexOf('=');
3146
+
3147
+ // skip things that don't look like key=value
3148
+ if (index < 0) {
3149
+ continue;
3150
+ }
3151
+
3152
+ var key = pair.substring(0, index).trim();
3153
+
3154
+ // only assign once
3155
+ if (undefined == obj[key]) {
3156
+ var val = pair.substring(index + 1, pair.length).trim();
3157
+
3158
+ // quoted values
3159
+ if (val[0] === '"') {
3160
+ val = val.slice(1, -1);
3161
+ }
3162
+
3163
+ obj[key] = tryDecode(val, dec);
3164
+ }
3165
+ }
3166
+
3167
+ return obj;
3168
+ }
3169
+
3170
+ /**
3171
+ * Serialize data into a cookie header.
3172
+ *
3173
+ * Serialize the a name value pair into a cookie string suitable for
3174
+ * http headers. An optional options object specified cookie parameters.
3175
+ *
3176
+ * serialize('foo', 'bar', { httpOnly: true })
3177
+ * => "foo=bar; httpOnly"
3178
+ *
3179
+ * @param {string} name
3180
+ * @param {string} val
3181
+ * @param {object} [options]
3182
+ * @return {string}
3183
+ * @public
3184
+ */
3185
+
3186
+ function serialize(name, val, options) {
3187
+ var opt = options || {};
3188
+ var enc = opt.encode || encode;
3189
+
3190
+ if (typeof enc !== 'function') {
3191
+ throw new TypeError('option encode is invalid');
3192
+ }
3193
+
3194
+ if (!fieldContentRegExp.test(name)) {
3195
+ throw new TypeError('argument name is invalid');
3196
+ }
3197
+
3198
+ var value = enc(val);
3199
+
3200
+ if (value && !fieldContentRegExp.test(value)) {
3201
+ throw new TypeError('argument val is invalid');
3202
+ }
3203
+
3204
+ var str = name + '=' + value;
3205
+
3206
+ if (null != opt.maxAge) {
3207
+ var maxAge = opt.maxAge - 0;
3208
+
3209
+ if (isNaN(maxAge) || !isFinite(maxAge)) {
3210
+ throw new TypeError('option maxAge is invalid')
3211
+ }
3212
+
3213
+ str += '; Max-Age=' + Math.floor(maxAge);
3214
+ }
3215
+
3216
+ if (opt.domain) {
3217
+ if (!fieldContentRegExp.test(opt.domain)) {
3218
+ throw new TypeError('option domain is invalid');
3219
+ }
3220
+
3221
+ str += '; Domain=' + opt.domain;
3222
+ }
3223
+
3224
+ if (opt.path) {
3225
+ if (!fieldContentRegExp.test(opt.path)) {
3226
+ throw new TypeError('option path is invalid');
3227
+ }
3228
+
3229
+ str += '; Path=' + opt.path;
3230
+ }
3231
+
3232
+ if (opt.expires) {
3233
+ if (typeof opt.expires.toUTCString !== 'function') {
3234
+ throw new TypeError('option expires is invalid');
3235
+ }
3236
+
3237
+ str += '; Expires=' + opt.expires.toUTCString();
3238
+ }
3239
+
3240
+ if (opt.httpOnly) {
3241
+ str += '; HttpOnly';
3242
+ }
3243
+
3244
+ if (opt.secure) {
3245
+ str += '; Secure';
3246
+ }
3247
+
3248
+ if (opt.sameSite) {
3249
+ var sameSite = typeof opt.sameSite === 'string'
3250
+ ? opt.sameSite.toLowerCase() : opt.sameSite;
3251
+
3252
+ switch (sameSite) {
3253
+ case true:
3254
+ str += '; SameSite=Strict';
3255
+ break;
3256
+ case 'lax':
3257
+ str += '; SameSite=Lax';
3258
+ break;
3259
+ case 'strict':
3260
+ str += '; SameSite=Strict';
3261
+ break;
3262
+ case 'none':
3263
+ str += '; SameSite=None';
3264
+ break;
3265
+ default:
3266
+ throw new TypeError('option sameSite is invalid');
3267
+ }
3268
+ }
3269
+
3270
+ return str;
3271
+ }
3272
+
3273
+ /**
3274
+ * Try decoding a string using a decoding function.
3275
+ *
3276
+ * @param {string} str
3277
+ * @param {function} decode
3278
+ * @private
3279
+ */
3280
+
3281
+ function tryDecode(str, decode) {
3282
+ try {
3283
+ return decode(str);
3284
+ } catch (e) {
3285
+ return str;
3286
+ }
2889
3287
  }
2890
3288
 
2891
3289
  function getAllCookies() {
@@ -2917,13 +3315,36 @@ function getRequestCookies(request) {
2917
3315
  }
2918
3316
  }
2919
3317
 
3318
+ /**
3319
+ * Sets relevant cookies on the request.
3320
+ * Request cookies are taken from the following sources:
3321
+ * - Immediate (own) request cookies (those in the "Cookie" request header);
3322
+ * - From the `document.cookie` based on the request's `credentials` value;
3323
+ * - From the internal cookie store that persists/hydrates cookies in Node.js
3324
+ */
2920
3325
  function setRequestCookies(request) {
2921
3326
  var _a;
3327
+ // Set mocked request cookies from the `cookie` header of the original request.
3328
+ // No need to take `credentials` into account, because in Node.js requests are intercepted
3329
+ // _after_ they happen. Request issuer should have already taken care of sending relevant cookies.
3330
+ // Unlike browser, where interception is on the worker level, _before_ the request happens.
3331
+ const requestCookiesString = request.headers.get('cookie');
2922
3332
  cookies.store.hydrate();
2923
- request.cookies = Object.assign(Object.assign({}, getRequestCookies(request)), 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 }]) => Object.assign(cookies, { [name]: value }), {}));
2924
- request.headers.set('cookie', Object.entries(request.cookies)
2925
- .map(([name, value]) => `${name}=${value}`)
2926
- .join('; '));
3333
+ 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 }]) => {
3334
+ return Object.assign(cookies, { [name.trim()]: value });
3335
+ }, {});
3336
+ const cookiesFromDocument = getRequestCookies(request);
3337
+ const forwardedCookies = Object.assign(Object.assign({}, cookiesFromDocument), cookiesFromStore);
3338
+ // Ensure the persisted (document) cookies are propagated to the request.
3339
+ // Propagated the cookies persisted in the Cookuie Store to the request headers.
3340
+ // This forwards relevant request cookies based on the request's credentials.
3341
+ for (const [name, value] of Object.entries(forwardedCookies)) {
3342
+ request.headers.append('cookie', `${name}=${value}`);
3343
+ }
3344
+ const ownCookies = requestCookiesString
3345
+ ? parse_1(requestCookiesString)
3346
+ : {};
3347
+ request.cookies = Object.assign(Object.assign(Object.assign({}, request.cookies), forwardedCookies), ownCookies);
2927
3348
  }
2928
3349
 
2929
3350
  /**
@@ -2935,6 +3356,7 @@ function parseIsomorphicRequest(request) {
2935
3356
  url: request.url,
2936
3357
  method: request.method,
2937
3358
  body: parseBody(request.body, request.headers),
3359
+ credentials: request.credentials || 'same-origin',
2938
3360
  headers: request.headers,
2939
3361
  cookies: {},
2940
3362
  redirect: 'manual',
@@ -2946,24 +3368,39 @@ function parseIsomorphicRequest(request) {
2946
3368
  integrity: '',
2947
3369
  destination: 'document',
2948
3370
  bodyUsed: false,
2949
- credentials: 'same-origin',
3371
+ passthrough,
2950
3372
  };
2951
- // Set mocked request cookies from the `cookie` header of the original request.
2952
- // No need to take `credentials` into account, because in Node.js requests are intercepted
2953
- // _after_ they happen. Request issuer should have already taken care of sending relevant cookies.
2954
- // Unlike browser, where interception is on the worker level, _before_ the request happens.
2955
- const requestCookiesString = request.headers.get('cookie');
2956
3373
  // Attach all the cookies from the virtual cookie store.
2957
3374
  setRequestCookies(mockedRequest);
2958
- const requestCookies = requestCookiesString
2959
- ? parse_1(requestCookiesString)
2960
- : {};
2961
- // Merge both direct request cookies and the cookies inherited
2962
- // from other same-origin requests in the cookie store.
2963
- mockedRequest.cookies = Object.assign(Object.assign({}, mockedRequest.cookies), requestCookies);
2964
3375
  return mockedRequest;
2965
3376
  }
2966
3377
 
3378
+ var lib$1 = {};
3379
+
3380
+ var until$1 = {};
3381
+
3382
+ Object.defineProperty(until$1, "__esModule", { value: true });
3383
+ /**
3384
+ * Gracefully handles a given Promise factory.
3385
+ * @example
3386
+ * cosnt [error, data] = await until(() => asyncAction())
3387
+ */
3388
+ until$1.until = async (promise) => {
3389
+ try {
3390
+ const data = await promise().catch((error) => {
3391
+ throw error;
3392
+ });
3393
+ return [null, data];
3394
+ }
3395
+ catch (error) {
3396
+ return [error, null];
3397
+ }
3398
+ };
3399
+
3400
+ Object.defineProperty(lib$1, "__esModule", { value: true });
3401
+ var until_1 = until$1;
3402
+ var until = lib$1.until = until_1.until;
3403
+
2967
3404
  /**
2968
3405
  * Returns a mocked response for a given request using following request handlers.
2969
3406
  */
@@ -6702,114 +7139,6 @@ function isStringEqual(actual, expected) {
6702
7139
  return actual.toLowerCase() === expected.toLowerCase();
6703
7140
  }
6704
7141
 
6705
- var statuses = {
6706
- "100": "Continue",
6707
- "101": "Switching Protocols",
6708
- "102": "Processing",
6709
- "103": "Early Hints",
6710
- "200": "OK",
6711
- "201": "Created",
6712
- "202": "Accepted",
6713
- "203": "Non-Authoritative Information",
6714
- "204": "No Content",
6715
- "205": "Reset Content",
6716
- "206": "Partial Content",
6717
- "207": "Multi-Status",
6718
- "208": "Already Reported",
6719
- "226": "IM Used",
6720
- "300": "Multiple Choices",
6721
- "301": "Moved Permanently",
6722
- "302": "Found",
6723
- "303": "See Other",
6724
- "304": "Not Modified",
6725
- "305": "Use Proxy",
6726
- "307": "Temporary Redirect",
6727
- "308": "Permanent Redirect",
6728
- "400": "Bad Request",
6729
- "401": "Unauthorized",
6730
- "402": "Payment Required",
6731
- "403": "Forbidden",
6732
- "404": "Not Found",
6733
- "405": "Method Not Allowed",
6734
- "406": "Not Acceptable",
6735
- "407": "Proxy Authentication Required",
6736
- "408": "Request Timeout",
6737
- "409": "Conflict",
6738
- "410": "Gone",
6739
- "411": "Length Required",
6740
- "412": "Precondition Failed",
6741
- "413": "Payload Too Large",
6742
- "414": "URI Too Long",
6743
- "415": "Unsupported Media Type",
6744
- "416": "Range Not Satisfiable",
6745
- "417": "Expectation Failed",
6746
- "418": "I'm a Teapot",
6747
- "421": "Misdirected Request",
6748
- "422": "Unprocessable Entity",
6749
- "423": "Locked",
6750
- "424": "Failed Dependency",
6751
- "425": "Too Early",
6752
- "426": "Upgrade Required",
6753
- "428": "Precondition Required",
6754
- "429": "Too Many Requests",
6755
- "431": "Request Header Fields Too Large",
6756
- "451": "Unavailable For Legal Reasons",
6757
- "500": "Internal Server Error",
6758
- "501": "Not Implemented",
6759
- "502": "Bad Gateway",
6760
- "503": "Service Unavailable",
6761
- "504": "Gateway Timeout",
6762
- "505": "HTTP Version Not Supported",
6763
- "506": "Variant Also Negotiates",
6764
- "507": "Insufficient Storage",
6765
- "508": "Loop Detected",
6766
- "509": "Bandwidth Limit Exceeded",
6767
- "510": "Not Extended",
6768
- "511": "Network Authentication Required"
6769
- };
6770
-
6771
- /**
6772
- * Sets a response status code and text.
6773
- * @example
6774
- * res(ctx.status(301))
6775
- * res(ctx.status(400, 'Custom status text'))
6776
- * @see {@link https://mswjs.io/docs/api/context/status `ctx.status()`}
6777
- */
6778
- const status = (statusCode, statusText) => {
6779
- return (res) => {
6780
- res.status = statusCode;
6781
- res.statusText =
6782
- statusText || statuses[String(statusCode)];
6783
- return res;
6784
- };
6785
- };
6786
-
6787
- /**
6788
- * Sets one or multiple response headers.
6789
- * @example
6790
- * ctx.set('Content-Type', 'text/plain')
6791
- * ctx.set({
6792
- * 'Accept': 'application/javascript',
6793
- * 'Content-Type': "text/plain"
6794
- * })
6795
- * @see {@link https://mswjs.io/docs/api/context/set `ctx.set()`}
6796
- */
6797
- function set(...args) {
6798
- return (res) => {
6799
- const [name, value] = args;
6800
- if (typeof name === 'string') {
6801
- res.headers.append(name, value);
6802
- }
6803
- else {
6804
- const headers = lib$1.objectToHeaders(name);
6805
- headers.forEach((value, name) => {
6806
- res.headers.append(name, value);
6807
- });
6808
- }
6809
- return res;
6810
- };
6811
- }
6812
-
6813
7142
  /**
6814
7143
  * Sets a given cookie on the mocked response.
6815
7144
  * @example res(ctx.cookie('name', 'value'))
@@ -6879,95 +7208,39 @@ function mergeRight(left, right) {
6879
7208
  const json = (body) => {
6880
7209
  return (res) => {
6881
7210
  res.headers.set('Content-Type', 'application/json');
6882
- res.body = JSON.stringify(body);
6883
- return res;
6884
- };
6885
- };
6886
-
6887
- /**
6888
- * Sets a given payload as a GraphQL response body.
6889
- * @example
6890
- * res(ctx.data({ user: { firstName: 'John' }}))
6891
- * @see {@link https://mswjs.io/docs/api/context/data `ctx.data()`}
6892
- */
6893
- const data = (payload) => {
6894
- return (res) => {
6895
- const prevBody = jsonParse(res.body) || {};
6896
- const nextBody = mergeRight(prevBody, { data: payload });
6897
- return json(nextBody)(res);
6898
- };
6899
- };
6900
-
6901
- /**
6902
- * Sets the GraphQL extensions on a given response.
6903
- * @example
6904
- * res(ctx.extensions({ tracing: { version: 1 }}))
6905
- * @see {@link https://mswjs.io/docs/api/context/extensions `ctx.extensions()`}
6906
- */
6907
- const extensions = (payload) => {
6908
- return (res) => {
6909
- const prevBody = jsonParse(res.body) || {};
6910
- const nextBody = mergeRight(prevBody, { extensions: payload });
6911
- return json(nextBody)(res);
6912
- };
6913
- };
6914
-
6915
- const SET_TIMEOUT_MAX_ALLOWED_INT = 2147483647;
6916
- const MIN_SERVER_RESPONSE_TIME = 100;
6917
- const MAX_SERVER_RESPONSE_TIME = 400;
6918
- const NODE_SERVER_RESPONSE_TIME = 5;
6919
- const getRandomServerResponseTime = () => {
6920
- if (lib$3.exports.isNodeProcess()) {
6921
- return NODE_SERVER_RESPONSE_TIME;
6922
- }
6923
- return Math.floor(Math.random() * (MAX_SERVER_RESPONSE_TIME - MIN_SERVER_RESPONSE_TIME) +
6924
- MIN_SERVER_RESPONSE_TIME);
6925
- };
6926
- /**
6927
- * Delays the response by the given duration (ms).
6928
- * @example
6929
- * res(ctx.delay(1200)) // delay response by 1200ms
6930
- * res(ctx.delay()) // emulate realistic server response time
6931
- * res(ctx.delay('infinite')) // delay response infinitely
6932
- * @see {@link https://mswjs.io/docs/api/context/delay `ctx.delay()`}
6933
- */
6934
- const delay = (durationOrMode) => {
6935
- return (res) => {
6936
- let delayTime;
6937
- if (typeof durationOrMode === 'string') {
6938
- switch (durationOrMode) {
6939
- case 'infinite': {
6940
- // Using `Infinity` as a delay value executes the response timeout immediately.
6941
- // Instead, use the maximum allowed integer for `setTimeout`.
6942
- delayTime = SET_TIMEOUT_MAX_ALLOWED_INT;
6943
- break;
6944
- }
6945
- case 'real': {
6946
- delayTime = getRandomServerResponseTime();
6947
- break;
6948
- }
6949
- default: {
6950
- throw new Error(`Failed to delay a response: unknown delay mode "${durationOrMode}". Please make sure you provide one of the supported modes ("real", "infinite") or a number to "ctx.delay".`);
6951
- }
6952
- }
6953
- }
6954
- else if (typeof durationOrMode === 'undefined') {
6955
- // Use random realistic server response time when no explicit delay duration was provided.
6956
- delayTime = getRandomServerResponseTime();
6957
- }
6958
- else {
6959
- // Guard against passing values like `Infinity` or `Number.MAX_VALUE`
6960
- // as the response delay duration. They don't produce the result you may expect.
6961
- if (durationOrMode > SET_TIMEOUT_MAX_ALLOWED_INT) {
6962
- throw new Error(`Failed to delay a response: provided delay duration (${durationOrMode}) exceeds the maximum allowed duration for "setTimeout" (${SET_TIMEOUT_MAX_ALLOWED_INT}). This will cause the response to be returned immediately. Please use a number within the allowed range to delay the response by exact duration, or consider the "infinite" delay mode to delay the response indefinitely.`);
6963
- }
6964
- delayTime = durationOrMode;
6965
- }
6966
- res.delay = delayTime;
7211
+ res.body = JSON.stringify(body);
6967
7212
  return res;
6968
7213
  };
6969
7214
  };
6970
7215
 
7216
+ /**
7217
+ * Sets a given payload as a GraphQL response body.
7218
+ * @example
7219
+ * res(ctx.data({ user: { firstName: 'John' }}))
7220
+ * @see {@link https://mswjs.io/docs/api/context/data `ctx.data()`}
7221
+ */
7222
+ const data = (payload) => {
7223
+ return (res) => {
7224
+ const prevBody = jsonParse(res.body) || {};
7225
+ const nextBody = mergeRight(prevBody, { data: payload });
7226
+ return json(nextBody)(res);
7227
+ };
7228
+ };
7229
+
7230
+ /**
7231
+ * Sets the GraphQL extensions on a given response.
7232
+ * @example
7233
+ * res(ctx.extensions({ tracing: { version: 1 }}))
7234
+ * @see {@link https://mswjs.io/docs/api/context/extensions `ctx.extensions()`}
7235
+ */
7236
+ const extensions = (payload) => {
7237
+ return (res) => {
7238
+ const prevBody = jsonParse(res.body) || {};
7239
+ const nextBody = mergeRight(prevBody, { extensions: payload });
7240
+ return json(nextBody)(res);
7241
+ };
7242
+ };
7243
+
6971
7244
  /**
6972
7245
  * Sets a given list of GraphQL errors on the mocked response.
6973
7246
  * @example res(ctx.errors([{ message: 'Unauthorized' }]))
@@ -6984,43 +7257,6 @@ const errors = (errorsList) => {
6984
7257
  };
6985
7258
  };
6986
7259
 
6987
- const useFetch = lib$3.exports.isNodeProcess() ? require('node-fetch') : window.fetch;
6988
- const augmentRequestInit = (requestInit) => {
6989
- const headers = new lib$1.Headers(requestInit.headers);
6990
- headers.set('x-msw-bypass', 'true');
6991
- return Object.assign(Object.assign({}, requestInit), { headers: headers.all() });
6992
- };
6993
- const createFetchRequestParameters = (input) => {
6994
- const { body, method } = input;
6995
- const requestParameters = Object.assign(Object.assign({}, input), { body: undefined });
6996
- if (['GET', 'HEAD'].includes(method)) {
6997
- return requestParameters;
6998
- }
6999
- if (typeof body === 'object' ||
7000
- typeof body === 'number' ||
7001
- typeof body === 'boolean') {
7002
- requestParameters.body = JSON.stringify(body);
7003
- }
7004
- else {
7005
- requestParameters.body = body;
7006
- }
7007
- return requestParameters;
7008
- };
7009
- /**
7010
- * Performs a bypassed request inside a request handler.
7011
- * @example
7012
- * const originalResponse = await ctx.fetch(req)
7013
- * @see {@link https://mswjs.io/docs/api/context/fetch `ctx.fetch()`}
7014
- */
7015
- const fetch = (input, requestInit = {}) => {
7016
- if (typeof input === 'string') {
7017
- return useFetch(input, augmentRequestInit(requestInit));
7018
- }
7019
- const requestParameters = createFetchRequestParameters(input);
7020
- const derivedRequestInit = augmentRequestInit(requestParameters);
7021
- return useFetch(input.url.href, derivedRequestInit);
7022
- };
7023
-
7024
7260
  /**
7025
7261
  * Sets a textual response body. Appends a `Content-Type: text/plain`
7026
7262
  * header on the mocked response.
@@ -7092,7 +7328,7 @@ function prepareRequest(request) {
7092
7328
  * Formats a mocked response for introspection in the browser's console.
7093
7329
  */
7094
7330
  function prepareResponse(res) {
7095
- const responseHeaders = lib$1.objectToHeaders(res.headers);
7331
+ const responseHeaders = lib$2.objectToHeaders(res.headers);
7096
7332
  return Object.assign(Object.assign({}, res), {
7097
7333
  // Parse a response JSON body for preview in the logs
7098
7334
  body: parseBody(res.body, responseHeaders) });
@@ -7536,184 +7772,6 @@ function matchRequestUrl(url, path, baseUrl) {
7536
7772
  };
7537
7773
  }
7538
7774
 
7539
- /**
7540
- * Composes a given list of functions into a new function that
7541
- * executes from right to left.
7542
- */
7543
- function compose(...fns) {
7544
- return (...args) => {
7545
- return fns.reduceRight((leftFn, rightFn) => {
7546
- return leftFn instanceof Promise
7547
- ? Promise.resolve(leftFn).then(rightFn)
7548
- : rightFn(leftFn);
7549
- }, args[0]);
7550
- };
7551
- }
7552
-
7553
- class NetworkError extends Error {
7554
- constructor(message) {
7555
- super(message);
7556
- this.name = 'NetworkError';
7557
- }
7558
- }
7559
-
7560
- const defaultResponse = {
7561
- status: 200,
7562
- statusText: 'OK',
7563
- body: null,
7564
- delay: 0,
7565
- once: false,
7566
- };
7567
- const defaultResponseTransformers = [];
7568
- function createResponseComposition(responseOverrides, defaultTransformers = defaultResponseTransformers) {
7569
- return (...transformers) => __awaiter(this, void 0, void 0, function* () {
7570
- const initialResponse = Object.assign({}, defaultResponse, {
7571
- headers: new lib$1.Headers({
7572
- 'x-powered-by': 'msw',
7573
- }),
7574
- }, responseOverrides);
7575
- const resolvedTransformers = [
7576
- ...defaultTransformers,
7577
- ...transformers,
7578
- ].filter(Boolean);
7579
- const resolvedResponse = resolvedTransformers.length > 0
7580
- ? compose(...resolvedTransformers)(initialResponse)
7581
- : initialResponse;
7582
- return resolvedResponse;
7583
- });
7584
- }
7585
- const response = Object.assign(createResponseComposition(), {
7586
- once: createResponseComposition({ once: true }),
7587
- networkError(message) {
7588
- throw new NetworkError(message);
7589
- },
7590
- });
7591
-
7592
- const BUILD_FRAME = /(node_modules)?[\/\\]lib[\/\\](umd|esm|iief|cjs)[\/\\]|^[^\/\\]*$/;
7593
- /**
7594
- * Return the stack trace frame of a function's invocation.
7595
- */
7596
- function getCallFrame(error) {
7597
- // In <IE11, new Error may return an undefined stack
7598
- const stack = error.stack;
7599
- if (!stack) {
7600
- return;
7601
- }
7602
- const frames = stack.split('\n').slice(1);
7603
- // Get the first frame that doesn't reference the library's internal trace.
7604
- // Assume that frame is the invocation frame.
7605
- const declarationFrame = frames.find((frame) => {
7606
- return !BUILD_FRAME.test(frame);
7607
- });
7608
- if (!declarationFrame) {
7609
- return;
7610
- }
7611
- // Extract file reference from the stack frame.
7612
- const declarationPath = declarationFrame
7613
- .replace(/\s*at [^()]*\(([^)]+)\)/, '$1')
7614
- .replace(/^@/, '');
7615
- return declarationPath;
7616
- }
7617
-
7618
- /**
7619
- * Determines if the given function is an iterator.
7620
- */
7621
- function isIterable(fn) {
7622
- if (!fn) {
7623
- return false;
7624
- }
7625
- return typeof fn[Symbol.iterator] == 'function';
7626
- }
7627
-
7628
- const defaultContext = {
7629
- status,
7630
- set,
7631
- delay,
7632
- fetch,
7633
- };
7634
- class RequestHandler {
7635
- constructor(options) {
7636
- this.shouldSkip = false;
7637
- this.ctx = options.ctx || defaultContext;
7638
- this.resolver = options.resolver;
7639
- const callFrame = getCallFrame(new Error());
7640
- this.info = Object.assign(Object.assign({}, options.info), { callFrame });
7641
- }
7642
- /**
7643
- * Parse the captured request to extract additional information from it.
7644
- * Parsed result is then exposed to other methods of this request handler.
7645
- */
7646
- parse(_request, _resolutionContext) {
7647
- return null;
7648
- }
7649
- /**
7650
- * Test if this handler matches the given request.
7651
- */
7652
- test(request, resolutionContext) {
7653
- return this.predicate(request, this.parse(request, resolutionContext), resolutionContext);
7654
- }
7655
- /**
7656
- * Derive the publicly exposed request (`req`) instance of the response resolver
7657
- * from the captured request and its parsed result.
7658
- */
7659
- getPublicRequest(request, _parsedResult) {
7660
- return request;
7661
- }
7662
- markAsSkipped(shouldSkip = true) {
7663
- this.shouldSkip = shouldSkip;
7664
- }
7665
- /**
7666
- * Execute this request handler and produce a mocked response
7667
- * using the given resolver function.
7668
- */
7669
- run(request, resolutionContext) {
7670
- return __awaiter(this, void 0, void 0, function* () {
7671
- if (this.shouldSkip) {
7672
- return null;
7673
- }
7674
- const parsedResult = this.parse(request, resolutionContext);
7675
- const shouldIntercept = this.predicate(request, parsedResult, resolutionContext);
7676
- if (!shouldIntercept) {
7677
- return null;
7678
- }
7679
- const publicRequest = this.getPublicRequest(request, parsedResult);
7680
- // Create a response extraction wrapper around the resolver
7681
- // since it can be both an async function and a generator.
7682
- const executeResolver = this.wrapResolver(this.resolver);
7683
- const mockedResponse = yield executeResolver(publicRequest, response, this.ctx);
7684
- return this.createExecutionResult(parsedResult, publicRequest, mockedResponse);
7685
- });
7686
- }
7687
- wrapResolver(resolver) {
7688
- return (req, res, ctx) => __awaiter(this, void 0, void 0, function* () {
7689
- const result = this.resolverGenerator || (yield resolver(req, res, ctx));
7690
- if (isIterable(result)) {
7691
- const { value, done } = result[Symbol.iterator]().next();
7692
- const nextResponse = yield value;
7693
- // If the generator is done and there is no next value,
7694
- // return the previous generator's value.
7695
- if (!nextResponse && done) {
7696
- return this.resolverGeneratorResult;
7697
- }
7698
- if (!this.resolverGenerator) {
7699
- this.resolverGenerator = result;
7700
- }
7701
- this.resolverGeneratorResult = nextResponse;
7702
- return nextResponse;
7703
- }
7704
- return result;
7705
- });
7706
- }
7707
- createExecutionResult(parsedResult, request, response) {
7708
- return {
7709
- handler: this,
7710
- parsedResult: parsedResult || null,
7711
- request,
7712
- response: response || null,
7713
- };
7714
- }
7715
- }
7716
-
7717
7775
  var RESTMethods;
7718
7776
  (function (RESTMethods) {
7719
7777
  RESTMethods["HEAD"] = "HEAD";
@@ -7724,17 +7782,11 @@ var RESTMethods;
7724
7782
  RESTMethods["OPTIONS"] = "OPTIONS";
7725
7783
  RESTMethods["DELETE"] = "DELETE";
7726
7784
  })(RESTMethods || (RESTMethods = {}));
7727
- const restContext = {
7728
- set,
7729
- status,
7730
- cookie,
7785
+ const restContext = Object.assign(Object.assign({}, defaultContext), { cookie,
7731
7786
  body,
7732
7787
  text,
7733
7788
  json,
7734
- xml,
7735
- delay,
7736
- fetch,
7737
- };
7789
+ xml });
7738
7790
  /**
7739
7791
  * Request handler for REST API requests.
7740
7792
  * Provides request matching based on method and URL.
@@ -7805,16 +7857,10 @@ function tryCatch(fn, onException) {
7805
7857
  }
7806
7858
  }
7807
7859
 
7808
- const graphqlContext = {
7809
- set,
7810
- status,
7811
- delay,
7812
- fetch,
7813
- data,
7860
+ const graphqlContext = Object.assign(Object.assign({}, defaultContext), { data,
7814
7861
  extensions,
7815
7862
  errors,
7816
- cookie,
7817
- };
7863
+ cookie });
7818
7864
  function isDocumentNode(value) {
7819
7865
  if (value == null) {
7820
7866
  return false;
@@ -8034,17 +8080,24 @@ function readResponseCookies(request, response) {
8034
8080
  }
8035
8081
 
8036
8082
  function handleRequest(request, handlers, options, emitter, handleRequestOptions) {
8037
- var _a, _b, _c;
8083
+ var _a, _b, _c, _d;
8038
8084
  return __awaiter(this, void 0, void 0, function* () {
8039
8085
  emitter.emit('request:start', request);
8040
8086
  // Perform bypassed requests (i.e. issued via "ctx.fetch") as-is.
8041
8087
  if (request.headers.get('x-msw-bypass') === 'true') {
8042
8088
  emitter.emit('request:end', request);
8043
- (_a = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onBypassResponse) === null || _a === void 0 ? void 0 : _a.call(handleRequestOptions, request);
8089
+ (_a = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onPassthroughResponse) === null || _a === void 0 ? void 0 : _a.call(handleRequestOptions, request);
8044
8090
  return;
8045
8091
  }
8046
8092
  // Resolve a mocked response from the list of request handlers.
8047
- const lookupResult = yield getResponse(request, handlers, handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.resolutionContext);
8093
+ const [lookupError, lookupResult] = yield until(() => {
8094
+ return getResponse(request, handlers, handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.resolutionContext);
8095
+ });
8096
+ if (lookupError) {
8097
+ // Allow developers to react to unhandled exceptions in request handlers.
8098
+ emitter.emit('unhandledException', lookupError, request);
8099
+ throw lookupError;
8100
+ }
8048
8101
  const { handler, response } = lookupResult;
8049
8102
  // When there's no handler for the request, consider it unhandled.
8050
8103
  // Allow the developer to react to such cases.
@@ -8052,7 +8105,7 @@ function handleRequest(request, handlers, options, emitter, handleRequestOptions
8052
8105
  onUnhandledRequest(request, handlers, options.onUnhandledRequest);
8053
8106
  emitter.emit('request:unhandled', request);
8054
8107
  emitter.emit('request:end', request);
8055
- (_b = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onBypassResponse) === null || _b === void 0 ? void 0 : _b.call(handleRequestOptions, request);
8108
+ (_b = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onPassthroughResponse) === null || _b === void 0 ? void 0 : _b.call(handleRequestOptions, request);
8056
8109
  return;
8057
8110
  }
8058
8111
  // When the handled request returned no mocked response, warn the developer,
@@ -8065,7 +8118,14 @@ Expected response resolver to return a mocked response Object, but got %s. The o
8065
8118
  %s\
8066
8119
  `, response, handler.info.header, handler.info.callFrame);
8067
8120
  emitter.emit('request:end', request);
8068
- (_c = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onBypassResponse) === null || _c === void 0 ? void 0 : _c.call(handleRequestOptions, request);
8121
+ (_c = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onPassthroughResponse) === null || _c === void 0 ? void 0 : _c.call(handleRequestOptions, request);
8122
+ return;
8123
+ }
8124
+ // When the developer explicitly returned "req.passthrough()" do not warn them.
8125
+ // Perform the request as-is.
8126
+ if (response.passthrough) {
8127
+ emitter.emit('request:end', request);
8128
+ (_d = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onPassthroughResponse) === null || _d === void 0 ? void 0 : _d.call(handleRequestOptions, request);
8069
8129
  return;
8070
8130
  }
8071
8131
  // Store all the received response cookies in the virtual cookie store.
@@ -8112,8 +8172,8 @@ const DEFAULT_LISTEN_OPTIONS = {
8112
8172
  * Useful to generate identical API using different patches to request issuing modules.
8113
8173
  */
8114
8174
  function createSetupServer(...interceptors$1) {
8115
- const emitter = new lib$2.StrictEventEmitter();
8116
- const publicEmitter = new lib$2.StrictEventEmitter();
8175
+ const emitter = new lib$3.StrictEventEmitter();
8176
+ const publicEmitter = new lib$3.StrictEventEmitter();
8117
8177
  pipeEvents(emitter, publicEmitter);
8118
8178
  return function setupServer(...requestHandlers) {
8119
8179
  requestHandlers.forEach((handler) => {
@@ -8124,7 +8184,7 @@ function createSetupServer(...interceptors$1) {
8124
8184
  // so it could be modified at a runtime.
8125
8185
  let currentHandlers = [...requestHandlers];
8126
8186
  // Error when attempting to run this function in a browser environment.
8127
- if (!lib$3.exports.isNodeProcess()) {
8187
+ if (!lib$4.exports.isNodeProcess()) {
8128
8188
  throw new Error(devUtils.formatMessage('Failed to execute `setupServer` in the environment that is not Node.js (i.e. a browser). Consider using `setupWorker` instead.'));
8129
8189
  }
8130
8190
  let resolvedOptions = {};