* Asynchronously unzips an archive file. * * @param {string} src path to the source file to unzip. * @param {string} dst path to the destination directory. * @return {!Promise } a promise that will resolve with `dst` once the * archive has been unzipped.
(src, dst)
| 161 | * archive has been unzipped. |
| 162 | */ |
| 163 | function unzip(src, dst) { |
| 164 | return load(src).then((zip) => { |
| 165 | const promisedDirs = new Map() |
| 166 | const promises = [] |
| 167 | |
| 168 | zip.z_.forEach((relPath, file) => { |
| 169 | let p |
| 170 | if (file.dir) { |
| 171 | p = createDir(relPath) |
| 172 | } else { |
| 173 | let dirname = path.dirname(relPath) |
| 174 | if (dirname === '.') { |
| 175 | p = writeFile(relPath, file) |
| 176 | } else { |
| 177 | p = createDir(dirname).then(() => writeFile(relPath, file)) |
| 178 | } |
| 179 | } |
| 180 | promises.push(p) |
| 181 | }) |
| 182 | |
| 183 | return Promise.all(promises).then(() => dst) |
| 184 | |
| 185 | function createDir(dir) { |
| 186 | let p = promisedDirs.get(dir) |
| 187 | if (!p) { |
| 188 | p = io.mkdirp(path.join(dst, dir)) |
| 189 | promisedDirs.set(dir, p) |
| 190 | } |
| 191 | return p |
| 192 | } |
| 193 | |
| 194 | function writeFile(relPath, file) { |
| 195 | return file.async('nodebuffer').then((buffer) => io.write(path.join(dst, relPath), buffer)) |
| 196 | } |
| 197 | }) |
| 198 | } |
| 199 | |
| 200 | // PUBLIC API |
| 201 | module.exports = { Zip, load, unzip } |