decompress
Advanced tools
Comparing version
215
index.js
'use strict'; | ||
var fs = require('fs'); | ||
var map = require('map-key'); | ||
var mkdir = require('mkdirp'); | ||
var each = require('each-async'); | ||
var fs = require('fs-extra'); | ||
var path = require('path'); | ||
var pipeline = require('stream-combiner'); | ||
var rm = require('rimraf'); | ||
var tempfile = require('tempfile'); | ||
var Ware = require('ware'); | ||
/** | ||
* Initialize Decompress with options | ||
* Initialize Decompress | ||
* | ||
* Options: | ||
* | ||
* - `ext` String with file name, MIME type, etc | ||
* - `path` Path to extract to | ||
* - `strip` Equivalent to --strip-components for tar | ||
* | ||
* @param {Object} opts | ||
* @api private | ||
* @api public | ||
*/ | ||
function Decompress(opts) { | ||
opts = opts || {}; | ||
this.opts = opts; | ||
this.path = opts.path || process.cwd(); | ||
this.ext = opts.ext || ''; | ||
this.strip = +opts.strip || 0; | ||
this.extractors = { | ||
'.zip': this._extractZip, | ||
'.tar': this._extractTar, | ||
'.tar.gz': this._extractTarGz, | ||
'.tgz': this._extractTarGz, | ||
'application/zip': this._extractZip, | ||
'application/x-gzip': this._extractTarGz, | ||
'application/x-tar': this._extractTar, | ||
'application/x-tgz': this._extractTarGz | ||
}; | ||
this.extractor = this._getExtractor(this.ext); | ||
function Decompress() { | ||
this.ware = new Ware(); | ||
} | ||
/** | ||
* Extract an archive | ||
* Add a plugin to the middleware stack | ||
* | ||
* @param {Function} plugin | ||
* @api public | ||
*/ | ||
Decompress.prototype.extract = function () { | ||
var self = this; | ||
var stream = this.extractor(); | ||
if (!fs.existsSync(this.path)) { | ||
mkdir.sync(self.path); | ||
} | ||
return stream; | ||
Decompress.prototype.use = function (plugin) { | ||
this.ware.use(plugin); | ||
return this; | ||
}; | ||
/** | ||
* Check if a file can be extracted | ||
* Get or set the source file | ||
* | ||
* @param {String} src | ||
* @param {String} mime | ||
* @param {String|Buffer} file | ||
* @api public | ||
*/ | ||
Decompress.prototype.canExtract = function (src, mime) { | ||
if (this._getExtractor(src)) { | ||
return true; | ||
Decompress.prototype.src = function (file) { | ||
if (!arguments.length) { | ||
return this._src; | ||
} | ||
if (mime && this._getExtractor(mime)) { | ||
return true; | ||
} | ||
return false; | ||
this._src = file; | ||
return this; | ||
}; | ||
/** | ||
* Get the extractor for a desired file | ||
* Get or set the destination path | ||
* | ||
* @param {String} src | ||
* @api private | ||
* @param {String} path | ||
* @api public | ||
*/ | ||
Decompress.prototype._getExtractor = function (src) { | ||
src = src.toLowerCase(); | ||
return map(this.extractors, src); | ||
Decompress.prototype.dest = function (path) { | ||
if (!arguments.length) { | ||
return this._dest; | ||
} | ||
this._dest = path; | ||
return this; | ||
}; | ||
/** | ||
* Extract a zip file | ||
* Decompress archive | ||
* | ||
* @api private | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Decompress.prototype._extractZip = function () { | ||
var AdmZip = require('adm-zip'); | ||
var tmp = tempfile('.zip'); | ||
Decompress.prototype.decompress = function (cb) { | ||
cb = cb || function () {}; | ||
var self = this; | ||
var stream = fs.createWriteStream(tmp); | ||
var zip; | ||
stream.on('close', function () { | ||
zip = new AdmZip(tmp); | ||
this.read(function (err, file) { | ||
if (!file || file.contents.length === 0) { | ||
return cb(); | ||
} | ||
zip.getEntries().forEach(function (entry) { | ||
if (!entry.isDirectory) { | ||
var dest; | ||
var dir = path.dirname(entry.entryName.toString()).split('/'); | ||
var file = path.basename(entry.rawEntryName.toString()); | ||
self.run(file, function (err) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
if (self.strip) { | ||
dir = dir.slice(self.strip); | ||
} | ||
dest = path.join(self.path, dir.join(path.sep), file); | ||
mkdir.sync(path.dirname(dest)); | ||
fs.writeFileSync(dest, entry.getData()); | ||
if (self.opts.mode) { | ||
fs.chmodSync(dest, self.opts.mode); | ||
} | ||
} | ||
self.write(self.files, function (err) { | ||
cb(err, file); | ||
}); | ||
}); | ||
rm.sync(tmp); | ||
}); | ||
}; | ||
return stream; | ||
/** | ||
* Run a file through the middleware | ||
* | ||
* @param {Object} file | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Decompress.prototype.run = function (file, cb) { | ||
this.ware.run(file, this, cb); | ||
}; | ||
/** | ||
* Extract a tar file | ||
* Read the archive | ||
* | ||
* @api private | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Decompress.prototype._extractTar = function () { | ||
var tar = require('tar'); | ||
var stream = tar.Extract(this.opts); | ||
Decompress.prototype.read = function (cb) { | ||
var file = {}; | ||
var src = this.src(); | ||
return stream; | ||
if (Buffer.isBuffer(src)) { | ||
file.contents = src; | ||
return cb(null, file); | ||
} | ||
fs.readFile(src, function (err, buf) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
file.contents = buf; | ||
file.path = src; | ||
cb(null, file); | ||
}); | ||
}; | ||
/** | ||
* Extract a tar.gz file | ||
* Write files to destination | ||
* | ||
* @api private | ||
* @param {Array} files | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Decompress.prototype._extractTarGz = function () { | ||
var tar = require('tar'); | ||
var zlib = require('zlib'); | ||
var stream = zlib.Unzip(); | ||
var dest = tar.Extract(this.opts); | ||
Decompress.prototype.write = function (files, cb) { | ||
var dest = this.dest(); | ||
return pipeline(stream, dest); | ||
if (!dest) { | ||
return cb(); | ||
} | ||
each(files, function (file, i, done) { | ||
fs.outputFile(path.join(dest, file.path), file.contents, function (err) { | ||
done(err); | ||
}); | ||
}, function (err) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
cb(); | ||
}); | ||
}; | ||
@@ -167,10 +163,5 @@ | ||
module.exports = function (opts) { | ||
var decompress = new Decompress(opts); | ||
return decompress.extract(); | ||
}; | ||
module.exports.canExtract = function (src, mime) { | ||
var decompress = new Decompress(); | ||
return decompress.canExtract(src, mime); | ||
}; | ||
module.exports = Decompress; | ||
module.exports.tar = require('decompress-tar'); | ||
module.exports.targz = require('decompress-targz'); | ||
module.exports.zip = require('decompress-zip'); |
{ | ||
"name": "decompress", | ||
"version": "0.2.4", | ||
"version": "0.3.0", | ||
"description": "Easily extract zip, tar and tar.gz archives", | ||
@@ -15,5 +15,2 @@ "license": "MIT", | ||
}, | ||
"bin": { | ||
"decompress": "cli.js" | ||
}, | ||
"scripts": { | ||
@@ -23,6 +20,6 @@ "test": "mocha --reporter list" | ||
"files": [ | ||
"cli.js", | ||
"index.js" | ||
], | ||
"keywords": [ | ||
"decompress", | ||
"extract", | ||
@@ -34,12 +31,8 @@ "tar", | ||
"dependencies": { | ||
"adm-zip": "^0.4.3", | ||
"extname": "^0.1.1", | ||
"get-stdin": "^0.1.0", | ||
"map-key": "^0.1.1", | ||
"mkdirp": "^0.3.5", | ||
"nopt": "^2.2.0", | ||
"rimraf": "^2.2.2", | ||
"stream-combiner": "^0.0.4", | ||
"tar": "^0.1.18", | ||
"tempfile": "^0.1.2" | ||
"decompress-tar": "^0.1.0", | ||
"decompress-targz": "^0.1.0", | ||
"decompress-zip": "^0.1.0", | ||
"each-async": "^0.1.3", | ||
"fs-extra": "^0.8.1", | ||
"ware": "^0.2.1" | ||
}, | ||
@@ -46,0 +39,0 @@ "devDependencies": { |
# decompress [](https://travis-ci.org/kevva/decompress) | ||
> Easily extract `.zip`, `.tar` and `.tar.gz` archives | ||
> Easily extract archives | ||
@@ -13,80 +13,14 @@ ## Install | ||
You'll only need to pass a type into `ext` and it'll figure the rest out for | ||
you. | ||
```js | ||
var decompress = require('decompress'); | ||
var fs = require('fs'); | ||
var Decompress = require('decompress'); | ||
var decompress = new Decompress() | ||
.src('foo.zip') | ||
.dest('destFolder') | ||
.use(Decompress.zip({ strip: 1 })); | ||
fs.createReadStream('foo.tar.gz').pipe(decompress({ ext: '.tar.gz' })); | ||
decompress.decompress(); | ||
``` | ||
## API | ||
### decompress(opts) | ||
Extract an archive using the `ext` option to determine which extractor to use. | ||
If no `path` is specified it'll extract it to your current location. | ||
### decompress.canExtract(src, mime) | ||
Determine if a file can be extracted or not by checking the file extension | ||
and/or the MIME type. | ||
```js | ||
decompress.canExtract('foo.zip'); | ||
// => true | ||
decompress.canExtract('application/zip'); | ||
// => true | ||
``` | ||
## Options | ||
### `ext` | ||
Type: `String` | ||
Default: `''` | ||
String that can be a file name, URL, MIME type etc. | ||
### `path` | ||
Type: `String` | ||
Default: `process.cwd()` | ||
Path to extract the archive to. If no `path` is defined it'll extract it to your | ||
current location. | ||
### `strip` | ||
Type: `Number` | ||
Default: `0` | ||
Equivalent to `--strip-components` for tar. | ||
## CLI | ||
```bash | ||
$ npm install --global decompress | ||
``` | ||
```bash | ||
$ decompress --help | ||
Usage | ||
$ decompress <file> | ||
$ cat <file> | decompress | ||
Example | ||
$ decompress --out dist --strip 1 archive.zip | ||
$ cat files.txt | decompress --out dist | ||
Options | ||
-o, --out <path> Path to extract the archive to | ||
-s, --strip <number> Strip path segments from root when extracting | ||
``` | ||
## License | ||
MIT © [Kevin Mårtensson](http://kevinmartensson.com) |
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
6
-40%2
-33.33%4056
-49.41%3
-25%134
-39.37%26
-71.74%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ 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