gildas-lormeau/zip.js

Issues with the ZipReaderStream example

jespertheend opened this issue · 2 comments

I wanted to take zip data from a POST request, decompress it and write it to disk.
I tried to use this example as a starting point, but ended up running into a couple of issues.

zip.js/index.d.ts

Lines 631 to 641 in 1cb7354

* @example
* This example will take a zip file, decompress it and then recompress each file in it, saving it to disk.
* ```
* for await (const entry of (await fetch(urlToZippedFile)).body.pipeThrough(new ZipWriterStream()))
* if (entry.readable) {
* console.log(entry.filename)
* entry.readable
* .pipeThrough(ZipReaderStream().transform(entry.filename))
* .pipeTo((await Deno.create(entry.filename + '.zip')).writable)
* }
* ```

  1. The first line gave me a type error, because new ZipWriterStream() is not a valid type for pipeThrough(). I think ZipWriterStream and ZipReaderStream need to be swapped in this example.
  2. The zip file I used contains directories, so Deno.create fails for any files inside subdirectories. A call to ensureFile from std/fs fixed this for me.
  3. I think it's best to await the entry.readable.pipeTo() call in case an error is thrown. I had wrapped my code with a try catch block but the errors from the second issue weren't caught.

This is what ended up working for me:

try {
	for await (const entry of (request.body.pipeThrough(new ZipReaderStream()))) {
		const fullPath = stdPath.resolve(tmpDir, entry.filename);
		if (entry.directory) {
			await ensureDir(fullPath);
			continue;
		}

		await ensureFile(fullPath);
		await entry.readable?.pipeTo((await Deno.create(fullPath)).writable);
	}
} catch (e) {
	console.error(e);
	throw new HttpError(STATUS_CODE.InternalServerError, "Failed to parse the zip file.");
}

Thank you very much, I must admit I hadn't tested this piece of code. All your comments are pertinent. Would you like me to integrate the changes for you or would you prefer to submit a PR to make your contribution more official?

I can submit a PR!