Mirror: A Node.js fetch shim using built-in Request, Response, and Headers (but without native fetch)
1/// <reference types="@types/node" />
2
3import * as buffer from 'node:buffer';
4
5type Or<T, U> = void extends T ? U : T;
6
7export type BodyInit =
8 | ArrayBuffer
9 | AsyncIterable<Uint8Array>
10 | Blob
11 | FormData
12 | Iterable<Uint8Array>
13 | NodeJS.ArrayBufferView
14 | URLSearchParams
15 | null
16 | string;
17
18// See: https://nodejs.org/docs/latest-v20.x/api/globals.html#class-file
19// The `File` global was only added in Node.js 20
20interface _File extends Or<File, globalThis.File> {}
21const _File: Or<typeof File, typeof buffer.File> = buffer.File;
22if (typeof globalThis.File === 'undefined') {
23 globalThis.File = _File;
24}
25
26declare global {
27 var File: typeof _File;
28
29 // NOTE: In case undici was used, but its types aren't applied, this needs to be added
30 interface RequestInit {
31 duplex?: 'half';
32 }
33}
34
35// There be dragons here.
36// This is complex because of overlapping definitions in lib.dom, @types/node, and undici-types
37// Some types define and overload constructor interfaces with type interfaces
38// Here, we have to account for global differences and split the overloads apart
39
40interface _RequestInit extends Or<RequestInit, globalThis.RequestInit> {}
41interface _ResponseInit extends Or<ResponseInit, globalThis.ResponseInit> {}
42
43interface _URLSearchParams
44 extends Or<URLSearchParams, globalThis.URLSearchParams> {}
45interface URLSearchParamsClass
46 extends Or<typeof URLSearchParams, typeof globalThis.URLSearchParams> {}
47const _URLSearchParams: URLSearchParamsClass = URLSearchParams as any;
48
49interface _URL extends Or<URL, globalThis.URL> {}
50interface URLClass extends Or<typeof URL, typeof globalThis.URL> {}
51const _URL: URLClass = URL;
52
53interface _Request extends Or<Request, globalThis.Request> {}
54interface RequestClass extends Or<typeof Request, typeof globalThis.Request> {}
55const _Request: RequestClass = Request;
56
57interface _Response extends Or<Response, globalThis.Response> {}
58interface ResponseClass
59 extends Or<typeof Response, typeof globalThis.Response> {}
60const _Response: ResponseClass = Response;
61
62interface _Headers extends Or<Headers, globalThis.Headers> {}
63interface HeadersClass extends Or<typeof Headers, typeof globalThis.Headers> {}
64const _Headers: HeadersClass = Headers;
65
66interface _FormData extends Or<FormData, globalThis.FormData> {}
67interface FormDataClass
68 extends Or<typeof FormData, typeof globalThis.FormData> {}
69const _FormData: FormDataClass = FormData;
70
71export {
72 type _RequestInit as RequestInit,
73 type _ResponseInit as ResponseInit,
74 _File as File,
75 _URL as URL,
76 _URLSearchParams as URLSearchParams,
77 _Request as Request,
78 _Response as Response,
79 _Headers as Headers,
80 _FormData as FormData,
81};