download
Advanced tools
Comparing version 2.0.0 to 3.0.0
289
index.js
'use strict'; | ||
var assign = require('object-assign'); | ||
var archiveType = require('archive-type'); | ||
var Decompress = require('decompress'); | ||
var combine = require('stream-combiner'); | ||
var concat = require('concat-stream'); | ||
var conf = require('rc')('npm'); | ||
var each = require('each-async'); | ||
var fs = require('fs-extra'); | ||
var File = require('vinyl'); | ||
var fs = require('vinyl-fs'); | ||
var path = require('path'); | ||
var rename = require('gulp-rename'); | ||
var tar = require('decompress-tar'); | ||
var tarBz2 = require('decompress-tarbz2'); | ||
var tarGz = require('decompress-targz'); | ||
var through = require('through2'); | ||
var urlRegex = require('url-regex'); | ||
var Ware = require('ware'); | ||
var zip = require('decompress-unzip'); | ||
/** | ||
* Initialize Download | ||
* Initialize a new `Download` | ||
* | ||
@@ -19,48 +27,63 @@ * @param {Object} opts | ||
function Download(opts) { | ||
if (!(this instanceof Download)) { | ||
return new Download(); | ||
} | ||
if (!(this instanceof Download)) { | ||
return new Download(); | ||
} | ||
this._get = []; | ||
this.ware = new Ware(); | ||
this.opts = opts || {}; | ||
this.opts.encoding = null; | ||
this.opts.mode = this.opts.mode || null; | ||
this.opts.proxy = process.env.HTTPS_PROXY || | ||
process.env.https_proxy || | ||
process.env.HTTP_PROXY || | ||
process.env.http_proxy; | ||
this.opts = opts || {}; | ||
this.opts.proxy = conf['https-proxy'] || conf['http-proxy'] || conf.proxy; | ||
this.opts.strictSSL = conf['strict-ssl']; | ||
this.tasks = []; | ||
this.ware = new Ware(); | ||
this._get = []; | ||
} | ||
/** | ||
* Add a URL to download | ||
* Get or set URL to download | ||
* | ||
* @param {String|Object} file | ||
* @param {String} dest | ||
* @param {Object} opts | ||
* @param {String} url | ||
* @api public | ||
*/ | ||
Download.prototype.get = function (file, dest, opts) { | ||
if (!arguments.length) { | ||
return this._get; | ||
} | ||
Download.prototype.get = function (url) { | ||
if (!arguments.length) { | ||
return this._get; | ||
} | ||
if (typeof dest === 'object') { | ||
opts = dest; | ||
dest = undefined; | ||
} | ||
this._get.push(url); | ||
return this; | ||
}; | ||
opts = assign({}, this.opts, opts); | ||
/** | ||
* Get or set the destination folder | ||
* | ||
* @param {String} dir | ||
* @api public | ||
*/ | ||
if (file.url && file.name) { | ||
this._get.push({ url: file.url, name: file.name, dest: dest, opts: opts }); | ||
} else { | ||
this._get.push({ url: file, dest: dest, opts: opts }); | ||
} | ||
Download.prototype.dest = function (dir) { | ||
if (!arguments.length) { | ||
return this._dest; | ||
} | ||
return this; | ||
this._dest = dir; | ||
return this; | ||
}; | ||
/** | ||
* Rename the downloaded file | ||
* | ||
* @param {Function|String} name | ||
* @api public | ||
*/ | ||
Download.prototype.rename = function (name) { | ||
if (!arguments.length) { | ||
return this._name; | ||
} | ||
this._name = name; | ||
return this; | ||
}; | ||
/** | ||
* Add a plugin to the middleware stack | ||
@@ -73,20 +96,16 @@ * | ||
Download.prototype.use = function (plugin) { | ||
this.ware.use(plugin); | ||
return this; | ||
this.ware.use(plugin); | ||
return this; | ||
}; | ||
/** | ||
* Set proxy | ||
* Add a task to the middleware stack | ||
* | ||
* @param {String} proxy | ||
* @param {Function} task | ||
* @api public | ||
*/ | ||
Download.prototype.proxy = function (proxy) { | ||
if (!arguments.length) { | ||
return this.opts.proxy; | ||
} | ||
this.opts.proxy = proxy; | ||
return this; | ||
Download.prototype.pipe = function (task) { | ||
this.tasks.push(task); | ||
return this; | ||
}; | ||
@@ -102,137 +121,95 @@ | ||
Download.prototype.run = function (cb) { | ||
cb = cb || function () {}; | ||
cb = cb || function () {}; | ||
var files = []; | ||
var request = require('request'); | ||
var self = this; | ||
var request = require('request'); | ||
var self = this; | ||
var files = []; | ||
each(this.get(), function (obj, i, done) { | ||
var name = obj.name || path.basename(obj.url); | ||
var ret = []; | ||
each(this.get(), function (url, i, done) { | ||
var ret = []; | ||
var len = 0; | ||
request.get(obj.url, obj.opts) | ||
.on('error', done) | ||
if (!urlRegex().test(url)) { | ||
done(new Error('Specify a valid URL')); | ||
return; | ||
} | ||
.on('data', function (data) { | ||
ret.push(data); | ||
}) | ||
request.get(url, self.opts) | ||
.on('response', function (res) { | ||
if (res.statusCode < 200 || res.statusCode >= 300) { | ||
res.destroy(); | ||
done(new Error(res.statusCode)); | ||
return; | ||
} | ||
.on('response', function (res) { | ||
if (res.statusCode < 200 || res.statusCode >= 300) { | ||
cb(res.statusCode); | ||
return; | ||
} | ||
res.on('error', done); | ||
res.on('data', function (data) { | ||
ret.push(data); | ||
len += data.length; | ||
}); | ||
self._run(res, obj); | ||
}) | ||
self.ware.run(res, url); | ||
.on('end', function () { | ||
files.push({ url: obj.url, contents: Buffer.concat(ret) }); | ||
res.on('end', function () { | ||
files.push({ | ||
path: path.basename(url), | ||
contents: Buffer.concat(ret, len) | ||
}); | ||
if (!obj.dest) { | ||
done(); | ||
return; | ||
} | ||
done(); | ||
}); | ||
}) | ||
if (obj.opts.extract && archiveType(Buffer.concat(ret))) { | ||
return self._extract(Buffer.concat(ret), obj.dest, obj.opts, function (err) { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
.on('error', done); | ||
}, function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
done(); | ||
}); | ||
} | ||
var pipe = self.construct(files); | ||
var end = concat(function (files) { | ||
cb(null, files, pipe); | ||
}); | ||
self._write(Buffer.concat(ret), path.join(obj.dest, name), obj.opts, function (err) { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
pipe.on('error', function (err) { | ||
cb(err); | ||
return; | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}, function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
cb(null, files); | ||
}); | ||
pipe.pipe(end); | ||
}); | ||
}; | ||
/** | ||
* Run the response through the middleware | ||
* Construct stream | ||
* | ||
* @param {Object} res | ||
* @param {Object} file | ||
* @param {Array} files | ||
* @api public | ||
*/ | ||
Download.prototype._run = function (res, file) { | ||
this.ware.run(res, file); | ||
}; | ||
Download.prototype.construct = function (files) { | ||
var stream = through.obj(); | ||
/** | ||
* Write to file | ||
* | ||
* @param {Buffer} buf | ||
* @param {String} dest | ||
* @param {Object} opts | ||
* @param {Function} cb | ||
* @api private | ||
*/ | ||
files.forEach(function (file) { | ||
stream.write(new File(file)); | ||
}); | ||
Download.prototype._write = function (buf, dest, opts, cb) { | ||
fs.outputFile(dest, buf, function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
stream.end(); | ||
if (opts.mode) { | ||
return fs.chmod(dest, parseInt(opts.mode, 8), function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
if (this.opts.extract) { | ||
this.tasks.unshift(tar(this.opts), tarBz2(this.opts), tarGz(this.opts), zip(this.opts)); | ||
} | ||
cb(); | ||
}); | ||
} | ||
this.tasks.unshift(stream); | ||
cb(); | ||
}); | ||
}; | ||
if (this.rename()) { | ||
this.tasks.push(rename(this.rename())); | ||
} | ||
/** | ||
* Extract archive | ||
* | ||
* @param {Buffer} buf | ||
* @param {String} dest | ||
* @param {Object} opts | ||
* @param {Function} cb | ||
* @api private | ||
*/ | ||
if (this.dest()) { | ||
this.tasks.push(fs.dest(this.dest(), this.opts)); | ||
} | ||
Download.prototype._extract = function (buf, dest, opts, cb) { | ||
var decompress = new Decompress(opts) | ||
.src(buf) | ||
.dest(dest) | ||
.use(Decompress.tar(opts)) | ||
.use(Decompress.tarbz2(opts)) | ||
.use(Decompress.targz(opts)) | ||
.use(Decompress.zip(opts)); | ||
decompress.run(function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
cb(); | ||
}); | ||
return combine(this.tasks); | ||
}; | ||
@@ -239,0 +216,0 @@ |
{ | ||
"name": "download", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "Download and extract files effortlessly", | ||
@@ -15,2 +15,5 @@ "license": "MIT", | ||
}, | ||
"bin": { | ||
"download": "cli.js" | ||
}, | ||
"scripts": { | ||
@@ -30,14 +33,27 @@ "test": "node test/test.js" | ||
"dependencies": { | ||
"archive-type": "^1.0.2", | ||
"decompress": "^2.0.0", | ||
"concat-stream": "^1.4.6", | ||
"decompress-tar": "^2.0.1", | ||
"decompress-tarbz2": "^2.0.1", | ||
"decompress-targz": "^2.0.1", | ||
"decompress-unzip": "^2.0.0", | ||
"download-status": "^2.0.1", | ||
"each-async": "^1.0.0", | ||
"fs-extra": "^0.11.1", | ||
"object-assign": "^1.0.0", | ||
"get-stdin": "^3.0.0", | ||
"gulp-rename": "^1.2.0", | ||
"nopt": "^3.0.1", | ||
"rc": "^0.5.1", | ||
"request": "^2.34.0", | ||
"stream-combiner": "^0.2.1", | ||
"through2": "^0.6.1", | ||
"url-regex": "^1.0.3", | ||
"vinyl": "^0.4.3", | ||
"vinyl-fs": "^0.3.7", | ||
"ware": "^1.0.1" | ||
}, | ||
"devDependencies": { | ||
"ava": "0.0.4", | ||
"archive-type": "^1.0.2", | ||
"ava": "^0.0.4", | ||
"gulp-tar": "^1.1.0", | ||
"nock": "^0.47.0" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# download [![Build Status](http://img.shields.io/travis/kevva/decompress.svg?style=flat)](https://travis-ci.org/kevva/download) | ||
# download [![Build Status](http://img.shields.io/travis/kevva/download.svg?style=flat)](https://travis-ci.org/kevva/download) | ||
@@ -14,21 +14,23 @@ > Download and extract files effortlessly | ||
If you're fetching an archive you can set `extract: true` in options and | ||
it'll extract it for you. | ||
it'll extract it for you. You can also run your files through transform streams | ||
(e.g gulp plugins) using the `.pipe()` method. | ||
```js | ||
var Download = require('download'); | ||
var imagemin = require('gulp-imagemin'); | ||
var progress = require('download-status'); | ||
var download = new Download() | ||
.get('http://example.com/foo.zip', 'destFolder', { extract: true, strip: 1 }) | ||
.get('http://example.com/bar.jpg', 'destFolder') | ||
.get({ url: 'http://example.com/bar.jpg', name: 'foobar.jpg' }, 'destFolder') | ||
.use(progress()); | ||
var download = new Download({ extract: true, strip: 1 }) | ||
.get('http://example.com/foo.zip') | ||
.get('http://example.com/cat.jpg') | ||
.pipe(imagemin({ progressive: true })) | ||
.dest('dest') | ||
.use(progress()); | ||
download.run(function (err, files) { | ||
if (err) { | ||
throw err; | ||
} | ||
download.run(function (err, files, stream) { | ||
if (err) { | ||
throw err; | ||
} | ||
console.log(files); | ||
//=> [{ url: http://example.com/foo.zip, contents: <Buffer 50 4b 03 ...> }, { ... }] | ||
console.log('File downloaded successfully!'); | ||
}); | ||
@@ -41,12 +43,17 @@ ``` | ||
Creates a new `Download` instance. Options defined here will be applied to all | ||
downloads. | ||
Creates a new `Download` instance. | ||
### .get(file, dest, opts) | ||
### .get(url) | ||
Add a file to download. The `file` argument accepts a `String` containing a URL | ||
or an `Object` with a URL and a desired name. For example `{ url: http://example.com/file.zip, name: 'foo.zip' }`. If you don't supply a `dest` no files will be written to the disk. | ||
Add a file to download. | ||
Options defined here will only apply to the specified file. | ||
### .dest(dir) | ||
Set the destination folder to where your files will be downloaded. | ||
### .rename(name) | ||
Rename your files using [gulp-rename](https://github.com/hparra/gulp-rename). | ||
Takes a `String` or a `Function` as argument. | ||
### .use(plugin) | ||
@@ -56,5 +63,5 @@ | ||
### .proxy(proxy) | ||
### .pipe(task) | ||
Set proxy settings. Defaults to `process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy;`. | ||
Pipe your files through a transform stream (e.g a gulp plugin). | ||
@@ -91,4 +98,31 @@ ### .run(cb) | ||
## CLI | ||
```bash | ||
$ npm install --global download | ||
``` | ||
```sh | ||
$ download --help | ||
Usage | ||
download <url> | ||
download <url> > <file> | ||
download --out <directory> <url> | ||
cat <file> | download --out <directory> | ||
Example | ||
download http://foo.com/file.zip | ||
download http://foo.com/cat.png > dog.png | ||
download --extract --strip 1 --out dest http://foo.com/file.zip | ||
cat urls.txt | download --out dest | ||
Options | ||
-e, --extract Try decompressing the file | ||
-o, --out Where to place the downloaded files | ||
-s, --strip <number> Strip leading paths from file names on extraction | ||
``` | ||
## 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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
125
1
7535
18
4
176
1
+ Addedconcat-stream@^1.4.6
+ Addeddecompress-tar@^2.0.1
+ Addeddecompress-tarbz2@^2.0.1
+ Addeddecompress-targz@^2.0.1
+ Addeddecompress-unzip@^2.0.0
+ Addeddownload-status@^2.0.1
+ Addedget-stdin@^3.0.0
+ Addedgulp-rename@^1.2.0
+ Addednopt@^3.0.1
+ Addedrc@^0.5.1
+ Addedstream-combiner@^0.2.1
+ Addedthrough2@^0.6.1
+ Addedurl-regex@^1.0.3
+ Addedvinyl@^0.4.3
+ Addedvinyl-fs@^0.3.7
+ Addedabbrev@1.1.1(transitive)
+ Addedansi-regex@0.2.1(transitive)
+ Addedansi-styles@1.1.0(transitive)
+ Addedbl@0.9.5(transitive)
+ Addedchalk@0.5.1(transitive)
+ Addeddecompress-tar@2.0.2(transitive)
+ Addeddecompress-tarbz2@2.0.2(transitive)
+ Addeddecompress-targz@2.1.0(transitive)
+ Addeddecompress-unzip@2.1.2(transitive)
+ Addeddeep-extend@0.2.11(transitive)
+ Addeddefaults@1.0.4(transitive)
+ Addeddownload-status@2.2.1(transitive)
+ Addedduplexer@0.1.2(transitive)
+ Addedglob-stream@3.1.18(transitive)
+ Addedglob-watcher@0.0.6(transitive)
+ Addedgulp-rename@1.4.0(transitive)
+ Addedhas-ansi@0.1.0(transitive)
+ Addedini@1.3.8(transitive)
+ Addedis-integer@1.0.7(transitive)
+ Addedlongest@1.0.1(transitive)
+ Addedlpad-align@1.1.2(transitive)
+ Addedminimist@0.0.10(transitive)
+ Addednopt@3.0.6(transitive)
+ Addedprogress@1.1.8(transitive)
+ Addedrc@0.5.5(transitive)
+ Addedreadable-stream@1.1.14(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedstream-combiner@0.2.2(transitive)
+ Addedstrip-ansi@0.3.0(transitive)
+ Addedstrip-dirs@0.1.1(transitive)
+ Addedstrip-json-comments@0.1.3(transitive)
+ Addedsupports-color@0.2.0(transitive)
+ Addedtar-stream@0.4.7(transitive)
+ Addedthrough@2.3.8(transitive)
+ Addedunique-stream@1.0.0(transitive)
+ Addedurl-regex@1.0.4(transitive)
+ Addedvinyl-fs@0.3.14(transitive)
- Removedarchive-type@^1.0.2
- Removeddecompress@^2.0.0
- Removedfs-extra@^0.11.1
- Removedobject-assign@^1.0.0
- Removedarchive-type@1.0.4(transitive)
- Removedbuffer-to-vinyl@1.1.0(transitive)
- Removedcamelcase@1.2.1(transitive)
- Removedcamelcase-keys@1.0.0(transitive)
- Removeddecompress@2.3.0(transitive)
- Removeddecompress-tar@3.1.0(transitive)
- Removeddecompress-tarbz2@3.1.0(transitive)
- Removeddecompress-targz@3.1.0(transitive)
- Removeddecompress-unzip@3.4.0(transitive)
- Removedduplexer2@0.1.4(transitive)
- Removedduplexify@3.7.1(transitive)
- Removedfile-type@3.9.0(transitive)
- Removedfs-extra@0.11.1(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedglob@7.2.3(transitive)
- Removedglob-stream@4.1.1(transitive)
- Removedglob-watcher@0.0.8(transitive)
- Removedindent-string@1.2.2(transitive)
- Removedis-7zip@1.0.0(transitive)
- Removedis-rar@1.0.0(transitive)
- Removedjson-stable-stringify-without-jsonify@1.0.1(transitive)
- Removedjsonfile@2.4.0(transitive)
- Removedmeow@2.1.0(transitive)
- Removedmerge-stream@0.1.8(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedncp@0.6.0(transitive)
- Removedobject-assign@1.0.0(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedread-all-stream@3.1.0(transitive)
- Removedread-chunk@1.0.1(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedrepeating@1.1.3(transitive)
- Removedreplace-ext@0.0.1(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedstat-mode@0.2.2(transitive)
- Removedstream-combiner2@1.1.1(transitive)
- Removedstream-shift@1.0.3(transitive)
- Removedthrough2@2.0.54.0.2(transitive)
- Removedthrough2-filter@3.1.0(transitive)
- Removedunique-stream@2.3.1(transitive)
- Removeduuid@2.0.3(transitive)
- Removedvinyl@1.2.0(transitive)
- Removedvinyl-assign@1.2.1(transitive)
- Removedvinyl-fs@1.0.0(transitive)