msw 0.39.2 → 0.40.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/CHANGELOG.md +4 -0
- package/lib/esm/graphql-deps.js +4 -10
- package/lib/esm/graphql.js +2 -2
- package/lib/esm/index.js +69 -23
- package/lib/esm/{RequestHandler-deps.js → matchRequestUrl-deps.js} +192 -173
- package/lib/esm/mockServiceWorker.js +1 -1
- package/lib/esm/rest-deps.js +4 -10
- package/lib/esm/rest.js +1 -1
- package/lib/iife/index.js +2 -2
- package/lib/iife/mockServiceWorker.js +1 -1
- package/lib/types/handlers/GraphQLHandler.d.ts +2 -10
- package/lib/types/handlers/RequestHandler.d.ts +18 -8
- package/lib/types/handlers/RestHandler.d.ts +5 -9
- package/lib/types/index.d.ts +1 -1
- package/lib/types/native/index.d.ts +1 -1
- package/lib/types/node/setupServer.d.ts +1 -1
- package/lib/types/response.d.ts +4 -2
- package/lib/types/rest.d.ts +9 -9
- package/lib/types/setupWorker/glossary.d.ts +1 -0
- package/lib/types/setupWorker/start/utils/printStartMessage.d.ts +3 -2
- package/lib/types/sharedOptions.d.ts +1 -0
- package/lib/types/utils/getResponse.d.ts +1 -1
- package/lib/types/utils/handleRequest.d.ts +2 -2
- package/lib/types/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/types/utils/logging/prepareRequest.d.ts +2 -1
- package/lib/types/utils/matching/matchRequestUrl.d.ts +3 -1
- package/lib/umd/index.js +261 -208
- package/lib/umd/mockServiceWorker.js +1 -1
- package/native/lib/index.js +537 -489
- package/native/package.json +1 -1
- package/node/lib/index.js +537 -489
- package/node/package.json +1 -1
- package/package.json +14 -7
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$
|
|
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$
|
|
1964
|
+
}(lib$4, lib$4.exports));
|
|
1965
1965
|
|
|
1966
|
-
var lib$
|
|
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$
|
|
2036
|
+
}(lib$3));
|
|
2037
2037
|
|
|
2038
2038
|
function use(currentHandlers, ...handlers) {
|
|
2039
2039
|
currentHandlers.unshift(...handlers);
|
|
@@ -2047,20 +2047,7 @@ function resetHandlers(initialHandlers, ...nextHandlers) {
|
|
|
2047
2047
|
return nextHandlers.length > 0 ? [...nextHandlers] : [...initialHandlers];
|
|
2048
2048
|
}
|
|
2049
2049
|
|
|
2050
|
-
|
|
2051
|
-
* Parses a given value into a JSON.
|
|
2052
|
-
* Does not throw an exception on an invalid JSON string.
|
|
2053
|
-
*/
|
|
2054
|
-
function jsonParse(value) {
|
|
2055
|
-
try {
|
|
2056
|
-
return JSON.parse(value);
|
|
2057
|
-
}
|
|
2058
|
-
catch (error) {
|
|
2059
|
-
return undefined;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
|
-
var lib$1 = {};
|
|
2050
|
+
var lib$2 = {};
|
|
2064
2051
|
|
|
2065
2052
|
var Headers = {};
|
|
2066
2053
|
|
|
@@ -2549,49 +2536,460 @@ function flattenHeadersList(list) {
|
|
|
2549
2536
|
return [name, [].concat(values).join('; ')];
|
|
2550
2537
|
});
|
|
2551
2538
|
}
|
|
2552
|
-
flattenHeadersList$1.flattenHeadersList = flattenHeadersList;
|
|
2553
|
-
|
|
2554
|
-
var flattenHeadersObject$1 = {};
|
|
2539
|
+
flattenHeadersList$1.flattenHeadersList = flattenHeadersList;
|
|
2540
|
+
|
|
2541
|
+
var flattenHeadersObject$1 = {};
|
|
2542
|
+
|
|
2543
|
+
Object.defineProperty(flattenHeadersObject$1, "__esModule", { value: true });
|
|
2544
|
+
flattenHeadersObject$1.flattenHeadersObject = void 0;
|
|
2545
|
+
var reduceHeadersObject_1 = reduceHeadersObject$1;
|
|
2546
|
+
function flattenHeadersObject(headersObject) {
|
|
2547
|
+
return reduceHeadersObject_1.reduceHeadersObject(headersObject, function (headers, name, value) {
|
|
2548
|
+
headers[name] = [].concat(value).join('; ');
|
|
2549
|
+
return headers;
|
|
2550
|
+
}, {});
|
|
2551
|
+
}
|
|
2552
|
+
flattenHeadersObject$1.flattenHeadersObject = flattenHeadersObject;
|
|
2553
|
+
|
|
2554
|
+
(function (exports) {
|
|
2555
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2556
|
+
exports.flattenHeadersObject = exports.flattenHeadersList = exports.reduceHeadersObject = exports.objectToHeaders = exports.listToHeaders = exports.stringToHeaders = exports.headersToObject = exports.headersToList = exports.headersToString = exports.Headers = void 0;
|
|
2557
|
+
var Headers_1 = Headers;
|
|
2558
|
+
Object.defineProperty(exports, "Headers", { enumerable: true, get: function () { return Headers_1.default; } });
|
|
2559
|
+
var headersToString_1 = headersToString$1;
|
|
2560
|
+
Object.defineProperty(exports, "headersToString", { enumerable: true, get: function () { return headersToString_1.headersToString; } });
|
|
2561
|
+
var headersToList_1 = headersToList$1;
|
|
2562
|
+
Object.defineProperty(exports, "headersToList", { enumerable: true, get: function () { return headersToList_1.headersToList; } });
|
|
2563
|
+
var headersToObject_1 = headersToObject$1;
|
|
2564
|
+
Object.defineProperty(exports, "headersToObject", { enumerable: true, get: function () { return headersToObject_1.headersToObject; } });
|
|
2565
|
+
var stringToHeaders_1 = stringToHeaders$1;
|
|
2566
|
+
Object.defineProperty(exports, "stringToHeaders", { enumerable: true, get: function () { return stringToHeaders_1.stringToHeaders; } });
|
|
2567
|
+
var listToHeaders_1 = listToHeaders$1;
|
|
2568
|
+
Object.defineProperty(exports, "listToHeaders", { enumerable: true, get: function () { return listToHeaders_1.listToHeaders; } });
|
|
2569
|
+
var objectToHeaders_1 = objectToHeaders$1;
|
|
2570
|
+
Object.defineProperty(exports, "objectToHeaders", { enumerable: true, get: function () { return objectToHeaders_1.objectToHeaders; } });
|
|
2571
|
+
var reduceHeadersObject_1 = reduceHeadersObject$1;
|
|
2572
|
+
Object.defineProperty(exports, "reduceHeadersObject", { enumerable: true, get: function () { return reduceHeadersObject_1.reduceHeadersObject; } });
|
|
2573
|
+
var flattenHeadersList_1 = flattenHeadersList$1;
|
|
2574
|
+
Object.defineProperty(exports, "flattenHeadersList", { enumerable: true, get: function () { return flattenHeadersList_1.flattenHeadersList; } });
|
|
2575
|
+
var flattenHeadersObject_1 = flattenHeadersObject$1;
|
|
2576
|
+
Object.defineProperty(exports, "flattenHeadersObject", { enumerable: true, get: function () { return flattenHeadersObject_1.flattenHeadersObject; } });
|
|
2577
|
+
}(lib$2));
|
|
2578
|
+
|
|
2579
|
+
/**
|
|
2580
|
+
* Composes a given list of functions into a new function that
|
|
2581
|
+
* executes from right to left.
|
|
2582
|
+
*/
|
|
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
|
+
}
|
|
2555
2976
|
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
return
|
|
2563
|
-
}
|
|
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
|
+
}
|
|
2564
2988
|
}
|
|
2565
|
-
flattenHeadersObject$1.flattenHeadersObject = flattenHeadersObject;
|
|
2566
|
-
|
|
2567
|
-
(function (exports) {
|
|
2568
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2569
|
-
exports.flattenHeadersObject = exports.flattenHeadersList = exports.reduceHeadersObject = exports.objectToHeaders = exports.listToHeaders = exports.stringToHeaders = exports.headersToObject = exports.headersToList = exports.headersToString = exports.Headers = void 0;
|
|
2570
|
-
var Headers_1 = Headers;
|
|
2571
|
-
Object.defineProperty(exports, "Headers", { enumerable: true, get: function () { return Headers_1.default; } });
|
|
2572
|
-
var headersToString_1 = headersToString$1;
|
|
2573
|
-
Object.defineProperty(exports, "headersToString", { enumerable: true, get: function () { return headersToString_1.headersToString; } });
|
|
2574
|
-
var headersToList_1 = headersToList$1;
|
|
2575
|
-
Object.defineProperty(exports, "headersToList", { enumerable: true, get: function () { return headersToList_1.headersToList; } });
|
|
2576
|
-
var headersToObject_1 = headersToObject$1;
|
|
2577
|
-
Object.defineProperty(exports, "headersToObject", { enumerable: true, get: function () { return headersToObject_1.headersToObject; } });
|
|
2578
|
-
var stringToHeaders_1 = stringToHeaders$1;
|
|
2579
|
-
Object.defineProperty(exports, "stringToHeaders", { enumerable: true, get: function () { return stringToHeaders_1.stringToHeaders; } });
|
|
2580
|
-
var listToHeaders_1 = listToHeaders$1;
|
|
2581
|
-
Object.defineProperty(exports, "listToHeaders", { enumerable: true, get: function () { return listToHeaders_1.listToHeaders; } });
|
|
2582
|
-
var objectToHeaders_1 = objectToHeaders$1;
|
|
2583
|
-
Object.defineProperty(exports, "objectToHeaders", { enumerable: true, get: function () { return objectToHeaders_1.objectToHeaders; } });
|
|
2584
|
-
var reduceHeadersObject_1 = reduceHeadersObject$1;
|
|
2585
|
-
Object.defineProperty(exports, "reduceHeadersObject", { enumerable: true, get: function () { return reduceHeadersObject_1.reduceHeadersObject; } });
|
|
2586
|
-
var flattenHeadersList_1 = flattenHeadersList$1;
|
|
2587
|
-
Object.defineProperty(exports, "flattenHeadersList", { enumerable: true, get: function () { return flattenHeadersList_1.flattenHeadersList; } });
|
|
2588
|
-
var flattenHeadersObject_1 = flattenHeadersObject$1;
|
|
2589
|
-
Object.defineProperty(exports, "flattenHeadersObject", { enumerable: true, get: function () { return flattenHeadersObject_1.flattenHeadersObject; } });
|
|
2590
|
-
}(lib$1));
|
|
2591
2989
|
|
|
2592
2990
|
function parseContentHeaders(headersString) {
|
|
2593
2991
|
var _a, _b;
|
|
2594
|
-
const headers = lib$
|
|
2992
|
+
const headers = lib$2.stringToHeaders(headersString);
|
|
2595
2993
|
const contentType = headers.get('content-type') || 'text/plain';
|
|
2596
2994
|
const disposition = headers.get('content-disposition');
|
|
2597
2995
|
if (!disposition) {
|
|
@@ -2970,12 +3368,39 @@ function parseIsomorphicRequest(request) {
|
|
|
2970
3368
|
integrity: '',
|
|
2971
3369
|
destination: 'document',
|
|
2972
3370
|
bodyUsed: false,
|
|
3371
|
+
passthrough,
|
|
2973
3372
|
};
|
|
2974
3373
|
// Attach all the cookies from the virtual cookie store.
|
|
2975
3374
|
setRequestCookies(mockedRequest);
|
|
2976
3375
|
return mockedRequest;
|
|
2977
3376
|
}
|
|
2978
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
|
+
|
|
2979
3404
|
/**
|
|
2980
3405
|
* Returns a mocked response for a given request using following request handlers.
|
|
2981
3406
|
*/
|
|
@@ -6714,114 +7139,6 @@ function isStringEqual(actual, expected) {
|
|
|
6714
7139
|
return actual.toLowerCase() === expected.toLowerCase();
|
|
6715
7140
|
}
|
|
6716
7141
|
|
|
6717
|
-
var statuses = {
|
|
6718
|
-
"100": "Continue",
|
|
6719
|
-
"101": "Switching Protocols",
|
|
6720
|
-
"102": "Processing",
|
|
6721
|
-
"103": "Early Hints",
|
|
6722
|
-
"200": "OK",
|
|
6723
|
-
"201": "Created",
|
|
6724
|
-
"202": "Accepted",
|
|
6725
|
-
"203": "Non-Authoritative Information",
|
|
6726
|
-
"204": "No Content",
|
|
6727
|
-
"205": "Reset Content",
|
|
6728
|
-
"206": "Partial Content",
|
|
6729
|
-
"207": "Multi-Status",
|
|
6730
|
-
"208": "Already Reported",
|
|
6731
|
-
"226": "IM Used",
|
|
6732
|
-
"300": "Multiple Choices",
|
|
6733
|
-
"301": "Moved Permanently",
|
|
6734
|
-
"302": "Found",
|
|
6735
|
-
"303": "See Other",
|
|
6736
|
-
"304": "Not Modified",
|
|
6737
|
-
"305": "Use Proxy",
|
|
6738
|
-
"307": "Temporary Redirect",
|
|
6739
|
-
"308": "Permanent Redirect",
|
|
6740
|
-
"400": "Bad Request",
|
|
6741
|
-
"401": "Unauthorized",
|
|
6742
|
-
"402": "Payment Required",
|
|
6743
|
-
"403": "Forbidden",
|
|
6744
|
-
"404": "Not Found",
|
|
6745
|
-
"405": "Method Not Allowed",
|
|
6746
|
-
"406": "Not Acceptable",
|
|
6747
|
-
"407": "Proxy Authentication Required",
|
|
6748
|
-
"408": "Request Timeout",
|
|
6749
|
-
"409": "Conflict",
|
|
6750
|
-
"410": "Gone",
|
|
6751
|
-
"411": "Length Required",
|
|
6752
|
-
"412": "Precondition Failed",
|
|
6753
|
-
"413": "Payload Too Large",
|
|
6754
|
-
"414": "URI Too Long",
|
|
6755
|
-
"415": "Unsupported Media Type",
|
|
6756
|
-
"416": "Range Not Satisfiable",
|
|
6757
|
-
"417": "Expectation Failed",
|
|
6758
|
-
"418": "I'm a Teapot",
|
|
6759
|
-
"421": "Misdirected Request",
|
|
6760
|
-
"422": "Unprocessable Entity",
|
|
6761
|
-
"423": "Locked",
|
|
6762
|
-
"424": "Failed Dependency",
|
|
6763
|
-
"425": "Too Early",
|
|
6764
|
-
"426": "Upgrade Required",
|
|
6765
|
-
"428": "Precondition Required",
|
|
6766
|
-
"429": "Too Many Requests",
|
|
6767
|
-
"431": "Request Header Fields Too Large",
|
|
6768
|
-
"451": "Unavailable For Legal Reasons",
|
|
6769
|
-
"500": "Internal Server Error",
|
|
6770
|
-
"501": "Not Implemented",
|
|
6771
|
-
"502": "Bad Gateway",
|
|
6772
|
-
"503": "Service Unavailable",
|
|
6773
|
-
"504": "Gateway Timeout",
|
|
6774
|
-
"505": "HTTP Version Not Supported",
|
|
6775
|
-
"506": "Variant Also Negotiates",
|
|
6776
|
-
"507": "Insufficient Storage",
|
|
6777
|
-
"508": "Loop Detected",
|
|
6778
|
-
"509": "Bandwidth Limit Exceeded",
|
|
6779
|
-
"510": "Not Extended",
|
|
6780
|
-
"511": "Network Authentication Required"
|
|
6781
|
-
};
|
|
6782
|
-
|
|
6783
|
-
/**
|
|
6784
|
-
* Sets a response status code and text.
|
|
6785
|
-
* @example
|
|
6786
|
-
* res(ctx.status(301))
|
|
6787
|
-
* res(ctx.status(400, 'Custom status text'))
|
|
6788
|
-
* @see {@link https://mswjs.io/docs/api/context/status `ctx.status()`}
|
|
6789
|
-
*/
|
|
6790
|
-
const status = (statusCode, statusText) => {
|
|
6791
|
-
return (res) => {
|
|
6792
|
-
res.status = statusCode;
|
|
6793
|
-
res.statusText =
|
|
6794
|
-
statusText || statuses[String(statusCode)];
|
|
6795
|
-
return res;
|
|
6796
|
-
};
|
|
6797
|
-
};
|
|
6798
|
-
|
|
6799
|
-
/**
|
|
6800
|
-
* Sets one or multiple response headers.
|
|
6801
|
-
* @example
|
|
6802
|
-
* ctx.set('Content-Type', 'text/plain')
|
|
6803
|
-
* ctx.set({
|
|
6804
|
-
* 'Accept': 'application/javascript',
|
|
6805
|
-
* 'Content-Type': "text/plain"
|
|
6806
|
-
* })
|
|
6807
|
-
* @see {@link https://mswjs.io/docs/api/context/set `ctx.set()`}
|
|
6808
|
-
*/
|
|
6809
|
-
function set(...args) {
|
|
6810
|
-
return (res) => {
|
|
6811
|
-
const [name, value] = args;
|
|
6812
|
-
if (typeof name === 'string') {
|
|
6813
|
-
res.headers.append(name, value);
|
|
6814
|
-
}
|
|
6815
|
-
else {
|
|
6816
|
-
const headers = lib$1.objectToHeaders(name);
|
|
6817
|
-
headers.forEach((value, name) => {
|
|
6818
|
-
res.headers.append(name, value);
|
|
6819
|
-
});
|
|
6820
|
-
}
|
|
6821
|
-
return res;
|
|
6822
|
-
};
|
|
6823
|
-
}
|
|
6824
|
-
|
|
6825
7142
|
/**
|
|
6826
7143
|
* Sets a given cookie on the mocked response.
|
|
6827
7144
|
* @example res(ctx.cookie('name', 'value'))
|
|
@@ -6891,95 +7208,39 @@ function mergeRight(left, right) {
|
|
|
6891
7208
|
const json = (body) => {
|
|
6892
7209
|
return (res) => {
|
|
6893
7210
|
res.headers.set('Content-Type', 'application/json');
|
|
6894
|
-
res.body = JSON.stringify(body);
|
|
6895
|
-
return res;
|
|
6896
|
-
};
|
|
6897
|
-
};
|
|
6898
|
-
|
|
6899
|
-
/**
|
|
6900
|
-
* Sets a given payload as a GraphQL response body.
|
|
6901
|
-
* @example
|
|
6902
|
-
* res(ctx.data({ user: { firstName: 'John' }}))
|
|
6903
|
-
* @see {@link https://mswjs.io/docs/api/context/data `ctx.data()`}
|
|
6904
|
-
*/
|
|
6905
|
-
const data = (payload) => {
|
|
6906
|
-
return (res) => {
|
|
6907
|
-
const prevBody = jsonParse(res.body) || {};
|
|
6908
|
-
const nextBody = mergeRight(prevBody, { data: payload });
|
|
6909
|
-
return json(nextBody)(res);
|
|
6910
|
-
};
|
|
6911
|
-
};
|
|
6912
|
-
|
|
6913
|
-
/**
|
|
6914
|
-
* Sets the GraphQL extensions on a given response.
|
|
6915
|
-
* @example
|
|
6916
|
-
* res(ctx.extensions({ tracing: { version: 1 }}))
|
|
6917
|
-
* @see {@link https://mswjs.io/docs/api/context/extensions `ctx.extensions()`}
|
|
6918
|
-
*/
|
|
6919
|
-
const extensions = (payload) => {
|
|
6920
|
-
return (res) => {
|
|
6921
|
-
const prevBody = jsonParse(res.body) || {};
|
|
6922
|
-
const nextBody = mergeRight(prevBody, { extensions: payload });
|
|
6923
|
-
return json(nextBody)(res);
|
|
6924
|
-
};
|
|
6925
|
-
};
|
|
6926
|
-
|
|
6927
|
-
const SET_TIMEOUT_MAX_ALLOWED_INT = 2147483647;
|
|
6928
|
-
const MIN_SERVER_RESPONSE_TIME = 100;
|
|
6929
|
-
const MAX_SERVER_RESPONSE_TIME = 400;
|
|
6930
|
-
const NODE_SERVER_RESPONSE_TIME = 5;
|
|
6931
|
-
const getRandomServerResponseTime = () => {
|
|
6932
|
-
if (lib$3.exports.isNodeProcess()) {
|
|
6933
|
-
return NODE_SERVER_RESPONSE_TIME;
|
|
6934
|
-
}
|
|
6935
|
-
return Math.floor(Math.random() * (MAX_SERVER_RESPONSE_TIME - MIN_SERVER_RESPONSE_TIME) +
|
|
6936
|
-
MIN_SERVER_RESPONSE_TIME);
|
|
6937
|
-
};
|
|
6938
|
-
/**
|
|
6939
|
-
* Delays the response by the given duration (ms).
|
|
6940
|
-
* @example
|
|
6941
|
-
* res(ctx.delay(1200)) // delay response by 1200ms
|
|
6942
|
-
* res(ctx.delay()) // emulate realistic server response time
|
|
6943
|
-
* res(ctx.delay('infinite')) // delay response infinitely
|
|
6944
|
-
* @see {@link https://mswjs.io/docs/api/context/delay `ctx.delay()`}
|
|
6945
|
-
*/
|
|
6946
|
-
const delay = (durationOrMode) => {
|
|
6947
|
-
return (res) => {
|
|
6948
|
-
let delayTime;
|
|
6949
|
-
if (typeof durationOrMode === 'string') {
|
|
6950
|
-
switch (durationOrMode) {
|
|
6951
|
-
case 'infinite': {
|
|
6952
|
-
// Using `Infinity` as a delay value executes the response timeout immediately.
|
|
6953
|
-
// Instead, use the maximum allowed integer for `setTimeout`.
|
|
6954
|
-
delayTime = SET_TIMEOUT_MAX_ALLOWED_INT;
|
|
6955
|
-
break;
|
|
6956
|
-
}
|
|
6957
|
-
case 'real': {
|
|
6958
|
-
delayTime = getRandomServerResponseTime();
|
|
6959
|
-
break;
|
|
6960
|
-
}
|
|
6961
|
-
default: {
|
|
6962
|
-
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".`);
|
|
6963
|
-
}
|
|
6964
|
-
}
|
|
6965
|
-
}
|
|
6966
|
-
else if (typeof durationOrMode === 'undefined') {
|
|
6967
|
-
// Use random realistic server response time when no explicit delay duration was provided.
|
|
6968
|
-
delayTime = getRandomServerResponseTime();
|
|
6969
|
-
}
|
|
6970
|
-
else {
|
|
6971
|
-
// Guard against passing values like `Infinity` or `Number.MAX_VALUE`
|
|
6972
|
-
// as the response delay duration. They don't produce the result you may expect.
|
|
6973
|
-
if (durationOrMode > SET_TIMEOUT_MAX_ALLOWED_INT) {
|
|
6974
|
-
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.`);
|
|
6975
|
-
}
|
|
6976
|
-
delayTime = durationOrMode;
|
|
6977
|
-
}
|
|
6978
|
-
res.delay = delayTime;
|
|
7211
|
+
res.body = JSON.stringify(body);
|
|
6979
7212
|
return res;
|
|
6980
7213
|
};
|
|
6981
7214
|
};
|
|
6982
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
|
+
|
|
6983
7244
|
/**
|
|
6984
7245
|
* Sets a given list of GraphQL errors on the mocked response.
|
|
6985
7246
|
* @example res(ctx.errors([{ message: 'Unauthorized' }]))
|
|
@@ -6996,43 +7257,6 @@ const errors = (errorsList) => {
|
|
|
6996
7257
|
};
|
|
6997
7258
|
};
|
|
6998
7259
|
|
|
6999
|
-
const useFetch = lib$3.exports.isNodeProcess() ? require('node-fetch') : window.fetch;
|
|
7000
|
-
const augmentRequestInit = (requestInit) => {
|
|
7001
|
-
const headers = new lib$1.Headers(requestInit.headers);
|
|
7002
|
-
headers.set('x-msw-bypass', 'true');
|
|
7003
|
-
return Object.assign(Object.assign({}, requestInit), { headers: headers.all() });
|
|
7004
|
-
};
|
|
7005
|
-
const createFetchRequestParameters = (input) => {
|
|
7006
|
-
const { body, method } = input;
|
|
7007
|
-
const requestParameters = Object.assign(Object.assign({}, input), { body: undefined });
|
|
7008
|
-
if (['GET', 'HEAD'].includes(method)) {
|
|
7009
|
-
return requestParameters;
|
|
7010
|
-
}
|
|
7011
|
-
if (typeof body === 'object' ||
|
|
7012
|
-
typeof body === 'number' ||
|
|
7013
|
-
typeof body === 'boolean') {
|
|
7014
|
-
requestParameters.body = JSON.stringify(body);
|
|
7015
|
-
}
|
|
7016
|
-
else {
|
|
7017
|
-
requestParameters.body = body;
|
|
7018
|
-
}
|
|
7019
|
-
return requestParameters;
|
|
7020
|
-
};
|
|
7021
|
-
/**
|
|
7022
|
-
* Performs a bypassed request inside a request handler.
|
|
7023
|
-
* @example
|
|
7024
|
-
* const originalResponse = await ctx.fetch(req)
|
|
7025
|
-
* @see {@link https://mswjs.io/docs/api/context/fetch `ctx.fetch()`}
|
|
7026
|
-
*/
|
|
7027
|
-
const fetch = (input, requestInit = {}) => {
|
|
7028
|
-
if (typeof input === 'string') {
|
|
7029
|
-
return useFetch(input, augmentRequestInit(requestInit));
|
|
7030
|
-
}
|
|
7031
|
-
const requestParameters = createFetchRequestParameters(input);
|
|
7032
|
-
const derivedRequestInit = augmentRequestInit(requestParameters);
|
|
7033
|
-
return useFetch(input.url.href, derivedRequestInit);
|
|
7034
|
-
};
|
|
7035
|
-
|
|
7036
7260
|
/**
|
|
7037
7261
|
* Sets a textual response body. Appends a `Content-Type: text/plain`
|
|
7038
7262
|
* header on the mocked response.
|
|
@@ -7104,7 +7328,7 @@ function prepareRequest(request) {
|
|
|
7104
7328
|
* Formats a mocked response for introspection in the browser's console.
|
|
7105
7329
|
*/
|
|
7106
7330
|
function prepareResponse(res) {
|
|
7107
|
-
const responseHeaders = lib$
|
|
7331
|
+
const responseHeaders = lib$2.objectToHeaders(res.headers);
|
|
7108
7332
|
return Object.assign(Object.assign({}, res), {
|
|
7109
7333
|
// Parse a response JSON body for preview in the logs
|
|
7110
7334
|
body: parseBody(res.body, responseHeaders) });
|
|
@@ -7548,184 +7772,6 @@ function matchRequestUrl(url, path, baseUrl) {
|
|
|
7548
7772
|
};
|
|
7549
7773
|
}
|
|
7550
7774
|
|
|
7551
|
-
/**
|
|
7552
|
-
* Composes a given list of functions into a new function that
|
|
7553
|
-
* executes from right to left.
|
|
7554
|
-
*/
|
|
7555
|
-
function compose(...fns) {
|
|
7556
|
-
return (...args) => {
|
|
7557
|
-
return fns.reduceRight((leftFn, rightFn) => {
|
|
7558
|
-
return leftFn instanceof Promise
|
|
7559
|
-
? Promise.resolve(leftFn).then(rightFn)
|
|
7560
|
-
: rightFn(leftFn);
|
|
7561
|
-
}, args[0]);
|
|
7562
|
-
};
|
|
7563
|
-
}
|
|
7564
|
-
|
|
7565
|
-
class NetworkError extends Error {
|
|
7566
|
-
constructor(message) {
|
|
7567
|
-
super(message);
|
|
7568
|
-
this.name = 'NetworkError';
|
|
7569
|
-
}
|
|
7570
|
-
}
|
|
7571
|
-
|
|
7572
|
-
const defaultResponse = {
|
|
7573
|
-
status: 200,
|
|
7574
|
-
statusText: 'OK',
|
|
7575
|
-
body: null,
|
|
7576
|
-
delay: 0,
|
|
7577
|
-
once: false,
|
|
7578
|
-
};
|
|
7579
|
-
const defaultResponseTransformers = [];
|
|
7580
|
-
function createResponseComposition(responseOverrides, defaultTransformers = defaultResponseTransformers) {
|
|
7581
|
-
return (...transformers) => __awaiter(this, void 0, void 0, function* () {
|
|
7582
|
-
const initialResponse = Object.assign({}, defaultResponse, {
|
|
7583
|
-
headers: new lib$1.Headers({
|
|
7584
|
-
'x-powered-by': 'msw',
|
|
7585
|
-
}),
|
|
7586
|
-
}, responseOverrides);
|
|
7587
|
-
const resolvedTransformers = [
|
|
7588
|
-
...defaultTransformers,
|
|
7589
|
-
...transformers,
|
|
7590
|
-
].filter(Boolean);
|
|
7591
|
-
const resolvedResponse = resolvedTransformers.length > 0
|
|
7592
|
-
? compose(...resolvedTransformers)(initialResponse)
|
|
7593
|
-
: initialResponse;
|
|
7594
|
-
return resolvedResponse;
|
|
7595
|
-
});
|
|
7596
|
-
}
|
|
7597
|
-
const response = Object.assign(createResponseComposition(), {
|
|
7598
|
-
once: createResponseComposition({ once: true }),
|
|
7599
|
-
networkError(message) {
|
|
7600
|
-
throw new NetworkError(message);
|
|
7601
|
-
},
|
|
7602
|
-
});
|
|
7603
|
-
|
|
7604
|
-
const BUILD_FRAME = /(node_modules)?[\/\\]lib[\/\\](umd|esm|iief|cjs)[\/\\]|^[^\/\\]*$/;
|
|
7605
|
-
/**
|
|
7606
|
-
* Return the stack trace frame of a function's invocation.
|
|
7607
|
-
*/
|
|
7608
|
-
function getCallFrame(error) {
|
|
7609
|
-
// In <IE11, new Error may return an undefined stack
|
|
7610
|
-
const stack = error.stack;
|
|
7611
|
-
if (!stack) {
|
|
7612
|
-
return;
|
|
7613
|
-
}
|
|
7614
|
-
const frames = stack.split('\n').slice(1);
|
|
7615
|
-
// Get the first frame that doesn't reference the library's internal trace.
|
|
7616
|
-
// Assume that frame is the invocation frame.
|
|
7617
|
-
const declarationFrame = frames.find((frame) => {
|
|
7618
|
-
return !BUILD_FRAME.test(frame);
|
|
7619
|
-
});
|
|
7620
|
-
if (!declarationFrame) {
|
|
7621
|
-
return;
|
|
7622
|
-
}
|
|
7623
|
-
// Extract file reference from the stack frame.
|
|
7624
|
-
const declarationPath = declarationFrame
|
|
7625
|
-
.replace(/\s*at [^()]*\(([^)]+)\)/, '$1')
|
|
7626
|
-
.replace(/^@/, '');
|
|
7627
|
-
return declarationPath;
|
|
7628
|
-
}
|
|
7629
|
-
|
|
7630
|
-
/**
|
|
7631
|
-
* Determines if the given function is an iterator.
|
|
7632
|
-
*/
|
|
7633
|
-
function isIterable(fn) {
|
|
7634
|
-
if (!fn) {
|
|
7635
|
-
return false;
|
|
7636
|
-
}
|
|
7637
|
-
return typeof fn[Symbol.iterator] == 'function';
|
|
7638
|
-
}
|
|
7639
|
-
|
|
7640
|
-
const defaultContext = {
|
|
7641
|
-
status,
|
|
7642
|
-
set,
|
|
7643
|
-
delay,
|
|
7644
|
-
fetch,
|
|
7645
|
-
};
|
|
7646
|
-
class RequestHandler {
|
|
7647
|
-
constructor(options) {
|
|
7648
|
-
this.shouldSkip = false;
|
|
7649
|
-
this.ctx = options.ctx || defaultContext;
|
|
7650
|
-
this.resolver = options.resolver;
|
|
7651
|
-
const callFrame = getCallFrame(new Error());
|
|
7652
|
-
this.info = Object.assign(Object.assign({}, options.info), { callFrame });
|
|
7653
|
-
}
|
|
7654
|
-
/**
|
|
7655
|
-
* Parse the captured request to extract additional information from it.
|
|
7656
|
-
* Parsed result is then exposed to other methods of this request handler.
|
|
7657
|
-
*/
|
|
7658
|
-
parse(_request, _resolutionContext) {
|
|
7659
|
-
return null;
|
|
7660
|
-
}
|
|
7661
|
-
/**
|
|
7662
|
-
* Test if this handler matches the given request.
|
|
7663
|
-
*/
|
|
7664
|
-
test(request, resolutionContext) {
|
|
7665
|
-
return this.predicate(request, this.parse(request, resolutionContext), resolutionContext);
|
|
7666
|
-
}
|
|
7667
|
-
/**
|
|
7668
|
-
* Derive the publicly exposed request (`req`) instance of the response resolver
|
|
7669
|
-
* from the captured request and its parsed result.
|
|
7670
|
-
*/
|
|
7671
|
-
getPublicRequest(request, _parsedResult) {
|
|
7672
|
-
return request;
|
|
7673
|
-
}
|
|
7674
|
-
markAsSkipped(shouldSkip = true) {
|
|
7675
|
-
this.shouldSkip = shouldSkip;
|
|
7676
|
-
}
|
|
7677
|
-
/**
|
|
7678
|
-
* Execute this request handler and produce a mocked response
|
|
7679
|
-
* using the given resolver function.
|
|
7680
|
-
*/
|
|
7681
|
-
run(request, resolutionContext) {
|
|
7682
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
7683
|
-
if (this.shouldSkip) {
|
|
7684
|
-
return null;
|
|
7685
|
-
}
|
|
7686
|
-
const parsedResult = this.parse(request, resolutionContext);
|
|
7687
|
-
const shouldIntercept = this.predicate(request, parsedResult, resolutionContext);
|
|
7688
|
-
if (!shouldIntercept) {
|
|
7689
|
-
return null;
|
|
7690
|
-
}
|
|
7691
|
-
const publicRequest = this.getPublicRequest(request, parsedResult);
|
|
7692
|
-
// Create a response extraction wrapper around the resolver
|
|
7693
|
-
// since it can be both an async function and a generator.
|
|
7694
|
-
const executeResolver = this.wrapResolver(this.resolver);
|
|
7695
|
-
const mockedResponse = yield executeResolver(publicRequest, response, this.ctx);
|
|
7696
|
-
return this.createExecutionResult(parsedResult, publicRequest, mockedResponse);
|
|
7697
|
-
});
|
|
7698
|
-
}
|
|
7699
|
-
wrapResolver(resolver) {
|
|
7700
|
-
return (req, res, ctx) => __awaiter(this, void 0, void 0, function* () {
|
|
7701
|
-
const result = this.resolverGenerator || (yield resolver(req, res, ctx));
|
|
7702
|
-
if (isIterable(result)) {
|
|
7703
|
-
const { value, done } = result[Symbol.iterator]().next();
|
|
7704
|
-
const nextResponse = yield value;
|
|
7705
|
-
// If the generator is done and there is no next value,
|
|
7706
|
-
// return the previous generator's value.
|
|
7707
|
-
if (!nextResponse && done) {
|
|
7708
|
-
return this.resolverGeneratorResult;
|
|
7709
|
-
}
|
|
7710
|
-
if (!this.resolverGenerator) {
|
|
7711
|
-
this.resolverGenerator = result;
|
|
7712
|
-
}
|
|
7713
|
-
this.resolverGeneratorResult = nextResponse;
|
|
7714
|
-
return nextResponse;
|
|
7715
|
-
}
|
|
7716
|
-
return result;
|
|
7717
|
-
});
|
|
7718
|
-
}
|
|
7719
|
-
createExecutionResult(parsedResult, request, response) {
|
|
7720
|
-
return {
|
|
7721
|
-
handler: this,
|
|
7722
|
-
parsedResult: parsedResult || null,
|
|
7723
|
-
request,
|
|
7724
|
-
response: response || null,
|
|
7725
|
-
};
|
|
7726
|
-
}
|
|
7727
|
-
}
|
|
7728
|
-
|
|
7729
7775
|
var RESTMethods;
|
|
7730
7776
|
(function (RESTMethods) {
|
|
7731
7777
|
RESTMethods["HEAD"] = "HEAD";
|
|
@@ -7736,17 +7782,11 @@ var RESTMethods;
|
|
|
7736
7782
|
RESTMethods["OPTIONS"] = "OPTIONS";
|
|
7737
7783
|
RESTMethods["DELETE"] = "DELETE";
|
|
7738
7784
|
})(RESTMethods || (RESTMethods = {}));
|
|
7739
|
-
const restContext = {
|
|
7740
|
-
set,
|
|
7741
|
-
status,
|
|
7742
|
-
cookie,
|
|
7785
|
+
const restContext = Object.assign(Object.assign({}, defaultContext), { cookie,
|
|
7743
7786
|
body,
|
|
7744
7787
|
text,
|
|
7745
7788
|
json,
|
|
7746
|
-
xml
|
|
7747
|
-
delay,
|
|
7748
|
-
fetch,
|
|
7749
|
-
};
|
|
7789
|
+
xml });
|
|
7750
7790
|
/**
|
|
7751
7791
|
* Request handler for REST API requests.
|
|
7752
7792
|
* Provides request matching based on method and URL.
|
|
@@ -7817,16 +7857,10 @@ function tryCatch(fn, onException) {
|
|
|
7817
7857
|
}
|
|
7818
7858
|
}
|
|
7819
7859
|
|
|
7820
|
-
const graphqlContext = {
|
|
7821
|
-
set,
|
|
7822
|
-
status,
|
|
7823
|
-
delay,
|
|
7824
|
-
fetch,
|
|
7825
|
-
data,
|
|
7860
|
+
const graphqlContext = Object.assign(Object.assign({}, defaultContext), { data,
|
|
7826
7861
|
extensions,
|
|
7827
7862
|
errors,
|
|
7828
|
-
cookie
|
|
7829
|
-
};
|
|
7863
|
+
cookie });
|
|
7830
7864
|
function isDocumentNode(value) {
|
|
7831
7865
|
if (value == null) {
|
|
7832
7866
|
return false;
|
|
@@ -8046,17 +8080,24 @@ function readResponseCookies(request, response) {
|
|
|
8046
8080
|
}
|
|
8047
8081
|
|
|
8048
8082
|
function handleRequest(request, handlers, options, emitter, handleRequestOptions) {
|
|
8049
|
-
var _a, _b, _c;
|
|
8083
|
+
var _a, _b, _c, _d;
|
|
8050
8084
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8051
8085
|
emitter.emit('request:start', request);
|
|
8052
8086
|
// Perform bypassed requests (i.e. issued via "ctx.fetch") as-is.
|
|
8053
8087
|
if (request.headers.get('x-msw-bypass') === 'true') {
|
|
8054
8088
|
emitter.emit('request:end', request);
|
|
8055
|
-
(_a = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.
|
|
8089
|
+
(_a = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onPassthroughResponse) === null || _a === void 0 ? void 0 : _a.call(handleRequestOptions, request);
|
|
8056
8090
|
return;
|
|
8057
8091
|
}
|
|
8058
8092
|
// Resolve a mocked response from the list of request handlers.
|
|
8059
|
-
const lookupResult = yield
|
|
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
|
+
}
|
|
8060
8101
|
const { handler, response } = lookupResult;
|
|
8061
8102
|
// When there's no handler for the request, consider it unhandled.
|
|
8062
8103
|
// Allow the developer to react to such cases.
|
|
@@ -8064,7 +8105,7 @@ function handleRequest(request, handlers, options, emitter, handleRequestOptions
|
|
|
8064
8105
|
onUnhandledRequest(request, handlers, options.onUnhandledRequest);
|
|
8065
8106
|
emitter.emit('request:unhandled', request);
|
|
8066
8107
|
emitter.emit('request:end', request);
|
|
8067
|
-
(_b = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.
|
|
8108
|
+
(_b = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.onPassthroughResponse) === null || _b === void 0 ? void 0 : _b.call(handleRequestOptions, request);
|
|
8068
8109
|
return;
|
|
8069
8110
|
}
|
|
8070
8111
|
// When the handled request returned no mocked response, warn the developer,
|
|
@@ -8077,7 +8118,14 @@ Expected response resolver to return a mocked response Object, but got %s. The o
|
|
|
8077
8118
|
%s\
|
|
8078
8119
|
`, response, handler.info.header, handler.info.callFrame);
|
|
8079
8120
|
emitter.emit('request:end', request);
|
|
8080
|
-
(_c = handleRequestOptions === null || handleRequestOptions === void 0 ? void 0 : handleRequestOptions.
|
|
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);
|
|
8081
8129
|
return;
|
|
8082
8130
|
}
|
|
8083
8131
|
// Store all the received response cookies in the virtual cookie store.
|
|
@@ -8124,8 +8172,8 @@ const DEFAULT_LISTEN_OPTIONS = {
|
|
|
8124
8172
|
* Useful to generate identical API using different patches to request issuing modules.
|
|
8125
8173
|
*/
|
|
8126
8174
|
function createSetupServer(...interceptors$1) {
|
|
8127
|
-
const emitter = new lib$
|
|
8128
|
-
const publicEmitter = new lib$
|
|
8175
|
+
const emitter = new lib$3.StrictEventEmitter();
|
|
8176
|
+
const publicEmitter = new lib$3.StrictEventEmitter();
|
|
8129
8177
|
pipeEvents(emitter, publicEmitter);
|
|
8130
8178
|
return function setupServer(...requestHandlers) {
|
|
8131
8179
|
requestHandlers.forEach((handler) => {
|
|
@@ -8136,7 +8184,7 @@ function createSetupServer(...interceptors$1) {
|
|
|
8136
8184
|
// so it could be modified at a runtime.
|
|
8137
8185
|
let currentHandlers = [...requestHandlers];
|
|
8138
8186
|
// Error when attempting to run this function in a browser environment.
|
|
8139
|
-
if (!lib$
|
|
8187
|
+
if (!lib$4.exports.isNodeProcess()) {
|
|
8140
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.'));
|
|
8141
8189
|
}
|
|
8142
8190
|
let resolvedOptions = {};
|