import { FastifyReply, FastifyRequest } from "fastify"; import { generateId } from "../utils/id"; import { completeMultiPartUpload, deleteFileS3, getFileUrlS3, getUploadUrl, getUploadUrlMultiPart, uploadFileS3, } from "../utils/s3"; import { createFile, getFile } from "./file.service"; import { UploadMultiPartCompleteRequest } from "./file.schema"; export async function fileUploadHandler( req: FastifyRequest, res: FastifyReply ) { const file = await req.file(); if (!file) return res.code(400).send({ error: "file not found in the body" }); try { const chunks = []; for await (const chunk of file.file) { // @ts-ignore chunks.push(Buffer.from(chunk)); } const fileData = Buffer.concat(chunks); const key = generateId(); await uploadFileS3(key, fileData); const fileRec = await createFile( key, file.filename, file.mimetype, req.user.tenantId ); return res.code(201).send(fileRec); } catch (err) { return err; } } export async function fileUploadS3UrlHandler( req: FastifyRequest, res: FastifyReply ) { try { const key = generateId(); const signedUrl = await getUploadUrl(key); return res.code(200).send({ key, signedUrl }); } catch (err) { return err; } } export async function fileUploadS3UrlMultiPartHandler( req: FastifyRequest, res: FastifyReply ) { try { const { fileSize } = req.query as { fileSize: number }; if (!fileSize || fileSize == 0) return res.code(400).send({ error: "invalid fileSize" }); const key = generateId(); const multiPartRes = await getUploadUrlMultiPart(key, fileSize); return res.code(200).send({ key, ...multiPartRes }); } catch (err) { return err; } } export async function finishMulitPartUploadHandler( req: FastifyRequest, res: FastifyReply ) { const input = req.body as UploadMultiPartCompleteRequest; try { await completeMultiPartUpload(input.key, input.uploadId, input.parts); return res.code(200).send(); } catch (err) { return err; } } export async function fileDownloadHandler( req: FastifyRequest, res: FastifyReply ) { const { fileId } = req.params as { fileId: string }; const { direct } = req.query as { direct: boolean }; try { let id: string; let name: string | null; if (!direct) { const file = await getFile(fileId, req.user.tenantId); if (file === null) return res.code(404).send({ error: "resource not found" }); id = file.id; name = file.name; } else { id = fileId; name = null; } const signedUrl = await getFileUrlS3(id, name); return res.code(200).send({ url: signedUrl }); } catch (err) { return err; } } export async function deleteFileHandler( req: FastifyRequest, res: FastifyReply ) { const { fileId } = req.params as { fileId: string }; try { const file = await getFile(fileId, req.user.tenantId); if (file === null) return res.code(404).send({ error: "resource not found" }); await deleteFileS3(file.pid); await file.deleteOne(); return res.code(204).send(); } catch (err) { return err; } }