extract-zip
Advanced tools
Comparing version 1.0.3 to 1.1.0
#!/usr/bin/env node | ||
var path = require('path') | ||
var minimist = require('minimist') | ||
var extract = require('./') | ||
@@ -15,3 +13,3 @@ | ||
extract(source, {dir: dest}, function(err, results) { | ||
extract(source, {dir: dest}, function (err, results) { | ||
if (err) { | ||
@@ -18,0 +16,0 @@ console.error('error!', err) |
221
index.js
@@ -9,85 +9,92 @@ var fs = require('fs') | ||
module.exports = function(zipPath, opts, cb) { | ||
debug('opening', zipPath, 'with opts', opts) | ||
yauzl.open(zipPath, {autoClose: false}, function(err, zipfile) { | ||
module.exports = function (zipPath, opts, cb) { | ||
debug('creating target directory', opts.dir) | ||
mkdirp(opts.dir, function (err) { | ||
if (err) return cb(err) | ||
var cancelled = false | ||
var finished = false | ||
var q = async.queue(extractEntry, 1) | ||
q.drain = function() { | ||
if (!finished) return | ||
debug('zip extraction complete') | ||
cb() | ||
} | ||
zipfile.on("entry", function(entry) { | ||
debug('zipfile entry', entry.fileName) | ||
if (/\/$/.test(entry.fileName)) { | ||
// directory file names end with '/' | ||
return | ||
openZip() | ||
}) | ||
function openZip () { | ||
debug('opening', zipPath, 'with opts', opts) | ||
yauzl.open(zipPath, {autoClose: false}, function (err, zipfile) { | ||
if (err) return cb(err) | ||
var cancelled = false | ||
var finished = false | ||
var q = async.queue(extractEntry, 1) | ||
q.drain = function () { | ||
if (!finished) return | ||
debug('zip extraction complete') | ||
cb() | ||
} | ||
if (/^__MACOSX\//.test(entry.fileName)) { | ||
// dir name starts with __MACOSX/ | ||
return | ||
} | ||
q.push(entry, function(err) { | ||
debug('finished processing', entry.fileName, {err: err}) | ||
}) | ||
}) | ||
zipfile.on('end', function() { | ||
finished = true | ||
}) | ||
function extractEntry(entry, done) { | ||
if (cancelled) { | ||
debug('skipping entry', entry.fileName, {cancelled: cancelled}) | ||
return setImmediate(done) | ||
} else { | ||
debug('extracting entry', entry.fileName) | ||
} | ||
var dest = path.join(opts.dir, entry.fileName) | ||
var destDir = path.dirname(dest) | ||
// convert external file attr int into a fs stat mode int | ||
var mode = (entry.externalFileAttributes >> 16) & 0xFFFF | ||
// check if it's a symlink or dir (using stat mode constants) | ||
var IFMT = 61440 | ||
var IFDIR = 16384 | ||
var IFLNK = 40960 | ||
var symlink = (mode & IFMT) === IFLNK | ||
var isDir = (mode & IFMT) === IFDIR | ||
// if no mode then default to readable | ||
if (mode === 0) { | ||
if (isDir) mode = 0555 | ||
else mode = 0444 | ||
} | ||
// reverse umask first (~) | ||
var umask = ~process.umask() | ||
// & with processes umask to override invalid perms | ||
var procMode = mode & umask | ||
zipfile.openReadStream(entry, function(err, readStream) { | ||
if (err) { | ||
debug('openReadStream error', err) | ||
cancelled = true | ||
return done(err) | ||
zipfile.on('entry', function (entry) { | ||
debug('zipfile entry', entry.fileName) | ||
if (/^__MACOSX\//.test(entry.fileName)) { | ||
// dir name starts with __MACOSX/ | ||
return | ||
} | ||
readStream.on('error', function(err) { | ||
console.log('read err', err) | ||
q.push(entry, function (err) { | ||
debug('finished processing', entry.fileName, {err: err}) | ||
}) | ||
}) | ||
mkdirp(destDir, function(err) { | ||
zipfile.on('end', function () { | ||
finished = true | ||
}) | ||
function extractEntry (entry, done) { | ||
if (cancelled) { | ||
debug('skipping entry', entry.fileName, {cancelled: cancelled}) | ||
return setImmediate(done) | ||
} | ||
var dest = path.join(opts.dir, entry.fileName) | ||
var destDir = path.dirname(dest) | ||
// convert external file attr int into a fs stat mode int | ||
var mode = (entry.externalFileAttributes >> 16) & 0xFFFF | ||
// check if it's a symlink or dir (using stat mode constants) | ||
var IFMT = 61440 | ||
var IFDIR = 16384 | ||
var IFLNK = 40960 | ||
var symlink = (mode & IFMT) === IFLNK | ||
var isDir = (mode & IFMT) === IFDIR | ||
// if no mode then default to readable | ||
if (mode === 0) { | ||
if (isDir) mode = 365 // 0555 | ||
else mode = 292 // 0444 | ||
} | ||
debug('extracting entry', { filename: entry.fileName, isDir: isDir, isSymlink: symlink }) | ||
// reverse umask first (~) | ||
var umask = ~process.umask() | ||
// & with processes umask to override invalid perms | ||
var procMode = mode & umask | ||
if (isDir) { | ||
debug('creating directory', dest) | ||
return mkdirp(dest, function (err) { | ||
if (err) { | ||
debug('mkdirp error', destDir, {error: err}) | ||
cancelled = true | ||
return done(err) | ||
} | ||
return done() | ||
}) | ||
} | ||
debug('opening read stream', dest) | ||
zipfile.openReadStream(entry, function (err, readStream) { | ||
if (err) { | ||
debug('mkdirp error', destDir, {error: err}) | ||
debug('openReadStream error', err) | ||
cancelled = true | ||
@@ -97,35 +104,39 @@ return done(err) | ||
readStream.on('error', function (err) { | ||
console.log('read err', err) | ||
}) | ||
if (symlink) writeSymlink() | ||
else writeStream() | ||
}) | ||
function writeStream() { | ||
var writeStream = fs.createWriteStream(dest, {mode: procMode}) | ||
readStream.pipe(writeStream) | ||
writeStream.on('finish', function() { | ||
done() | ||
}) | ||
writeStream.on('error', function(err) { | ||
debug('write error', {error: err}) | ||
cancelled = true | ||
return done(err) | ||
}) | ||
} | ||
// AFAICT the content of the symlink file itself is the symlink target filename string | ||
function writeSymlink() { | ||
readStream.pipe(concat(function(data) { | ||
var link = data.toString() | ||
debug('creating symlink', link, dest) | ||
fs.symlink(link, dest, function(err) { | ||
if (err) cancelled = true | ||
done(err) | ||
function writeStream () { | ||
var writeStream = fs.createWriteStream(dest, {mode: procMode}) | ||
readStream.pipe(writeStream) | ||
writeStream.on('finish', function () { | ||
done() | ||
}) | ||
})) | ||
} | ||
}) | ||
} | ||
}) | ||
writeStream.on('error', function (err) { | ||
debug('write error', {error: err}) | ||
cancelled = true | ||
return done(err) | ||
}) | ||
} | ||
// AFAICT the content of the symlink file itself is the symlink target filename string | ||
function writeSymlink () { | ||
readStream.pipe(concat(function (data) { | ||
var link = data.toString() | ||
debug('creating symlink', link, dest) | ||
fs.symlink(link, dest, function (err) { | ||
if (err) cancelled = true | ||
done(err) | ||
}) | ||
})) | ||
} | ||
}) | ||
} | ||
}) | ||
} | ||
} |
{ | ||
"name": "extract-zip", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "unzip a zip file into a directory using 100% pure gluten-free organic javascript", | ||
@@ -10,9 +10,9 @@ "main": "index.js", | ||
"scripts": { | ||
"test": "node test/test.js" | ||
"test": "standard && node test/test.js" | ||
}, | ||
"author": "max ogden", | ||
"license": "BSD", | ||
"license": "BSD-2-Clause", | ||
"repository": { | ||
"type": "git", | ||
"url": "git@github.com:maxogden/extract-zip.git" | ||
"url": "git+ssh://git@github.com/maxogden/extract-zip.git" | ||
}, | ||
@@ -29,12 +29,12 @@ "keywords": [ | ||
"dependencies": { | ||
"minimist": "0.1.0", | ||
"debug": "0.7.4", | ||
"async": "0.9.0", | ||
"mkdirp": "0.5.0", | ||
"concat-stream": "^1.4.6", | ||
"through2": "0.6.3", | ||
"yauzl": "^2.1.0" | ||
"concat-stream": "1.5.0", | ||
"yauzl": "^2.3.1" | ||
}, | ||
"devDependencies": { | ||
"rimraf": "^2.2.8" | ||
"rimraf": "^2.2.8", | ||
"standard": "^5.2.2", | ||
"tape": "^4.2.0" | ||
}, | ||
@@ -41,0 +41,0 @@ "directories": { |
# extract-zip | ||
Streaming unzip written in pure JavaScript. Extracts a zip into a directory. Available as a library or a command line program. | ||
Unzip written in pure JavaScript. Extracts a zip into a directory. Available as a library or a command line program. | ||
@@ -8,2 +8,3 @@ Uses the [`yauzl`](http://npmjs.org/yauzl) ZIP parser. | ||
[![NPM](https://nodei.co/npm/extract-zip.png?global=true)](https://nodei.co/npm/extract-zip/) | ||
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) | ||
@@ -41,2 +42,2 @@ ## Installation | ||
If not specified, `targetDirectory` will default to `process.cwd()`. | ||
If not specified, `targetDirectory` will default to `process.cwd()`. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
5
0
0
42
6400
3
6
131
+ Addedconcat-stream@1.5.0(transitive)
+ Addedprocess-nextick-args@1.0.7(transitive)
+ Addedreadable-stream@2.0.6(transitive)
+ Addedtypedarray@0.0.7(transitive)
- Removedminimist@0.1.0
- Removedthrough2@0.6.3
- Removedbuffer-from@1.1.2(transitive)
- Removedconcat-stream@1.6.2(transitive)
- Removedisarray@0.0.1(transitive)
- Removedminimist@0.1.0(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedreadable-stream@1.0.342.3.8(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedthrough2@0.6.3(transitive)
- Removedtypedarray@0.0.6(transitive)
- Removedxtend@4.0.2(transitive)
Updatedconcat-stream@1.5.0
Updatedyauzl@^2.3.1