msw 0.36.1 → 0.36.5
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/README.md +42 -5
- package/lib/esm/RequestHandler-deps.js +24 -9
- package/lib/esm/index.js +14 -25
- package/lib/esm/mockServiceWorker.js +1 -1
- package/lib/esm/rest-deps.js +0 -1
- package/lib/iife/index.js +3 -3
- package/lib/iife/mockServiceWorker.js +1 -1
- package/lib/types/handlers/GraphQLHandler.d.ts +2 -2
- package/lib/types/handlers/RequestHandler.d.ts +7 -7
- package/lib/types/handlers/RestHandler.d.ts +2 -2
- package/lib/types/native/index.d.ts +1 -1
- package/lib/types/node/setupServer.d.ts +1 -1
- package/lib/types/utils/getResponse.d.ts +1 -1
- package/lib/types/utils/handleRequest.d.ts +1 -1
- package/lib/types/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/types/utils/matching/matchRequestUrl.d.ts +1 -1
- package/lib/types/utils/request/onUnhandledRequest.d.ts +1 -2
- package/lib/types/utils/url/isAbsoluteUrl.d.ts +4 -0
- package/lib/umd/index.js +263 -124
- package/lib/umd/mockServiceWorker.js +1 -1
- package/native/lib/index.js +41 -39
- package/node/lib/index.js +41 -39
- package/package.json +13 -4
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Browser usage is what sets Mock Service Worker apart from other tools. Utilizing
|
|
|
56
56
|
|
|
57
57
|
**Watch a 30 seconds explanation on how Mock Service Worker works in a browser:**
|
|
58
58
|
|
|
59
|
-
[](https://youtu.be/HcQCqboatZk)
|
|
60
60
|
|
|
61
61
|
### How is it different?
|
|
62
62
|
|
|
@@ -91,7 +91,7 @@ worker.start()
|
|
|
91
91
|
|
|
92
92
|
Performing a `GET https://github.com/octocat` request in your application will result into a mocked response that you can inspect in your browser's "Network" tab:
|
|
93
93
|
|
|
94
|
-

|
|
95
95
|
|
|
96
96
|
> **Tip:** Did you know that although Service Worker runs in a separate thread, your mock definition executes on the client-side? That way you can use the same languages (i.e. TypeScript), third-party libraries, and internal logic in mocks.
|
|
97
97
|
|
|
@@ -188,8 +188,45 @@ test('handles login exception', () => {
|
|
|
188
188
|
|
|
189
189
|
> **Tip:** Did you know that although the API is called `setupServer`, there are no actual servers involved? The name is chosen for familiarity, and the API is designed to resemble operating with an actual server.
|
|
190
190
|
|
|
191
|
-
##
|
|
191
|
+
## Sponsors
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
### Golden Sponsors
|
|
194
|
+
|
|
195
|
+
> Become our first golden sponsor and get featured right here, enjoying other perks like issue prioritization and a personal consulting session with us.
|
|
196
|
+
>
|
|
197
|
+
> **Learn more on our [GitHub Sponsors profile](https://github.com/sponsors/mswjs)**.
|
|
198
|
+
|
|
199
|
+
### Silver Sponsors
|
|
200
|
+
|
|
201
|
+
> Become our first _silver sponsor_ and get your profile image and link featured right here.
|
|
202
|
+
>
|
|
203
|
+
> **Learn more on our [GitHub Sponsors profile](https://github.com/sponsors/mswjs)**.
|
|
204
|
+
|
|
205
|
+
### Bronze Sponsors
|
|
206
|
+
|
|
207
|
+
> Become our first _bronze sponsor_ and get your profile image and link featured in this section.
|
|
208
|
+
>
|
|
209
|
+
> **Learn more on our [GitHub Sponsors profile](https://github.com/sponsors/mswjs)**.
|
|
210
|
+
|
|
211
|
+
## Awards & Mentions
|
|
194
212
|
|
|
195
|
-
<
|
|
213
|
+
<table>
|
|
214
|
+
<tr valign="middle">
|
|
215
|
+
<td width="124">
|
|
216
|
+
<img src="https://raw.githubusercontent.com/mswjs/msw/main/media/tech-radar.png" width="124" alt="Technology Radar">
|
|
217
|
+
</td>
|
|
218
|
+
<td>
|
|
219
|
+
<h4>Solution Worth Pursuing</h4>
|
|
220
|
+
<p><em><a href="https://www.thoughtworks.com/radar/languages-and-frameworks/mock-service-worker">Technology Radar</a> (2020–2021)</em></p>
|
|
221
|
+
</td>
|
|
222
|
+
</tr>
|
|
223
|
+
<tr>
|
|
224
|
+
<td width="124">
|
|
225
|
+
<img src="https://raw.githubusercontent.com/mswjs/msw/main/media/os-awards.png" width="124" alt="Open Source Awards 2020">
|
|
226
|
+
</td>
|
|
227
|
+
<td>
|
|
228
|
+
<h4>The Most Exciting Use of Technology</h4>
|
|
229
|
+
<p><em><a href="https://osawards.com/javascript/2020">Open Source Awards</a> (2020)</em></p>
|
|
230
|
+
</td>
|
|
231
|
+
</tr>
|
|
232
|
+
</table>
|
|
@@ -136,11 +136,9 @@ var InvariantError = /** @class */ (function (_super) {
|
|
|
136
136
|
_this.name = 'Invariant Violation';
|
|
137
137
|
_this.message = format_1.format.apply(void 0, __spreadArray([message], positionals));
|
|
138
138
|
if (_this.stack) {
|
|
139
|
-
var
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
.slice(STACK_FRAMES_TO_IGNORE)
|
|
143
|
-
.join('\n');
|
|
139
|
+
var nextStack = _this.stack.split('\n');
|
|
140
|
+
nextStack.splice(1, STACK_FRAMES_TO_IGNORE);
|
|
141
|
+
_this.stack = nextStack.join('\n');
|
|
144
142
|
}
|
|
145
143
|
return _this;
|
|
146
144
|
}
|
|
@@ -283,11 +281,12 @@ function parseMultipartData(data, headers) {
|
|
|
283
281
|
* Parses a given request/response body based on the "Content-Type" header.
|
|
284
282
|
*/
|
|
285
283
|
function parseBody(body, headers) {
|
|
284
|
+
var _a;
|
|
286
285
|
// Return whatever falsey body value is given.
|
|
287
286
|
if (!body) {
|
|
288
287
|
return body;
|
|
289
288
|
}
|
|
290
|
-
const contentType = (headers === null || headers === void 0 ? void 0 : headers.get('content-type')) || '';
|
|
289
|
+
const contentType = ((_a = headers === null || headers === void 0 ? void 0 : headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
291
290
|
// If the body has a Multipart Content-Type
|
|
292
291
|
// parse it into an object.
|
|
293
292
|
const hasMultipartContent = contentType.startsWith('multipart/form-data');
|
|
@@ -707,12 +706,23 @@ function cleanUrl(path) {
|
|
|
707
706
|
return path.replace(REDUNDANT_CHARACTERS_EXP, '');
|
|
708
707
|
}
|
|
709
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Determines if the given URL string is an absolute URL.
|
|
711
|
+
*/
|
|
712
|
+
function isAbsoluteUrl(url) {
|
|
713
|
+
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|
714
|
+
}
|
|
715
|
+
|
|
710
716
|
/**
|
|
711
717
|
* Returns an absolute URL based on the given path.
|
|
712
718
|
*/
|
|
713
719
|
function getAbsoluteUrl(path, baseUrl) {
|
|
714
|
-
//
|
|
715
|
-
if (
|
|
720
|
+
// already absolute URL
|
|
721
|
+
if (isAbsoluteUrl(path)) {
|
|
722
|
+
return path;
|
|
723
|
+
}
|
|
724
|
+
// Ignore path with pattern start with *
|
|
725
|
+
if (path.startsWith('*')) {
|
|
716
726
|
return path;
|
|
717
727
|
}
|
|
718
728
|
// Resolve a relative request URL against a given custom "baseUrl"
|
|
@@ -760,12 +770,17 @@ function coercePath(path) {
|
|
|
760
770
|
? `${parameterName}${wildcard}`
|
|
761
771
|
: `${parameterName}${expression}`;
|
|
762
772
|
})
|
|
773
|
+
/**
|
|
774
|
+
* Escape the port so that "path-to-regexp" can match
|
|
775
|
+
* absolute URLs including port numbers.
|
|
776
|
+
*/
|
|
777
|
+
.replace(/([^\/])(:)(?=\d+)/, '$1\\$2')
|
|
763
778
|
/**
|
|
764
779
|
* Escape the protocol so that "path-to-regexp" could match
|
|
765
780
|
* absolute URL.
|
|
766
781
|
* @see https://github.com/pillarjs/path-to-regexp/issues/259
|
|
767
782
|
*/
|
|
768
|
-
.replace(/^([^\/]+)(:)(?=\/\/)
|
|
783
|
+
.replace(/^([^\/]+)(:)(?=\/\/)/, '$1\\$2'));
|
|
769
784
|
}
|
|
770
785
|
/**
|
|
771
786
|
* Returns the result of matching given request URL against a mask.
|
package/lib/esm/index.js
CHANGED
|
@@ -970,10 +970,10 @@ function groupHandlersByType(handlers) {
|
|
|
970
970
|
graphql: [],
|
|
971
971
|
});
|
|
972
972
|
}
|
|
973
|
-
function
|
|
973
|
+
function getRestHandlerScore() {
|
|
974
974
|
return (request, handler) => {
|
|
975
975
|
const { path, method } = handler.info;
|
|
976
|
-
if (path instanceof RegExp) {
|
|
976
|
+
if (path instanceof RegExp || method instanceof RegExp) {
|
|
977
977
|
return Infinity;
|
|
978
978
|
}
|
|
979
979
|
const hasSameMethod = isStringEqual(request.method, method);
|
|
@@ -984,12 +984,15 @@ function getScoreForRestHandler() {
|
|
|
984
984
|
return score - methodScoreDelta;
|
|
985
985
|
};
|
|
986
986
|
}
|
|
987
|
-
function
|
|
987
|
+
function getGraphQLHandlerScore(parsedQuery) {
|
|
988
988
|
return (_, handler) => {
|
|
989
989
|
if (typeof parsedQuery.operationName === 'undefined') {
|
|
990
990
|
return Infinity;
|
|
991
991
|
}
|
|
992
992
|
const { operationType, operationName } = handler.info;
|
|
993
|
+
if (typeof operationName !== 'string') {
|
|
994
|
+
return Infinity;
|
|
995
|
+
}
|
|
993
996
|
const hasSameOperationType = parsedQuery.operationType === operationType;
|
|
994
997
|
// Always treat a handler with the same operation type as a more similar one.
|
|
995
998
|
const operationTypeScoreDelta = hasSameOperationType ? TYPE_MATCH_DELTA : 0;
|
|
@@ -999,16 +1002,12 @@ function getScoreForGraphQLHandler(parsedQuery) {
|
|
|
999
1002
|
}
|
|
1000
1003
|
function getSuggestedHandler(request, handlers, getScore) {
|
|
1001
1004
|
const suggestedHandlers = handlers
|
|
1002
|
-
.reduce((
|
|
1005
|
+
.reduce((suggestions, handler) => {
|
|
1003
1006
|
const score = getScore(request, handler);
|
|
1004
|
-
return
|
|
1007
|
+
return suggestions.concat([[score, handler]]);
|
|
1005
1008
|
}, [])
|
|
1006
|
-
.sort(([leftScore], [rightScore]) =>
|
|
1007
|
-
|
|
1008
|
-
})
|
|
1009
|
-
.filter(([score]) => {
|
|
1010
|
-
return score <= MAX_MATCH_SCORE;
|
|
1011
|
-
})
|
|
1009
|
+
.sort(([leftScore], [rightScore]) => leftScore - rightScore)
|
|
1010
|
+
.filter(([score]) => score <= MAX_MATCH_SCORE)
|
|
1012
1011
|
.slice(0, MAX_SUGGESTION_COUNT)
|
|
1013
1012
|
.map(([, handler]) => handler);
|
|
1014
1013
|
return suggestedHandlers;
|
|
@@ -1038,8 +1037,8 @@ function onUnhandledRequest(request, handlers, strategy = 'warn') {
|
|
|
1038
1037
|
? handlerGroups.graphql
|
|
1039
1038
|
: handlerGroups.rest;
|
|
1040
1039
|
const suggestedHandlers = getSuggestedHandler(request, relevantHandlers, parsedGraphQLQuery
|
|
1041
|
-
?
|
|
1042
|
-
:
|
|
1040
|
+
? getGraphQLHandlerScore(parsedGraphQLQuery)
|
|
1041
|
+
: getRestHandlerScore());
|
|
1043
1042
|
const handlerSuggestion = suggestedHandlers.length > 0
|
|
1044
1043
|
? getSuggestedHandlersMessage(suggestedHandlers)
|
|
1045
1044
|
: '';
|
|
@@ -1062,7 +1061,7 @@ Read more: https://mswjs.io/docs/getting-started/mocks\
|
|
|
1062
1061
|
// Print a developer-friendly error.
|
|
1063
1062
|
devUtils.error('Error: %s', message);
|
|
1064
1063
|
// Throw an exception to halt request processing and not perform the original request.
|
|
1065
|
-
throw new Error('Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.');
|
|
1064
|
+
throw new Error(devUtils.formatMessage('Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.'));
|
|
1066
1065
|
}
|
|
1067
1066
|
case 'warn': {
|
|
1068
1067
|
devUtils.warn('Warning: %s', message);
|
|
@@ -1398,22 +1397,12 @@ function prepareStartHandler(handler, context) {
|
|
|
1398
1397
|
};
|
|
1399
1398
|
}
|
|
1400
1399
|
|
|
1401
|
-
function uuidv4() {
|
|
1402
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
1403
|
-
const r = (Math.random() * 16) | 0;
|
|
1404
|
-
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
1405
|
-
return v.toString(16);
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
1400
|
/**
|
|
1410
1401
|
* Converts a given isomorphic request to a `MockedRequest` instance.
|
|
1411
1402
|
*/
|
|
1412
1403
|
function parseIsomorphicRequest(request) {
|
|
1413
|
-
const requestId = uuidv4();
|
|
1414
|
-
request.headers.set('x-msw-request-id', requestId);
|
|
1415
1404
|
const mockedRequest = {
|
|
1416
|
-
id:
|
|
1405
|
+
id: request.id,
|
|
1417
1406
|
url: request.url,
|
|
1418
1407
|
method: request.method,
|
|
1419
1408
|
body: parseBody(request.body, request.headers),
|
package/lib/esm/rest-deps.js
CHANGED
|
@@ -72,7 +72,6 @@ class RestHandler extends RequestHandler {
|
|
|
72
72
|
const matchesMethod = this.info.method instanceof RegExp
|
|
73
73
|
? this.info.method.test(request.method)
|
|
74
74
|
: isStringEqual(this.info.method, request.method);
|
|
75
|
-
// console.log({ request, matchesMethod, parsedResult })
|
|
76
75
|
return matchesMethod && parsedResult.matches;
|
|
77
76
|
}
|
|
78
77
|
log(request, response) {
|