feat: add endpoint to download whole folder

This commit is contained in:
2025-12-16 10:48:29 +05:30
parent 9e7cbfd3d8
commit 99b447d7cf
4 changed files with 69 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ import {
import { import {
createFile, createFile,
deleteFile, deleteFile,
downloadFolder,
getChildren, getChildren,
getFile, getFile,
updateFile, updateFile,
@@ -215,3 +216,19 @@ export async function fileDownloadHandler(
return err; return err;
} }
} }
export async function folderDownloadHandler(
req: FastifyRequest,
res: FastifyReply
) {
const { folderId } = req.params as { folderId: string };
try {
const folderTree = await downloadFolder(folderId, req.user.tenantId);
if (!folderTree) return res.code(404).send({ error: "resource not found" });
return res.code(200).send(folderTree);
} catch (err) {
return err;
}
}

View File

@@ -6,6 +6,7 @@ import {
fileDownloadHandler, fileDownloadHandler,
fileUploadS3UrlMultiPartHandler, fileUploadS3UrlMultiPartHandler,
finishMulitPartUploadHandler, finishMulitPartUploadHandler,
folderDownloadHandler,
getChildrenHandler, getChildrenHandler,
getFileHandler, getFileHandler,
updateFileHandler, updateFileHandler,
@@ -120,6 +121,15 @@ export async function fileRoutes(fastify: FastifyInstance) {
fileDownloadHandler fileDownloadHandler
); );
fastify.get(
"/:folderId/downloadFolder",
{
config: { requiredClaims: ["file:download"] },
preHandler: [fastify.authorize],
},
folderDownloadHandler
);
fastify.get( fastify.get(
"/multipart", "/multipart",
{ {

View File

@@ -1,6 +1,6 @@
import { AuthenticatedUser } from "../auth"; import { AuthenticatedUser } from "../auth";
import { generateId } from "../utils/id"; import { generateId } from "../utils/id";
import { deleteFileS3 } from "../utils/s3"; import { deleteFileS3, getFileUrlS3 } from "../utils/s3";
import { import {
CreateFileInput, CreateFileInput,
CreateFilesBatch, CreateFilesBatch,
@@ -148,3 +148,43 @@ export async function deleteFile(fileId: string, tenantId: string) {
); );
} }
} }
type File = {
pid: String;
name: String;
type: String;
size?: Number;
children?: File[];
downloadUrl?: String;
};
export async function downloadFolder(folderId: string, tenantId: string) {
async function traverseFolder(folderId: string) {
const fileTree: File[] = [];
const children = await getChildren(folderId, tenantId);
for (const child of children) {
if (child.mimeType == "folder") {
const subTree = await traverseFolder(child.pid);
fileTree.push({
pid: child.pid,
name: child.name,
type: "folder",
children: subTree,
});
} else {
const downloadUrl = await getFileUrlS3(child.pid, null, false);
fileTree.push({
pid: child.pid,
name: child.name,
type: child.mimeType,
downloadUrl,
});
}
}
return fileTree;
}
return await traverseFolder(folderId);
}

View File

@@ -101,7 +101,7 @@ export async function getFileUrlS3(
: undefined, : undefined,
}); });
return await getSignedUrl(client, command, { expiresIn: 300 }); return await getSignedUrl(client, command, { expiresIn: 900 });
} }
export async function deleteFileS3(key: string) { export async function deleteFileS3(key: string) {