333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
'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