I'm using Next.js and want to create a route to download a zip archive created with Archiver.
The problem is: how to pass Archiver to NextResponse?
Here is my code:
const filesPath = "./data/files/";
const archive = Archiver('zip', { zlib: { level: 9 } });
GetFilesFromKey(token).forEach((filename) => {
archive.file(filesPath + token + "/" + filename.filename, { name: filename.filename });
});
archive.finalize();
// Here needs to be the code that converts "archive" to "BodyInit"
return new NextResponse(SOME BODY INIT, {
headers: {
'Content-Disposition': `attachment; filename="files.zip"`,
'Content-Type': 'application/octet-stream',
},
});
I fixed it:
const filesPath = "./data/files/";
const archive = Archiver('zip', { zlib: { level: 9 } });
const readableStream = new ReadableStream({
start(controller) {
// Pipe data from the archive to the stream
archive.on('data', (chunk) => {
controller.enqueue(chunk);
});
// Handle errors
archive.on('error', (err) => {
console.error('Archiver error:', err);
controller.error(err);
});
// Close the stream when the archive finishes
archive.on('end', () => {
controller.close();
});
// Add files to the archive
GetFilesFromKey(token).forEach((filename) => {
archive.file(filesPath + token + "/" + filename.filename, { name: filename.filename });
});
// Finalize the archive
archive.finalize();
},
});
return new NextResponse(readableStream, {
headers: {
'Content-Disposition': `attachment; filename="files.zip"`,
'Content-Type': 'application/octet-stream',
},
});