mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
import {NextResponse} from "next/server";
|
|
import {auth} from "@/lib/auth/auth";
|
|
import {headers} from "next/headers";
|
|
import {db} from "@/db";
|
|
import * as drizzleDb from "@/db";
|
|
import {eq} from "drizzle-orm";
|
|
import {StorageInput} from "@/features/storages/types";
|
|
import {dispatchStorage} from "@/features/storages/dispatch";
|
|
import {Readable} from "node:stream";
|
|
|
|
export async function GET(
|
|
req: Request,
|
|
{params}: { params: Promise<{ fileName: string }> }
|
|
) {
|
|
const {searchParams} = new URL(req.url);
|
|
const fileName = (await params).fileName;
|
|
const storageId = searchParams.get('storageId');
|
|
|
|
if (!fileName) return NextResponse.json({error: "Missing file parameter"}, {status: 400});
|
|
|
|
const session = await auth.api.getSession({headers: await headers()});
|
|
if (!session) return NextResponse.json({error: "Unauthorized"}, {status: 403});
|
|
|
|
|
|
if (!storageId) {
|
|
return NextResponse.json({error: "Missing storageId in search params"}, {status: 404})
|
|
}
|
|
|
|
const ext = fileName.split(".").pop()?.toLowerCase();
|
|
const contentType =
|
|
ext === "png"
|
|
? "image/png"
|
|
: ext === "jpg" || ext === "jpeg"
|
|
? "image/jpeg"
|
|
: ext === "gif"
|
|
? "image/gif"
|
|
: ext === "webp"
|
|
? "image/webp"
|
|
: "application/octet-stream";
|
|
|
|
try {
|
|
|
|
const path = `images/${fileName}`;
|
|
|
|
const input: StorageInput = {
|
|
action: "get",
|
|
data: {
|
|
path: path,
|
|
},
|
|
metadata: {
|
|
storageId: storageId,
|
|
fileKind: "images"
|
|
}
|
|
}
|
|
|
|
const result = await dispatchStorage(input, undefined, storageId);
|
|
|
|
if (!result.file || !(result.file instanceof Readable)) {
|
|
console.error(`An error occurred while getting file :`, result);
|
|
return NextResponse.json(
|
|
{error: "Invalid file payload"},
|
|
{status: 500}
|
|
);
|
|
}
|
|
|
|
const fileStream = Readable.from(result.file as Readable);
|
|
|
|
const stream = new ReadableStream({
|
|
start(controller) {
|
|
fileStream.on('data', (chunk) => controller.enqueue(chunk));
|
|
fileStream.on('end', () => controller.close());
|
|
fileStream.on('error', (err) => controller.error(err));
|
|
},
|
|
});
|
|
|
|
return new NextResponse(stream, {
|
|
headers: {
|
|
'Content-Disposition': `inline; filename="${fileName}"`,
|
|
"Cache-Control": "no-store",
|
|
"Content-Type": contentType,
|
|
},
|
|
});
|
|
|
|
} catch (err) {
|
|
console.error("Error streaming image:", err);
|
|
return NextResponse.json({error: "Error fetching file"}, {status: 500});
|
|
}
|
|
} |