Mirror: A Node.js fetch shim using built-in Request, Response, and Headers (but without native fetch)

feat: Add `Body` mixin class (#6)

authored by kitten.sh and committed by GitHub 4913c1df 0ebcb847

Changed files
+63 -1
.changeset
src
+5
.changeset/perfect-dancers-doubt.md
··· 1 + --- 2 + 'fetch-nodeshim': minor 3 + --- 4 + 5 + Add `Body` mixin as export
+57 -1
src/body.ts
··· 1 1 import { Readable } from 'node:stream'; 2 2 import { isAnyArrayBuffer } from 'node:util/types'; 3 3 import { randomBytes } from 'node:crypto'; 4 - import { Blob, FormData, URLSearchParams } from './webstd'; 4 + import { Response, Blob, FormData, URLSearchParams } from './webstd'; 5 5 6 6 export type BodyInit = 7 7 | Exclude<RequestInit['body'], undefined | null> ··· 196 196 body, 197 197 }; 198 198 }; 199 + 200 + const kBodyInternals = Symbol('kBodyInternals'); 201 + 202 + export class Body { 203 + private [kBodyInternals]: BodyState; 204 + 205 + constructor(init: BodyInit | null) { 206 + this[kBodyInternals] = extractBody(init); 207 + } 208 + 209 + get body() { 210 + return this[kBodyInternals].body; 211 + } 212 + 213 + get bodyUsed() { 214 + const { body } = this[kBodyInternals]; 215 + if (isReadable(body)) { 216 + return Readable.isDisturbed(body); 217 + } else if (isReadableStream(body)) { 218 + return body.locked; 219 + } else { 220 + return false; 221 + } 222 + } 223 + 224 + async arrayBuffer() { 225 + const { body } = this[kBodyInternals]; 226 + return isAnyArrayBuffer(body) 227 + ? body 228 + : new Response(this.body).arrayBuffer(); 229 + } 230 + 231 + async formData() { 232 + const { body, contentLength, contentType } = this[kBodyInternals]; 233 + const headers = {}; 234 + if (contentLength) headers['Content-Length'] = contentLength; 235 + if (contentType) headers['Content-Type'] = contentType; 236 + return new Response(body, { headers }).formData(); 237 + } 238 + 239 + async blob() { 240 + const { contentType } = this[kBodyInternals]; 241 + return new Blob([await this.arrayBuffer()], { 242 + type: contentType ?? undefined, 243 + }); 244 + } 245 + 246 + async json() { 247 + const text = await this.text(); 248 + return JSON.parse(text); 249 + } 250 + 251 + async text() { 252 + return new TextDecoder().decode(await this.arrayBuffer()); 253 + } 254 + }
+1
src/index.ts
··· 1 1 export { fetch, fetch as default } from './fetch'; 2 + export { Body } from './body'; 2 3 export * from './webstd';