Skip to content

Commit c6bcd25

Browse files
committed
refactor: improve types in wait-for-fetch
1 parent e7ae1d4 commit c6bcd25

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

addon/src/wait-for-fetch.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,37 @@
11
import { default as waitForPromise } from './wait-for-promise.ts';
22

3+
const properties = [
4+
'ok',
5+
'status',
6+
'statusText',
7+
'bodyUsed',
8+
'headers',
9+
'redirected',
10+
'type',
11+
'url',
12+
] as const satisfies (keyof Response)[];
13+
type ResponseProp = (typeof properties)[number];
14+
function isResponseProperty(maybeProp: string): maybeProp is ResponseProp {
15+
return properties.some((prop) => maybeProp === prop);
16+
}
17+
18+
/**
19+
* Wraps the fetch promise in a test waiter, and also wraps the returned promises' async functions (like json()) in a
20+
* test waiter.
21+
*/
322
export async function waitForFetch(fetchPromise: ReturnType<typeof fetch>) {
423
const response = await waitForPromise(fetchPromise);
524

625
return new Proxy(response, {
726
get(target, prop, receiver) {
8-
if (
9-
typeof prop === 'string' &&
10-
['ok', 'status', 'statusText', 'bodyUsed', 'headers', 'redirected', 'type', 'url'].includes(prop)
11-
) {
27+
/* Depending on the stack, Response is often already a Proxy. Reflect.get() will error for property values, when
28+
* using a Proxy as the _receiver_ arg, so just return the value the normal way to avoid that issue. */
29+
if (typeof prop === 'string' && isResponseProperty(prop)) {
1230
return target[prop];
1331
}
1432
const original = Reflect.get(target, prop, receiver);
1533

34+
// For async functions, call them but wrapped in waitForPromise
1635
if (
1736
typeof prop === 'string' &&
1837
['json', 'text', 'arrayBuffer', 'blob', 'formData', 'bytes'].includes(prop)
@@ -21,10 +40,11 @@ export async function waitForFetch(fetchPromise: ReturnType<typeof fetch>) {
2140
return waitForPromise(original.call(target, ...args));
2241
};
2342
}
43+
// For sync functions, just call them
2444
if (typeof prop === 'string' && ['clone'].includes(prop)) {
25-
return (...args) => {
45+
return (...args: unknown[]) => {
2646
return original.call(target, ...args);
27-
}
47+
};
2848
}
2949
return original;
3050
},

0 commit comments

Comments
 (0)