Skip to content

Commit 4015118

Browse files
committed
Support relative urls
1 parent 3e03ca4 commit 4015118

File tree

4 files changed

+42
-3
lines changed

4 files changed

+42
-3
lines changed

src/index.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,33 @@ function requestNotMatches(request: Request, urlOrPredicate: UrlOrPredicate): bo
309309
return !requestMatches(request, urlOrPredicate);
310310
}
311311

312+
// Node 18 does not support URL.canParse()
313+
export function canParseURL(url: string): boolean {
314+
try {
315+
new URL(url);
316+
return true;
317+
} catch (err) {
318+
return false;
319+
}
320+
}
321+
322+
// Node Requests cannot be relative
323+
function resolveInput(input: string): string {
324+
if (canParseURL(input)) return input;
325+
326+
// Window context
327+
if (typeof window.document !== 'undefined') {
328+
return new URL(input, window.document.baseURI).toString();
329+
}
330+
331+
// Worker context
332+
if (typeof location !== 'undefined') {
333+
return new URL(input, location.origin).toString();
334+
}
335+
336+
return input;
337+
}
338+
312339
function normalizeRequest(input: RequestInput, requestInit?: RequestInit): Request {
313340
if (input instanceof Request) {
314341
if (input.signal && input.signal.aborted) {
@@ -319,12 +346,12 @@ function normalizeRequest(input: RequestInput, requestInit?: RequestInit): Reque
319346
if (requestInit && requestInit.signal && requestInit.signal.aborted) {
320347
abort();
321348
}
322-
return new Request(input, requestInit);
349+
return new Request(resolveInput(input), requestInit);
323350
} else {
324351
if (requestInit && requestInit.signal && requestInit.signal.aborted) {
325352
abort();
326353
}
327-
return new Request(input.toString(), requestInit);
354+
return new Request(resolveInput(input.toString()), requestInit);
328355
}
329356
}
330357

tests/api.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ describe('testing mockResponse', () => {
100100
expect(fetch.mock.calls[0]![0]).toEqual(new URL('https://instagram.com'));
101101
});
102102

103+
it('should support relative request urls', async () => {
104+
fetch.mockResponseOnce(JSON.stringify({ data: 'abcde' }), { status: 200 });
105+
106+
const response = await fetch('folder/file.json').then((res) => res.json());
107+
108+
expect(response).toEqual({ data: 'abcde' });
109+
});
110+
103111
it('should allow empty response bodies', async () => {
104112
fetch.mockResponseOnce(null, { status: 204 });
105113
fetch.mockResponseOnce(undefined, { status: 204 });

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"module": "NodeNext",
44
"moduleResolution": "NodeNext",
55
"lib": [
6-
"es2022"
6+
"es2022",
7+
"dom",
78
],
89
"baseUrl": "./",
910
"paths": {

vitest.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ export default defineConfig({
66
'vitest-fetch-mock': './src/index',
77
},
88
},
9+
test: {
10+
environment: 'jsdom',
11+
},
912
});

0 commit comments

Comments
 (0)