Comparing version
@@ -1,6 +0,5 @@ | ||
var binary = require('binary'); | ||
var PullStream = require('../PullStream'); | ||
var unzip = require('./unzip'); | ||
var Promise = require('bluebird'); | ||
var BufferStream = require('../BufferStream'); | ||
var read = require('../read'); | ||
@@ -12,5 +11,3 @@ var signature = Buffer(4); | ||
var endDir = PullStream(), | ||
records = PullStream(), | ||
self = this, | ||
vars; | ||
records = PullStream(); | ||
@@ -23,62 +20,33 @@ return source.size() | ||
.then(function() { | ||
return endDir.pull(22); | ||
return read.endOfDirectory(endDir); | ||
}) | ||
.then(function(data) { | ||
vars = binary.parse(data) | ||
.word32lu('signature') | ||
.word16lu('diskNumber') | ||
.word16lu('diskStart') | ||
.word16lu('numberOfRecordsOnDisk') | ||
.word16lu('numberOfRecords') | ||
.word32lu('sizeOfCentralDirectory') | ||
.word32lu('offsetToStartOfCentralDirectory') | ||
.word16lu('commentLength') | ||
.vars; | ||
.then(function(vars) { | ||
Object.defineProperty(vars,'source',{value: source}); | ||
source.stream(vars.offsetToStartOfCentralDirectory).pipe(records); | ||
vars.files = Promise.mapSeries(Array(vars.numberOfRecords),function() { | ||
return records.pull(46).then(function(data) { | ||
var vars = binary.parse(data) | ||
.word32lu('signature') | ||
.word16lu('versionMadeBy') | ||
.word16lu('versionsNeededToExtract') | ||
.word16lu('flags') | ||
.word16lu('compressionMethod') | ||
.word16lu('lastModifiedTime') | ||
.word16lu('lastModifiedDate') | ||
.word32lu('crc32') | ||
.word32lu('compressedSize') | ||
.word32lu('uncompressedSize') | ||
.word16lu('fileNameLength') | ||
.word16lu('extraFieldLength') | ||
.word16lu('fileCommentLength') | ||
.word16lu('diskNumber') | ||
.word16lu('internalFileAttributes') | ||
.word32lu('externalFileAttributes') | ||
.word32lu('offsetToLocalFileHeader') | ||
.vars; | ||
return read.directoryFileHeader(records) | ||
.then(function(file) { | ||
file.stream = function(_password, _raw) { | ||
var input = source.stream(file.offsetToLocalFileHeader); | ||
var output = read.fileStream(input.pipe(PullStream()),{password:_password, raw: _raw}); | ||
return records.pull(vars.fileNameLength).then(function(fileName) { | ||
vars.path = fileName.toString('utf8'); | ||
return records.pull(vars.extraFieldLength); | ||
}) | ||
.then(function(extraField) { | ||
return records.pull(vars.fileCommentLength); | ||
}) | ||
.then(function(comment) { | ||
vars.comment = comment; | ||
vars.stream = function(_password) { | ||
return unzip(source, vars.offsetToLocalFileHeader,_password); | ||
}; | ||
vars.buffer = function(_password) { | ||
return BufferStream(vars.stream(_password)); | ||
}; | ||
return vars; | ||
}); | ||
input.on('error',function(err) { | ||
output.emit('error',err); | ||
}); | ||
return output; | ||
}; | ||
file.buffer = function(_password) { | ||
return BufferStream(file.stream(_password)); | ||
}; | ||
return file; | ||
}); | ||
}); | ||
return Promise.props(vars); | ||
}); | ||
return Promise.props(vars); | ||
}); | ||
}; |
@@ -51,4 +51,28 @@ var fs = require('fs'); | ||
return directory(source); | ||
}, | ||
s3 : function(client,params) { | ||
var source = { | ||
size: function() { | ||
return new Promise(function(resolve,reject) { | ||
client.headObject(params, function(err,d) { | ||
if (err) | ||
reject(err); | ||
else | ||
resolve(d.ContentLength); | ||
}); | ||
}); | ||
}, | ||
stream: function(offset,length) { | ||
var d = {}; | ||
for (var key in params) | ||
d[key] = params[key]; | ||
d.Range = 'bytes='+offset+'-' + (length ? length : ''); | ||
return client.getObject(d).createReadStream(); | ||
} | ||
}; | ||
return directory(source); | ||
} | ||
}; | ||
210
lib/parse.js
var util = require('util'); | ||
var zlib = require('zlib'); | ||
var Stream = require('stream'); | ||
var binary = require('binary'); | ||
var Promise = require('bluebird'); | ||
var PullStream = require('./PullStream'); | ||
var NoopStream = require('./NoopStream'); | ||
var BufferStream = require('./BufferStream'); | ||
var read = require('./read'); | ||
@@ -39,17 +36,22 @@ // Backwards compatibility for node 0.8 | ||
// Read signature and put back on buffer | ||
var signature = data.readUInt32LE(0); | ||
self.buffer = Buffer.concat([data,self.buffer]); | ||
if (signature === 0x04034b50) { | ||
if (signature === 0x04034b50) | ||
return self._readFile(); | ||
} | ||
else if (signature === 0x02014b50) { | ||
self.__ended = true; | ||
return self._readCentralDirectoryFileHeader(); | ||
return read.directoryFileHeader(self) | ||
.then(function(vars) { | ||
return self._readRecord(); | ||
}); | ||
} | ||
else if (signature === 0x06054b50) { | ||
return self._readEndOfCentralDirectoryRecord(); | ||
} | ||
else if (self.__ended) { | ||
else if (signature === 0x06054b50 || self.__ended) { | ||
return self.pull(endDirectorySignature).then(function() { | ||
return self._readEndOfCentralDirectoryRecord(); | ||
return read.endOfDirectory(self); | ||
}) | ||
.then(function() { | ||
self.end(); | ||
self.push(null); | ||
}); | ||
@@ -64,176 +66,38 @@ } | ||
var self = this; | ||
self.pull(26).then(function(data) { | ||
var vars = binary.parse(data) | ||
.word16lu('versionsNeededToExtract') | ||
.word16lu('flags') | ||
.word16lu('compressionMethod') | ||
.word16lu('lastModifiedTime') | ||
.word16lu('lastModifiedDate') | ||
.word32lu('crc32') | ||
.word32lu('compressedSize') | ||
.word32lu('uncompressedSize') | ||
.word16lu('fileNameLength') | ||
.word16lu('extraFieldLength') | ||
.vars; | ||
var entry = read.fileStream(self,self._opts); | ||
return self.pull(vars.fileNameLength).then(function(fileName) { | ||
fileName = fileName.toString('utf8'); | ||
var entry = Stream.PassThrough(); | ||
entry.autodrain = function() { | ||
return new Promise(function(resolve,reject) { | ||
entry.pipe(NoopStream()); | ||
entry.on('finish',resolve); | ||
entry.on('error',reject); | ||
}); | ||
}; | ||
entry.header.then(function(vars) { | ||
var fileSizeKnown = !(vars.flags & 0x08); | ||
entry.path = vars.path; | ||
entry.props = {}; | ||
entry.props.path = vars.fileName; | ||
entry.type = (vars.compressedSize === 0 && /[\/\\]$/.test(vars.path)) ? 'Directory' : 'File'; | ||
entry.buffer = function() { | ||
return BufferStream(entry); | ||
}; | ||
entry.autodrain = function() { | ||
entry.autodraining = true; | ||
return new Promise(function(resolve,reject) { | ||
entry.on('finish',resolve); | ||
entry.on('error',reject); | ||
}); | ||
}; | ||
entry.path = fileName; | ||
entry.props = {}; | ||
entry.props.path = fileName; | ||
entry.type = (vars.compressedSize === 0 && /[\/\\]$/.test(fileName)) ? 'Directory' : 'File'; | ||
self.emit('entry',entry); | ||
if (self._opts.verbose) { | ||
if (entry.type === 'Directory') { | ||
console.log(' creating:', fileName); | ||
} else if (entry.type === 'File') { | ||
if (vars.compressionMethod === 0) { | ||
console.log(' extracting:', fileName); | ||
} else { | ||
console.log(' inflating:', fileName); | ||
} | ||
} | ||
} | ||
if (self._readableState.pipesCount) | ||
self.push(entry); | ||
self.emit('entry', entry); | ||
if (self._readableState.pipesCount) | ||
self.push(entry); | ||
entry | ||
.on('finish', function() { | ||
Promise.resolve(!fileSizeKnown && read.dataDescriptor(self)) | ||
.then(function() { | ||
return self._readRecord(); | ||
}); | ||
self.pull(vars.extraFieldLength).then(function(extraField) { | ||
var extra = binary.parse(extraField) | ||
.word16lu('signature') | ||
.word16lu('partsize') | ||
.word64lu('uncompressedSize') | ||
.word64lu('compressedSize') | ||
.word64lu('offset') | ||
.word64lu('disknum') | ||
.vars; | ||
if (vars.compressedSize === 0xffffffff) | ||
vars.compressedSize = extra.compressedSize; | ||
if (vars.uncompressedSize === 0xffffffff) | ||
vars.uncompressedSize= extra.uncompressedSize; | ||
if (self._opts.verbose) | ||
console.log({ | ||
filename:fileName, | ||
vars: vars, | ||
extra: extra | ||
}); | ||
var fileSizeKnown = !(vars.flags & 0x08), | ||
eof; | ||
var inflater = vars.compressionMethod ? zlib.createInflateRaw() : Stream.PassThrough(); | ||
if (fileSizeKnown) { | ||
entry.size = vars.uncompressedSize; | ||
eof = vars.compressedSize; | ||
} else { | ||
eof = new Buffer(4); | ||
eof.writeUInt32LE(0x08074b50, 0); | ||
} | ||
self.stream(eof) | ||
.pipe(inflater) | ||
.on('error',function(err) { self.emit('error',err);}) | ||
.pipe(entry) | ||
.on('finish', function() { | ||
return fileSizeKnown ? self._readRecord() : self._processDataDescriptor(entry); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; | ||
Parse.prototype._processDataDescriptor = function (entry) { | ||
var self = this; | ||
self.pull(16).then(function(data) { | ||
var vars = binary.parse(data) | ||
.word32lu('dataDescriptorSignature') | ||
.word32lu('crc32') | ||
.word32lu('compressedSize') | ||
.word32lu('uncompressedSize') | ||
.vars; | ||
entry.size = vars.uncompressedSize; | ||
self._readRecord(); | ||
}); | ||
}; | ||
Parse.prototype._readCentralDirectoryFileHeader = function () { | ||
var self = this; | ||
self.pull(42).then(function(data) { | ||
var vars = binary.parse(data) | ||
.word16lu('versionMadeBy') | ||
.word16lu('versionsNeededToExtract') | ||
.word16lu('flags') | ||
.word16lu('compressionMethod') | ||
.word16lu('lastModifiedTime') | ||
.word16lu('lastModifiedDate') | ||
.word32lu('crc32') | ||
.word32lu('compressedSize') | ||
.word32lu('uncompressedSize') | ||
.word16lu('fileNameLength') | ||
.word16lu('extraFieldLength') | ||
.word16lu('fileCommentLength') | ||
.word16lu('diskNumber') | ||
.word16lu('internalFileAttributes') | ||
.word32lu('externalFileAttributes') | ||
.word32lu('offsetToLocalFileHeader') | ||
.vars; | ||
return self.pull(vars.fileNameLength).then(function(fileName) { | ||
vars.fileName = fileName.toString('utf8'); | ||
return self.pull(vars.extraFieldLength); | ||
}) | ||
.then(function(extraField) { | ||
return self.pull(vars.fileCommentLength); | ||
}) | ||
.then(function(fileComment) { | ||
return self._readRecord(); | ||
}); | ||
}); | ||
}; | ||
Parse.prototype._readEndOfCentralDirectoryRecord = function() { | ||
var self = this; | ||
self.pull(18).then(function(data) { | ||
var vars = binary.parse(data) | ||
.word16lu('diskNumber') | ||
.word16lu('diskStart') | ||
.word16lu('numberOfRecordsOnDisk') | ||
.word16lu('numberOfRecords') | ||
.word32lu('sizeOfCentralDirectory') | ||
.word32lu('offsetToStartOfCentralDirectory') | ||
.word16lu('commentLength') | ||
.vars; | ||
self.pull(vars.commentLength).then(function(comment) { | ||
comment = comment.toString('utf8'); | ||
self.end(); | ||
self.push(null); | ||
}); | ||
}); | ||
}; | ||
Parse.prototype.promise = function() { | ||
@@ -240,0 +104,0 @@ var self = this; |
var Stream = require('stream'); | ||
var Parse = require('./parse'); | ||
var duplexer2 = require('duplexer2'); | ||
var BufferStream = require('./BufferStream'); | ||
@@ -10,2 +11,3 @@ // Backwards compatibility for node 0.8 | ||
function parseOne(match,opts) { | ||
opts = opts || {}; | ||
var inStream = Stream.PassThrough({objectMode:true}); | ||
@@ -18,2 +20,3 @@ var outStream = Stream.PassThrough(); | ||
transform._transform = function(entry,e,cb) { | ||
entry.password = opts.password; | ||
if (found || (re && !re.exec(entry.path))) { | ||
@@ -24,2 +27,6 @@ entry.autodrain(); | ||
found = true; | ||
out.emit('entry',entry); | ||
entry.on('error',function(e) { | ||
outStream.emit('error',e); | ||
}); | ||
entry.pipe(outStream) | ||
@@ -36,3 +43,7 @@ .on('error',function(err) { | ||
inStream.pipe(Parse(opts)) | ||
.on('error',function(err) { | ||
outStream.emit('error',err); | ||
}) | ||
.pipe(transform) | ||
.on('error',Object) // Silence error as its already addressed in transform | ||
.on('finish',function() { | ||
@@ -45,3 +56,8 @@ if (!found) | ||
return duplexer2(inStream,outStream); | ||
var out = duplexer2(inStream,outStream); | ||
out.buffer = function() { | ||
return BufferStream(outStream); | ||
}; | ||
return out; | ||
} | ||
@@ -48,0 +64,0 @@ |
@@ -36,3 +36,3 @@ var Stream = require('stream'); | ||
var p = Stream.PassThrough(); | ||
var count = 0,done,packet,self= this; | ||
var done,packet,self= this; | ||
@@ -60,3 +60,3 @@ function pull() { | ||
p.write(packet,function() { | ||
if (!self.buffer.length) self.cb(); | ||
if (self.buffer.length === (eof.length || 0)) self.cb(); | ||
}); | ||
@@ -66,9 +66,8 @@ } | ||
if (!done) { | ||
if (self.finished && !this.__ended) { | ||
if (self.finished && !self.__ended) { | ||
self.removeListener('chunk',pull); | ||
p.emit('error','FILE_ENDED'); | ||
p.emit('error',new Error('FILE_ENDED')); | ||
this.__ended = true; | ||
return; | ||
} | ||
} else { | ||
@@ -108,3 +107,3 @@ self.removeListener('chunk',pull); | ||
if (self.finished) | ||
return reject('FILE_ENDED'); | ||
return reject(new Error('FILE_ENDED')); | ||
self.stream(eof,includeEof) | ||
@@ -111,0 +110,0 @@ .on('error',reject) |
{ | ||
"name": "unzipper", | ||
"version": "0.9.0-rc1", | ||
"version": "0.9.0-rc10", | ||
"description": "Unzip cross-platform streaming API ", | ||
@@ -24,5 +24,2 @@ "author": "Evan Oxfeld <eoxfeld@gmail.com>", | ||
}, | ||
"bin": { | ||
"webunzip": "bin/webunzip.js" | ||
}, | ||
"license": "MIT", | ||
@@ -41,4 +38,5 @@ "dependencies": { | ||
"devDependencies": { | ||
"aws-sdk": "^2.77.0", | ||
"request": "^2.79.0", | ||
"tap": ">= 0.3.0 < 1", | ||
"tap": "^10.3.2", | ||
"temp": ">= 0.4.0 < 1", | ||
@@ -48,10 +46,2 @@ "dirdiff": ">= 0.0.1 < 1", | ||
}, | ||
"dependencies": { | ||
"fstream": "~1.0.10", | ||
"inquirer": "~2.0.0", | ||
"minimist": "~1.2.0", | ||
"multi-progress": "~2.0.0", | ||
"progress": "~1.1.8", | ||
"request": "~2.79.0" | ||
}, | ||
"directories": { | ||
@@ -58,0 +48,0 @@ "example": "examples", |
@@ -64,3 +64,3 @@ # unzipper [](https://api.travis-ci.org/ZJONSSON/node-unzipper) | ||
objectMode: true, | ||
_transform: function(entry,e,cb) { | ||
transform: function(entry,e,cb) { | ||
var fileName = entry.path; | ||
@@ -185,3 +185,26 @@ var type = entry.type; // 'Directory' or 'File' | ||
### Open.s3([aws-sdk], [params]) | ||
This function will return a Promise to the central directory information from a zipfile on S3. Range-headers are used to avoid reading the whole file. Unzipper does not ship with with the aws-sdk so you have to provide an instanciated client as first arguments. The params object requires `Bucket` and `Key` to fetch the correct file. | ||
Example: | ||
```js | ||
var unzipper = require('./unzip'); | ||
var AWS = require('aws-sdk'); | ||
var s3Client = AWS.S3(config); | ||
unzipper.Open.s3(s3Client,{Bucket: 'unzipper', Key: 'archive.zip'}) | ||
.then(function(d) { | ||
console.log('directory',d); | ||
return new Promise(function(resolve,reject) { | ||
d.files[0].stream() | ||
.pipe(fs.createWriteStream('firstFile')) | ||
.on('error',reject); | ||
.on('finish',resolve) | ||
}); | ||
}); | ||
``` | ||
## Licenses | ||
See LICENCE | ||
See LICENCE |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
209
12.97%2
-86.67%30792
-68.59%9
50%6
20%20
-55.56%633
-43.93%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed