Mirror: A Node.js fetch shim using built-in Request, Response, and Headers (but without native fetch)
at v0.4.5 124 lines 4.0 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} 84 85interface _Response extends Or<Response, globalThis.Response> {} 86interface ResponseClass 87 extends Or<typeof Response, typeof globalThis.Response> { 88 new (body?: BodyInit, init?: _ResponseInit): _Response; 89} 90 91interface _Headers extends Or<Headers, globalThis.Headers> {} 92interface HeadersClass extends Or<typeof Headers, typeof globalThis.Headers> { 93 new (init?: HeadersInit): _Headers; 94} 95 96interface _FormData 97 extends Or< 98 FormData & _Iterable<[string, FormDataEntryValue]>, 99 globalThis.FormData 100 > {} 101interface FormDataClass 102 extends Or<typeof FormData, typeof globalThis.FormData> {} 103 104let _Request: RequestClass; 105let _Response: ResponseClass; 106let _Headers: HeadersClass; 107let _FormData: FormDataClass; 108if (typeof Request !== 'undefined') _Request = Request; 109if (typeof Response !== 'undefined') _Response = Response; 110if (typeof Headers !== 'undefined') _Headers = Headers; 111if (typeof FormData !== 'undefined') _FormData = FormData; 112 113export { 114 type _RequestInit as RequestInit, 115 type _ResponseInit as ResponseInit, 116 _Blob as Blob, 117 _File as File, 118 _URL as URL, 119 _URLSearchParams as URLSearchParams, 120 _Request as Request, 121 _Response as Response, 122 _Headers as Headers, 123 _FormData as FormData, 124};