feat: modernize dashboard widgets
This commit is contained in:
1 parent
1a5e083fd0
commit
6f2cd7fc2b
270 files changed
+10189
-3544
No files matched your search
@@ -0,0 +1,45 @@
|
||||
interface ReadableResponse {
|
||||
headers: { get: (name: string) => string | null };
|
||||
body: {
|
||||
getReader: () => {
|
||||
read: () => Promise<{ done: boolean; value?: Uint8Array }>;
|
||||
cancel: () => Promise<void>;
|
||||
};
|
||||
} | null;
|
||||
}
|
||||
|
||||
export async function readBoundedJsonResponseAsync(
|
||||
response: ReadableResponse,
|
||||
maxBytes: number,
|
||||
label = "Response",
|
||||
): Promise<unknown> {
|
||||
const declaredLength = Number(response.headers.get("content-length"));
|
||||
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
||||
throw new Error(`${label} exceeds ${maxBytes} bytes`);
|
||||
}
|
||||
|
||||
if (!response.body) return null;
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const chunks: Uint8Array[] = [];
|
||||
let byteLength = 0;
|
||||
for (;;) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
if (!value) continue;
|
||||
byteLength += value.byteLength;
|
||||
if (byteLength > maxBytes) {
|
||||
await reader.cancel();
|
||||
throw new Error(`${label} exceeds ${maxBytes} bytes`);
|
||||
}
|
||||
chunks.push(value);
|
||||
}
|
||||
|
||||
const body = new Uint8Array(byteLength);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
body.set(chunk, offset);
|
||||
offset += chunk.byteLength;
|
||||
}
|
||||
return JSON.parse(new TextDecoder().decode(body)) as unknown;
|
||||
}
|
||||
@@ -2,3 +2,4 @@ export * from "./security";
|
||||
export * from "./encryption";
|
||||
export * from "./request";
|
||||
export * from "./errors";
|
||||
export * from "./bounded-response";
|
||||
Reference in new issue
Block a user