Refactor code
This commit is contained in:
@ -2,7 +2,7 @@ import { s3 } from "@/lib/s3";
|
||||
import type { S3Body } from "@/types/s3";
|
||||
import { GetObjectCommand } from "@aws-sdk/client-s3";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { Readable } from "stream";
|
||||
import { Readable } from "node:stream";
|
||||
|
||||
function isWebReadableStream(value: unknown): value is ReadableStream<Uint8Array> {
|
||||
return !!value && typeof (value as ReadableStream<Uint8Array>).getReader === "function";
|
||||
|
||||
@ -4,7 +4,7 @@ import type { S3Body } from "@/types/s3";
|
||||
import { GetObjectCommand } from "@aws-sdk/client-s3";
|
||||
import archiver from "archiver";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { Readable } from "stream";
|
||||
import { Readable } from "node:stream";
|
||||
|
||||
// Streams commission request files (single or zip) from S3.
|
||||
type Mode = "display" | "download" | "bulk";
|
||||
@ -17,13 +17,30 @@ function contentDisposition(filename: string, mode: Mode) {
|
||||
}
|
||||
|
||||
function sanitizeZipEntryName(name: string) {
|
||||
return name.replace(/[^\w.\- ()\[\]]+/g, "_").slice(0, 180);
|
||||
return name.replace(/[^\w.\- ()[\]]+/g, "_").slice(0, 180);
|
||||
}
|
||||
|
||||
function isWebReadableStream(value: unknown): value is ReadableStream<Uint8Array> {
|
||||
return !!value && typeof (value as ReadableStream<Uint8Array>).getReader === "function";
|
||||
}
|
||||
|
||||
function webStreamToAsyncIterable(stream: ReadableStream<Uint8Array>) {
|
||||
const reader = stream.getReader();
|
||||
return {
|
||||
async *[Symbol.asyncIterator]() {
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
if (value) yield value;
|
||||
}
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function toBodyInit(body: S3Body): BodyInit {
|
||||
if (body instanceof Readable) {
|
||||
return Readable.toWeb(body) as ReadableStream<Uint8Array>;
|
||||
@ -141,9 +158,16 @@ export async function GET(req: NextRequest) {
|
||||
if (body instanceof Readable) {
|
||||
archive.append(body, { name: entryName });
|
||||
} else if (isWebReadableStream(body)) {
|
||||
archive.append(Readable.from(body as AsyncIterable<Uint8Array>), { name: entryName });
|
||||
archive.append(Readable.from(webStreamToAsyncIterable(body)), { name: entryName });
|
||||
} else if (body instanceof Blob) {
|
||||
const stream = body.stream();
|
||||
archive.append(Readable.from(webStreamToAsyncIterable(stream)), { name: entryName });
|
||||
} else if (Buffer.isBuffer(body)) {
|
||||
archive.append(body, { name: entryName });
|
||||
} else if (body instanceof Uint8Array) {
|
||||
archive.append(Buffer.from(body), { name: entryName });
|
||||
} else {
|
||||
archive.append(body as Buffer, { name: entryName });
|
||||
throw new Error("Unsupported S3 body type for zip entry");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { useEffect } from "react";
|
||||
|
||||
// Global error UI for the app router segment.
|
||||
export default function Error({
|
||||
export default function ErrorPage({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
@ -27,6 +27,7 @@ export default function Error({
|
||||
|
||||
<div className="flex justify-center gap-4 pt-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={reset}
|
||||
className="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition"
|
||||
>
|
||||
|
||||
@ -21,6 +21,7 @@ export default function GlobalError({
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={reset}
|
||||
className="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user