Socket
Socket
Sign inDemoInstall

archiver

Package Overview
Dependencies
Maintainers
1
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

archiver - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

benchmark/common.js

26

examples/pack-tgz.js

@@ -5,7 +5,6 @@ var fs = require('fs');

var archiver = require('archiver');
var async = require('async');
var out = fs.createWriteStream('out.tar.gz');
var gzipper = zlib.createGzip();
var archive = archiver.createTar();
var output = fs.createWriteStream(__dirname + '/example-output.tar.gz');
var archive = archiver('tar');

@@ -16,7 +15,12 @@ archive.on('error', function(err) {

archive.pipe(gzipper).pipe(out);
archive.pipe(gzipper).pipe(output);
async.forEach(['file1.js', 'file2.js'], function(file, next) {
archive.addFile(fs.createReadStream(file), { name: file }, next);
}, function(err) {
var file1 = __dirname + '/fixtures/file1.txt';
var file2 = __dirname + '/fixtures/file2.txt';
archive
.addFile(fs.createReadStream(file1), { name: 'file1.txt' })
.addFile(fs.createReadStream(file2), { name: 'file2.txt' });
archive.finalize(function(err, written) {
if (err) {

@@ -26,9 +30,3 @@ throw err;

archive.finalize(function(err, written) {
if (err) {
throw err;
}
console.log(written + ' total bytes written');
});
console.log(written + ' total bytes written');
});

@@ -12,5 +12,3 @@ /**

var archiver = module.exports = {};
archiver.create = function(type, options) {
var archiver = module.exports = function(type, options) {
if (type === 'zip') {

@@ -25,2 +23,4 @@ return new zipArchiver(options);

archiver.create = archiver;
archiver.createTar = function(options) {

@@ -32,2 +32,2 @@ return new tarArchiver(options);

return new zipArchiver(options);
};
};

@@ -9,72 +9,107 @@ /**

var stream = require('stream');
require('../compat/buffer');
var inherits = require('util').inherits;
var Readable = require('stream').Readable || require('readable-stream');
var util = require('../util');
var Archiver = module.exports = function() {
var self = this;
var Archiver = module.exports = function(options) {
Readable.call(this, options);
self.readable = true;
self.paused = false;
self.busy = false;
self.eof = false;
self.queue = [];
self.fileptr = 0;
self.files = [];
this.archiver = {
processing: false,
finalize: false,
finalized: false,
eof: false,
pointer: 0,
file: {},
files: [],
queue: []
};
};
inherits(Archiver, stream.Stream);
inherits(Archiver, Readable);
Archiver.prototype.pause = function() {
var self = this;
self.paused = true;
Archiver.prototype._read = function(n, callback) {
this._processQueue();
};
Archiver.prototype.resume = function() {
var self = this;
self.paused = false;
Archiver.prototype._push = function(data) {
this.push(data);
self._read();
if (data) {
this.archiver.pointer += data.length;
}
};
Archiver.prototype.destroy = function() {
var self = this;
self.readable = false;
Archiver.prototype._emitErrorCallback = function(err, data) {
if (err) {
this.emit('error', err);
}
};
Archiver.prototype._read = function() {
var self = this;
Archiver.prototype._processFile = function(source, data, callback) {
callback(new Error('method not implemented'));
};
if (self.readable === false || self.paused) {
Archiver.prototype._processQueue = function() {
if (this.archiver.processing) {
return;
}
if (self.queue.length > 0) {
var data = self.queue.shift();
self.emit('data', data);
if (this.archiver.queue.length > 0) {
var next = this.archiver.queue.shift();
this._processFile(next.source, next.data, next.callback);
} else if (this.archiver.finalized && this.archiver.eof === false) {
this.archiver.eof = true;
this._push(null);
} else if (this.archiver.finalize && this.archiver.queue.length === 0) {
this._finalize();
}
};
if (self.eof && self.queue.length === 0) {
self.emit('end');
self.readable = false;
Archiver.prototype._finalize = function() {
this.emit('error', new Error('method not implemented'));
};
if (util.lo.isFunction(self.callback)) {
self.callback(null, self.fileptr);
}
Archiver.prototype.append = function(source, data, callback) {
if (typeof source === 'string') {
source = new Buffer(source, 'utf-8');
} else if (source && source.pause) {
source.pause();
}
//TODO look into possible cpu usage issues
util.nextTick(function() {
self._read();
});
};
if (typeof callback !== 'function') {
callback = this._emitErrorCallback.bind(this);
}
Archiver.prototype.addFile = function(source, data, callback) {
// placeholder
if (this.archiver.processing || this.archiver.queue.length) {
this.archiver.queue.push({
data: data,
source: source,
callback: callback
});
} else {
this._processFile(source, data, callback);
}
return this;
};
Archiver.prototype.addFile = Archiver.prototype.append;
Archiver.prototype.finalize = function(callback) {
// placeholder
};
if (typeof callback === 'function') {
this.on('end', function() {
callback(null, this.archiver.pointer);
}.bind(this));
}
this.archiver.finalize = true;
this._processQueue();
return this;
};

@@ -16,9 +16,5 @@ /**

var tarArchiver = module.exports = function(options) {
var self = this;
Archiver.call(this);
Archiver.call(self);
options = options || {};
options = self.options = util.lo.defaults(options, {
options = this.options = util.defaults(options, {
recordSize: 512,

@@ -28,4 +24,4 @@ recordsPerBlock: 20

self.recordSize = options.recordSize;
self.blockSize = options.recordsPerBlock * self.recordSize;
this.recordSize = options.recordSize;
this.blockSize = options.recordsPerBlock * options.recordSize;
};

@@ -35,48 +31,7 @@

tarArchiver.prototype._writeData = function(file, sourceBuffer) {
tarArchiver.prototype._processFile = function(source, data, callback) {
var self = this;
self.archiver.processing = true;
var fileSize = file.size;
file.mode = util.padNumber(file.mode, 7);
file.uid = util.padNumber(file.uid, 7);
file.gid = util.padNumber(file.gid, 7);
file.size = util.padNumber(fileSize, 11);
file.mtime = util.padNumber(file.mtime, 11);
var headerBuffer = headers.file.toBuffer(file);
self.queue.push(headerBuffer);
self.fileptr += headerBuffer.length;
self.queue.push(sourceBuffer);
self.fileptr += sourceBuffer.length;
var extraBytes = self.recordSize - (fileSize % self.recordSize || self.recordSize);
var extraBytesBuffer = util.cleanBuffer(extraBytes);
self.queue.push(extraBytesBuffer);
self.fileptr += extraBytesBuffer.length;
self.files.push(file);
self.busy = false;
};
tarArchiver.prototype.addFile = function(source, data, callback) {
var self = this;
if (util.lo.isFunction(callback) === false) {
callback = util.fallCall;
}
if (self.busy) {
callback(new Error('Previous file not finished'));
return;
}
if (util.lo.isString(source)) {
source = new Buffer(source, 'utf8');
}
var file = util.lo.defaults(data || {}, {
var file = util.defaults(data, {
name: null,

@@ -91,3 +46,3 @@ comment: '',

if (util.lo.isEmpty(file.name) || util.lo.isString(file.name) === false) {
if (typeof file.name !== 'string' || file.name.length === 0) {
callback(new Error('File name is empty or not a valid string value'));

@@ -97,55 +52,55 @@ return;

file.name = util.unixifyPath(file.name);
if (file.name.substring(0, 1) === '/') {
file.name = file.name.substring(1);
}
file.name = util.sanitizeFilePath(file.name);
file.type = '0';
file.size = 0;
if (util.lo.isDate(file.date)) {
file.date = file.date;
} else if (util.lo.isString(file.date)) {
file.date = new Date(file.date);
} else if (util.lo.isNumber(file.mtime) === false) {
file.date = new Date();
}
file.date = util.dateify(file.date);
if (util.lo.isNumber(file.mtime) === false) {
if (typeof file.mtime !== 'number') {
file.mtime = util.octalDateTime(file.date);
}
file.gid = util.lo.isNumber(file.gid) ? file.gid : 0;
file.mode = util.lo.isNumber(file.mode) ? file.mode : parseInt('777', 8) & 0xfff;
file.uid = util.lo.isNumber(file.uid) ? file.uid : 0;
file.gid = typeof file.gid === 'number' ? file.gid : 0;
file.mode = typeof file.mode === 'number' ? file.mode : parseInt('777', 8) & 0xfff;
file.uid = typeof file.uid === 'number' ? file.uid : 0;
self.busy = true;
self.file = file;
file.mode = util.padNumber(file.mode, 7);
file.uid = util.padNumber(file.uid, 7);
file.gid = util.padNumber(file.gid, 7);
file.mtime = util.padNumber(file.mtime, 11);
function onEnd() {
self._writeData(file, source);
file.offset = self.archiver.pointer;
self.archiver.file = file;
var sourceBuffer;
var extraBytes;
function onend() {
file.size = util.padNumber(sourceBuffer.length, 11);
extraBytes = self.recordSize - (sourceBuffer.length % self.recordSize || self.recordSize);
self._push(headers.file.toBuffer(file));
self._push(sourceBuffer);
self._push(util.cleanBuffer(extraBytes));
self.archiver.files.push(file);
self.archiver.processing = false;
callback();
self._processQueue();
}
function update(chunk) {
file.size += chunk.length;
}
if (Buffer.isBuffer(source)) {
update(source);
util.nextTick(onEnd);
sourceBuffer = source;
onend();
} else if (util.isStream(source)) {
util.collectStream(source, function(err, buffer) {
if (err) {
self.emit('error', new Error('Stream collection failed'));
callback(err);
return;
}
update(buffer);
source = buffer;
util.nextTick(onEnd);
sourceBuffer = buffer;
onend();
});

@@ -155,28 +110,11 @@ } else {

}
util.nextTick(function() {
self._read();
});
};
tarArchiver.prototype.finalize = function(callback) {
var self = this;
tarArchiver.prototype._finalize = function() {
var endBytes = this.blockSize - (this.archiver.pointer % this.blockSize);
if (util.lo.isFunction(callback) === false) {
callback = util.fallCall;
}
this.archiver.finalize = false;
this.archiver.finalized = true;
if (self.files.length === 0) {
callback(new Error('No files in archive'));
return;
}
var endBytes = self.blockSize - (self.fileptr % self.blockSize);
var endBytesBuffer = util.cleanBuffer(endBytes);
self.queue.push(endBytesBuffer);
self.fileptr += endBytesBuffer.length;
self.callback = callback;
self.eof = true;
};
this._push(util.cleanBuffer(endBytes));
};

@@ -10,3 +10,2 @@ /**

var inherits = require('util').inherits;
var zlib = require('zlib');

@@ -16,20 +15,14 @@ var Archiver = require('./core');

var util = require('../util');
var DeflateRawChecksum = require('../util/DeflateRawChecksum');
var zipArchiver = module.exports = function(options) {
var self = this;
Archiver.call(this);
Archiver.call(self);
options = self.options = util.lo.defaults(options || {}, {
options = this.options = util.defaults(options, {
comment: '',
forceUTC: false,
zlib: {
level: 6
level: 1
}
});
if (util.lo.isNumber(options.level)) {
options.zlib.level = options.level;
delete options.level;
}
};

@@ -39,38 +32,19 @@

// local file header
zipArchiver.prototype._pushLocalFileHeader = function(file) {
var self = this;
zipArchiver.prototype._buildCentralDirectory = function() {
var files = this.archiver.files;
var comment = this.options.comment;
file.offset = self.fileptr;
var cdoffset = this.archiver.pointer;
var fileHeaderBuffer = headers.file.toBuffer(file);
self.queue.push(fileHeaderBuffer);
self.fileptr += fileHeaderBuffer.length;
};
zipArchiver.prototype._pushDataDescriptor = function(file) {
var self = this;
var dataDescriptorBuffer = headers.descriptor.toBuffer(file);
self.queue.push(dataDescriptorBuffer);
self.fileptr += dataDescriptorBuffer.length;
};
zipArchiver.prototype._pushCentralDirectory = function() {
var self = this;
var cdoffset = self.fileptr;
var ptr = 0;
var cdsize = 0;
var centralDirectoryBuffers = [];
var centralDirectoryBuffer;
for (var i = 0; i < self.files.length; i++) {
var file = self.files[i];
for (var i = 0; i < files.length; i++) {
var file = files[i];
centralDirectoryBuffer = headers.centralHeader.toBuffer(file);
self.queue.push(centralDirectoryBuffer);
centralDirectoryBuffers.push(centralDirectoryBuffer);
ptr += centralDirectoryBuffer.length;

@@ -82,7 +56,7 @@ }

var centralDirectoryFooterData = {
directoryRecordsDisk: self.files.length,
directoryRecords: self.files.length,
directoryRecordsDisk: files.length,
directoryRecords: files.length,
directorySize: cdsize,
directoryOffset: cdoffset,
comment: self.options.comment
comment: comment
};

@@ -92,24 +66,13 @@

self.queue.push(centralDirectoryFooterBuffer);
centralDirectoryBuffers.push(centralDirectoryFooterBuffer);
ptr += centralDirectoryFooterBuffer.length;
self.fileptr += ptr;
return Buffer.concat(centralDirectoryBuffers, ptr);
};
zipArchiver.prototype.addFile = function(source, data, callback) {
zipArchiver.prototype._processFile = function(source, data, callback) {
var self = this;
self.archiver.processing = true;
if (util.lo.isFunction(callback) === false) {
callback = util.fallCall;
}
if (self.busy) {
callback(new Error('Previous file not finished'));
return;
}
if (util.lo.isString(source)) {
source = new Buffer(source, 'utf-8');
}
var file = util.lo.defaults(data || {}, {
var file = util.defaults(data, {
name: null,

@@ -123,3 +86,3 @@ comment: '',

if (util.lo.isEmpty(file.name) || util.lo.isString(file.name) === false) {
if (typeof file.name !== 'string' || file.name.length === 0) {
callback(new Error('File name is empty or not a valid string value'));

@@ -129,17 +92,6 @@ return;

file.name = util.unixifyPath(file.name);
file.name = util.sanitizeFilePath(file.name);
file.date = util.dateify(file.date);
if (file.name.substring(0, 1) === '/') {
file.name = file.name.substring(1);
}
if (util.lo.isDate(file.date)) {
file.date = file.date;
} else if (util.lo.isString(file.date)) {
file.date = new Date(file.date);
} else if (util.lo.isNumber(file.lastModifiedDate) === false) {
file.date = new Date();
}
if (util.lo.isNumber(file.lastModifiedDate) === false) {
if (typeof file.lastModifiedDate !== 'number') {
file.lastModifiedDate = util.dosDateTime(file.date, self.options.forceUTC);

@@ -155,90 +107,81 @@ }

self.busy = true;
self.file = file;
self._pushLocalFileHeader(file);
self.archiver.file = file;
var checksum = util.crc32.createCRC32();
file.offset = self.archiver.pointer;
self._push(headers.file.toBuffer(file));
function onEnd() {
file.crc32 = checksum.digest();
if (file.store) {
file.compressedSize = file.uncompressedSize;
}
var deflate;
self.fileptr += file.compressedSize;
self._pushDataDescriptor(file);
if (file.store === false) {
deflate = new DeflateRawChecksum(self.options.zlib);
self.files.push(file);
self.busy = false;
callback();
deflate.on('error', callback);
deflate.on('data', function(chunk) {
self._push(chunk);
});
deflate.on('end', function() {
file.crc32 = deflate.digest;
file.uncompressedSize = deflate.rawSize;
file.compressedSize = deflate.compressedSize;
onend();
});
}
function update(chunk) {
checksum.update(chunk);
file.uncompressedSize += chunk.length;
function onend() {
self._push(headers.descriptor.toBuffer(file));
self.archiver.files.push(file);
self.archiver.processing = false;
callback();
self._processQueue();
}
if (file.store) {
if (Buffer.isBuffer(source)) {
update(source);
self.queue.push(source);
util.nextTick(onEnd);
if (Buffer.isBuffer(source)) {
if (file.store) {
file.uncompressedSize += source.length;
file.crc32 = util.crc32.createCRC32().update(source).digest();
file.compressedSize = file.uncompressedSize;
self._push(source);
onend();
} else {
// Assume stream
source.on('data', function(chunk) {
update(chunk);
self.queue.push(chunk);
});
source.on('end', onEnd);
deflate.write(source);
deflate.end();
}
} else {
var deflate = zlib.createDeflateRaw(self.zlib);
} else if (util.isStream(source)) {
if (file.store) {
var checksum = util.crc32.createCRC32();
deflate.on('data', function(chunk) {
file.compressedSize += chunk.length;
self.queue.push(chunk);
});
source.on('error', callback);
deflate.on('end', onEnd);
if (Buffer.isBuffer(source)) {
update(source);
deflate.write(source);
deflate.end();
} else if (util.isStream(source)) {
source.on('data', function(chunk) {
update(chunk);
deflate.write(chunk); //TODO check for false & wait for drain
checksum.update(chunk);
file.uncompressedSize += chunk.length;
self._push(chunk);
});
source.on('end', function() {
deflate.end();
source.on('end', function () {
file.compressedSize = file.uncompressedSize;
file.crc32 = checksum.digest();
onend();
});
} else {
callback(new Error('A valid Stream or Buffer instance is needed as input source'));
source.pipe(deflate);
}
if (typeof source.resume === 'function') {
source.resume();
}
} else {
callback(new Error('A valid Stream or Buffer instance is needed as input source'));
}
util.nextTick(function() {
self._read();
});
};
zipArchiver.prototype.finalize = function(callback) {
var self = this;
zipArchiver.prototype._finalize = function() {
this.archiver.finalize = false;
this.archiver.finalized = true;
if (util.lo.isFunction(callback) === false) {
callback = util.fallCall;
}
if (self.files.length === 0) {
callback(new Error('No files in archive'));
return;
}
self.callback = callback;
self._pushCentralDirectory();
self.eof = true;
};
this._push(this._buildCentralDirectory());
};

@@ -84,2 +84,4 @@ /**

}
return this;
};

@@ -86,0 +88,0 @@

@@ -15,4 +15,2 @@ /**

util.lo = require('lodash');
util.crc32 = require('./crc32');

@@ -50,2 +48,6 @@

});
if (typeof stream.resume === 'function') {
stream.resume();
}
};

@@ -69,2 +71,33 @@

util.dateify = function(dateish) {
var date;
if (dateish instanceof Date) {
date = dateish;
} else if (typeof dateish === 'string') {
date = new Date(dateish);
} else {
date = new Date();
}
return date;
};
util.defaults = function(obj) {
obj = obj || {};
var args = Array.prototype.slice.call(arguments, 1);
args.forEach(function(source) {
if (source) {
for (var prop in source) {
if (obj[prop] == null) {
obj[prop] = source[prop];
}
}
}
});
return obj;
};
util.dosDateTime = function(d, utc) {

@@ -93,10 +126,2 @@ d = (d instanceof Date) ? d : new Date();

util.fallCall = function(err, data) {
if (err) {
throw err;
}
return data;
};
util.isStream = function(source) {

@@ -114,3 +139,3 @@ return (source instanceof stream.Stream);

num = num.toString(base || 8);
return this.repeat('0', bytes - num.length) + num;
return util.repeat('0', bytes - num.length) + num;
};

@@ -136,10 +161,15 @@

util.unixifyPath = function(filepath) {
if (process.platform === 'win32') {
return filepath.replace(/\\/g, '/');
} else {
return filepath;
util.sanitizeFilePath = function(filepath) {
filepath = path.normalize(filepath);
filepath = util.unixifyPath(filepath);
while (filepath.substring(0, 1) === '/') {
filepath = filepath.substring(1);
}
return filepath;
};
util.nextTick = (('setImmediate' in global) ? setImmediate : process.nextTick);
util.unixifyPath = function(filepath) {
return filepath.replace(/\\/g, '/');
};
{
"name": "archiver",
"version": "0.3.0",
"version": "0.4.0",
"description": "Creates Archives (ZIP) via Node Streams.",

@@ -28,11 +28,13 @@ "homepage": "https://github.com/ctalkington/node-archiver",

"scripts": {
"test": "nodeunit tests"
"test": "nodeunit test/simple",
"bench": "node benchmark/simple/pack-zip.js"
},
"dependencies": {
"lodash": "~0.10.0",
"rimraf": "~2.0.2",
"mkdirp": "~0.3.4"
"readable-stream": "~0.3.0"
},
"devDependencies": {
"nodeunit": "~0.7.4"
"nodeunit": "~0.7.4",
"rimraf": "~2.1.2",
"mkdirp": "~0.3.4",
"stream-bench": "~0.1.2"
},

@@ -45,2 +47,2 @@ "keywords": [

]
}
}

@@ -1,2 +0,2 @@

# Archiver v0.3.0 [![Build Status](https://secure.travis-ci.org/ctalkington/node-archiver.png?branch=master)](http://travis-ci.org/ctalkington/node-archiver)
# Archiver v0.4.0 [![Build Status](https://secure.travis-ci.org/ctalkington/node-archiver.png?branch=master)](http://travis-ci.org/ctalkington/node-archiver)

@@ -21,15 +21,7 @@ Creates Archives (Zip, Tar) via Node Streams. Depends on Node's build-in zlib module for compression available since version 0.6.3.

#### createZip(options)
Creates an Archiver Zip instance.
#### createTar(options)
Creates an Archiver Tar instance.
### Instance Methods
#### addFile(input, data, callback(err))
#### append(input, data, callback(err))
Adds a file to the instance. Input can be in the form of a text string, buffer, or stream. When the instance has received, processed, and emitted the input, the callback is fired.
Appends a file to the instance. Input can be in the form of a text string, buffer, or stream. When the instance has received, processed, and emitted the input, the callback is fired.

@@ -98,7 +90,2 @@ #### finalize(callback(err, bytesWritten))

Here are a few examples to get you started. All examples use the [async module](https://github.com/caolan/async) to avoid deep nesting of callbacks.
* [basic packing](https://github.com/ctalkington/node-archiver/blob/master/examples/pack.js)
* [tar packing with gzip](https://github.com/ctalkington/node-archiver/blob/master/examples/pack-tgz.js)
Take a peek at the [examples](https://github.com/ctalkington/node-archiver/blob/master/examples) folder for a complete listing.

@@ -105,0 +92,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc