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

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

Changed files
+63 -1
.changeset
src
+5
.changeset/perfect-dancers-doubt.md
···
···
+
---
+
'fetch-nodeshim': minor
+
---
+
+
Add `Body` mixin as export
+57 -1
src/body.ts
···
import { Readable } from 'node:stream';
import { isAnyArrayBuffer } from 'node:util/types';
import { randomBytes } from 'node:crypto';
-
import { Blob, FormData, URLSearchParams } from './webstd';
export type BodyInit =
| Exclude<RequestInit['body'], undefined | null>
···
body,
};
};
···
import { Readable } from 'node:stream';
import { isAnyArrayBuffer } from 'node:util/types';
import { randomBytes } from 'node:crypto';
+
import { Response, Blob, FormData, URLSearchParams } from './webstd';
export type BodyInit =
| Exclude<RequestInit['body'], undefined | null>
···
body,
};
};
+
+
const kBodyInternals = Symbol('kBodyInternals');
+
+
export class Body {
+
private [kBodyInternals]: BodyState;
+
+
constructor(init: BodyInit | null) {
+
this[kBodyInternals] = extractBody(init);
+
}
+
+
get body() {
+
return this[kBodyInternals].body;
+
}
+
+
get bodyUsed() {
+
const { body } = this[kBodyInternals];
+
if (isReadable(body)) {
+
return Readable.isDisturbed(body);
+
} else if (isReadableStream(body)) {
+
return body.locked;
+
} else {
+
return false;
+
}
+
}
+
+
async arrayBuffer() {
+
const { body } = this[kBodyInternals];
+
return isAnyArrayBuffer(body)
+
? body
+
: new Response(this.body).arrayBuffer();
+
}
+
+
async formData() {
+
const { body, contentLength, contentType } = this[kBodyInternals];
+
const headers = {};
+
if (contentLength) headers['Content-Length'] = contentLength;
+
if (contentType) headers['Content-Type'] = contentType;
+
return new Response(body, { headers }).formData();
+
}
+
+
async blob() {
+
const { contentType } = this[kBodyInternals];
+
return new Blob([await this.arrayBuffer()], {
+
type: contentType ?? undefined,
+
});
+
}
+
+
async json() {
+
const text = await this.text();
+
return JSON.parse(text);
+
}
+
+
async text() {
+
return new TextDecoder().decode(await this.arrayBuffer());
+
}
+
}
+1
src/index.ts
···
export { fetch, fetch as default } from './fetch';
export * from './webstd';
···
export { fetch, fetch as default } from './fetch';
+
export { Body } from './body';
export * from './webstd';