UNPKG

@jeffy-g/unzip

Version:

![GitHub](https://img.shields.io/github/license/jeffy-g/rm-cstyle-cmts?style=flat)

100 lines 2.65 kB
/*! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Copyright (C) 2024 jeffy-g <hirotom1107@gmail.com> Released under the MIT license https://opensource.org/licenses/mit-license.php - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /// <reference path="./ffunzip.d.ts"/> const fs = require("fs"); const path = require("path"); const fflate = require("fflate"); require("colors.ts"); /** * push already created directries * @type {Set<string>} */ const knownDirectories = new Set(); /** * @param {string} parent */ const mkdirs = (parent) => { if (!knownDirectories.has(parent)) { fs.mkdirSync(parent, { recursive: true }); knownDirectories.add(parent); } }; /** * @param {string} path */ const removeLastSlash = (path) => path.replace(/(\/|\\)$/, ""); /** * @type {(destDir: string, promises: Promise<void>[], cb: (...args: any) => void) => TForEachCallback} */ const forEachCallback = (destDir, promises, cb) => ([filename, data]) => { /** * @see {@link knownDirectories push the dirs} * @see {@link mkdirs check already created} */ const size = data.length; const output = `${destDir}/${filename}`; /** @type {TSimpleZipEntry} */ const info = { state: "pending", type: size ? "File" : "Folder", path: filename, size }; if (!size) { mkdirs(output); info.state = "ignore"; cb(info); return; } cb(info); mkdirs(path.dirname(output)); promises.push( fs.promises.writeFile(output, data, "binary").then(() => { info.state = "write"; cb(info); }) ); }; /** * @param {string} fileName zip file path * @param {string} destDir output directory path * @param {TUnzipCallback} cb */ const unzipWithCallback = (fileName, destDir, cb) => { fs.readFile(fileName, null, (err, data) => { if (err) { console.error(err); return; } /** @type {(file: UnzipFileInfo) => boolean} */ const filter = (file) => { cb({ state: "info", type: file.size ? "File" : "Folder", path: file.name, size: file.size }); return true; }; destDir = removeLastSlash(destDir); fflate.unzip(data, { filter }, async (err, unzipped) => { if (err) { console.error(err); return; } /** @type {Promise<void>[]} */ const promises = []; Object.entries(unzipped).forEach(forEachCallback(destDir, promises, cb)); await Promise.all(promises); cb(fileName); knownDirectories.clear(); }); }); }; unzipWithCallback.version = "v1.1.13"; module.exports = unzipWithCallback;