UNPKG

cross-unzip

Version:

Cross-platform 'native' unzip in Node.js

78 lines (69 loc) 2.18 kB
'use strict' var spawn = require('child_process').spawn var relative = require('path').relative var basename = require('path').basename var dirname = require('path').dirname var slice = Array.prototype.slice var isWin = process.platform === 'win32' // todo: progress feedback function zip (src, pack, callback) { if (isWin) { var _7z = require('win-7zip')['7z'] // eg. 7z a -tzip archive.zip ./archive run(_7z, ['a', '-tzip', pack, src], callback) } else { // inspired by cross-zip // https://github.com/feross/cross-zip/blob/abf9908a259988657c773ea111f83dfcece2ff5f/index.js#L80-L82 var dir = dirname(src) var file = basename(src) run('zip', ['-r', '-y', pack, file], { cwd: dir }, callback) } } function unzip (pack, dest, callback) { if (isWin) { var _7z = require('win-7zip')['7z'] // 确实奇葩 // eg. 7z x archive.zip -oc:\Doc run(_7z, ['x', pack, '-y', '-o' + dest], callback) } else { run('unzip', ['-o', pack, '-d', dest], callback) } } // https://nodejs.org/api/child_process.html#child_process_event_error // Note that the 'exit' event may or may not fire after an error has occurred. // If you are listening to both the 'exit' and 'error' events, // it is important to guard against accidentally invoking handler functions multiple times. function run (bin, args, opts, callback) { if (!callback) { callback = opts opts = null } opts = Object.assign({}, opts, { stdio: 'ignore' }) callback = onceify(callback) var prc = spawn(bin, args, opts) prc.on('error', function (err) { callback(err) }) prc.on('exit', function (code) { callback(code ? new Error('Exited with code ' + code) : null) }) } // http://stackoverflow.com/questions/30234908/javascript-v8-optimisation-and-leaking-arguments // javascript V8 optimisation and “leaking arguments” // making callback to be invoked only once function onceify (fn) { var called = false return function () { if (called) return called = true fn.apply(this, slice.call(arguments)) // slice arguments } } unzip.isWin = isWin unzip.unzip = unzip unzip.zip = zip module.exports = unzip