Mirror: A Node.js fetch shim using built-in Request, Response, and Headers (but without native fetch)
at v0.2.1 3.8 kB view raw
1import * as buffer from 'node:buffer'; 2 3type Or<T, U> = void extends T ? U : T; 4 5export type HeadersInit = 6 | string[][] 7 | Record<string, string | ReadonlyArray<string>> 8 | _Headers; 9 10export type FormDataEntryValue = string | _File; 11 12export type RequestInfo = string | _URL | _Request; 13 14interface _Iterable<T, TReturn = any, TNext = any> 15 extends Or< 16 Iterable<T, TReturn, TNext>, 17 globalThis.Iterable<T, TReturn, TNext> 18 > {} 19interface _AsyncIterable<T, TReturn = any, TNext = any> 20 extends Or< 21 AsyncIterable<T, TReturn, TNext>, 22 globalThis.AsyncIterable<T, TReturn, TNext> 23 > {} 24interface _ReadableStream<T = any> 25 extends Or<ReadableStream<T>, globalThis.ReadableStream<T>> {} 26 27// NOTE: AsyncIterable<Uint8Array> is left out 28export type BodyInit = 29 | ArrayBuffer 30 | _Blob 31 | NodeJS.ArrayBufferView 32 | _URLSearchParams 33 | _ReadableStream 34 | _AsyncIterable<Uint8Array> 35 | _FormData 36 | _Iterable<Uint8Array> 37 | null 38 | string; 39 40// See: https://nodejs.org/docs/latest-v20.x/api/globals.html#class-file 41// The `File` global was only added in Node.js 20 42interface _File extends _Blob, Or<File, globalThis.File> { 43 readonly name: string; 44 readonly lastModified: number; 45} 46interface _File extends Or<globalThis.File, buffer.File> {} 47interface FileClass extends Or<typeof globalThis.File, typeof buffer.File> {} 48const _File: FileClass = globalThis.File || buffer.File; 49if (typeof globalThis.File === 'undefined') { 50 globalThis.File = _File; 51} 52 53// There be dragons here. 54// This is complex because of overlapping definitions in lib.dom, @types/node, and undici-types 55// Some types define and overload constructor interfaces with type interfaces 56// Here, we have to account for global differences and split the overloads apart 57 58interface _RequestInit extends Or<RequestInit, globalThis.RequestInit> { 59 duplex?: 'half'; 60} 61interface _ResponseInit extends Or<ResponseInit, globalThis.ResponseInit> {} 62 63interface _Blob extends Or<Blob, globalThis.Blob> {} 64interface BlobClass extends Or<typeof Blob, typeof globalThis.Blob> {} 65const _Blob: BlobClass = Blob; 66 67interface _URLSearchParams 68 extends Or<URLSearchParams, globalThis.URLSearchParams> {} 69interface URLSearchParamsClass 70 extends Or<typeof URLSearchParams, typeof globalThis.URLSearchParams> {} 71const _URLSearchParams: URLSearchParamsClass = URLSearchParams as any; 72 73interface _URL extends Or<URL, globalThis.URL> {} 74interface URLClass extends Or<typeof URL, typeof globalThis.URL> {} 75const _URL: URLClass = URL; 76 77interface _Request extends Or<Request, globalThis.Request> {} 78interface RequestClass extends Or<typeof Request, typeof globalThis.Request> { 79 new ( 80 input: RequestInfo, 81 init?: _RequestInit | Or<RequestInit, globalThis.RequestInit> 82 ): _Request; 83} 84const _Request: RequestClass = Request; 85 86interface _Response extends Or<Response, globalThis.Response> {} 87interface ResponseClass 88 extends Or<typeof Response, typeof globalThis.Response> { 89 new (body?: BodyInit, init?: _ResponseInit): _Response; 90} 91const _Response: ResponseClass = Response; 92 93interface _Headers extends Or<Headers, globalThis.Headers> {} 94interface HeadersClass extends Or<typeof Headers, typeof globalThis.Headers> { 95 new (init?: HeadersInit): _Headers; 96} 97const _Headers: HeadersClass = Headers; 98 99interface _FormData 100 extends Or< 101 FormData & _Iterable<[string, FormDataEntryValue]>, 102 globalThis.FormData 103 > {} 104interface FormDataClass 105 extends Or<typeof FormData, typeof globalThis.FormData> {} 106const _FormData: FormDataClass = FormData; 107 108export { 109 type _RequestInit as RequestInit, 110 type _ResponseInit as ResponseInit, 111 _Blob as Blob, 112 _File as File, 113 _URL as URL, 114 _URLSearchParams as URLSearchParams, 115 _Request as Request, 116 _Response as Response, 117 _Headers as Headers, 118 _FormData as FormData, 119};