Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nodejs-file-downloader

Package Overview
Dependencies
Maintainers
1
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nodejs-file-downloader - npm Package Compare versions

Comparing version 4.2.0 to 4.3.0

47

Downloader.js

@@ -79,2 +79,3 @@ const fs = require('fs');

* @param {function} [config.onProgress = undefined]
* @param {function} [config.shouldStop = undefined]
* @param {boolean} [config.shouldBufferResponse = false]

@@ -98,3 +99,3 @@ * @param {boolean} [config.useSynchronousMode = false]

httpsAgent: undefined,
proxy:undefined,
proxy: undefined,
headers: undefined,

@@ -113,4 +114,4 @@ cloneFiles: true,

if (this.config.filename) {

@@ -124,3 +125,3 @@ this.config.fileName = this.config.filename

// this.response = null;
this.percentage = 0;
this.fileSize = null;

@@ -144,2 +145,3 @@ this.currentDataSize = 0;

await this._makeUntilSuccessful(async () => {
this._resetData()
const response = await this._request();

@@ -167,3 +169,9 @@ // const readStream = response.readStream

_resetData() {
this.percentage = 0;
this.fileSize = null;
this.currentDataSize = 0;
}
/**

@@ -173,2 +181,3 @@ * @return {Promise<IncomingMessage} response

async _request() {
// this.resetData()
const response = await this._makeRequest();

@@ -239,2 +248,11 @@ // debugger;

},
shouldStop: async (e) => {
// debugger
if (this.config.shouldStop) {
if (await this.config.shouldStop(e) === true) {
return true;
}
}
},
maxAttempts: this.config.maxAttempts

@@ -251,3 +269,3 @@ })

async _makeRequest() {
const {timeout,headers,proxy,url,httpsAgent} = this.config;
const { timeout, headers, proxy, url, httpsAgent } = this.config;
const options = {

@@ -257,16 +275,12 @@ timeout,

}
if(httpsAgent){
if (httpsAgent) {
options.httpsAgent = httpsAgent;
}
else if(proxy){
else if (proxy) {
// debugger
options.httpsAgent = new HttpsProxyAgent(proxy)
}
// debugger
// console.log(options)
const response = await request(url, options);
// debugger;
var response = await request(url, options);
return response;

@@ -305,7 +319,14 @@ }

that.currentDataSize += chunk.byteLength;
if (that.fileSize) {
that.percentage = ((that.currentDataSize / that.fileSize) * 100).toFixed(2)
} else {
that.percentage = NaN
}
that.percentage = ((that.currentDataSize / that.fileSize) * 100).toFixed(2)
const remainingFracture = (100 - that.percentage) / 100;
const remainingSize = Math.round(remainingFracture * that.fileSize);
if (that.config.onProgress) {
that.config.onProgress(that.percentage, chunk);
that.config.onProgress(that.percentage, chunk, remainingSize);
}

@@ -312,0 +333,0 @@

@@ -74,3 +74,4 @@

// debugger;
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/contentType')

@@ -86,3 +87,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/contentType',
url: `http://www.${host}.com/contentType`,
directory: "./downloads",

@@ -111,2 +112,36 @@ cloneFiles: false,

it('Should get NaN in onProgress', async () => {
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/contentType')
.reply(200, (uri, requestBody) => {
return fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg'))
// fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback
}, {
'Content-Type': 'image/jpeg',
})
const downloader = new Downloader({
url: `http://www.${host}.com/contentType`,
directory: "./downloads",
cloneFiles: false,
onProgress: (p, chunk,remaining) => {
// debugger;
expect(isNaN(p)).toBe(true)
expect(isNaN(remaining)).toBe(true)
expect(Object.getPrototypeOf(chunk).constructor.name).toBe('Buffer')
}
})
// debugger;
await downloader.download();
// debugger
await verifyFile('./downloads/contentType.jpeg', 23642);
// console.log(verify)
})
it('Should download a picture and overwrite the name', async () => {

@@ -122,4 +157,4 @@ // mock.onGet("/Desert.jpg").reply(

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Desert.jpg')

@@ -135,3 +170,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Desert.jpg',
url: `http://www.${host}.com/Desert.jpg`,
directory: "./downloads",

@@ -161,4 +196,4 @@ cloneFiles: false,

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Desert.jpg')

@@ -174,3 +209,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Desert.jpg',
url: `http://www.${host}.com/Desert.jpg`,
directory: "./downloads/May/2020",

@@ -200,3 +235,4 @@ cloneFiles: false

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Desert.jpg')

@@ -212,3 +248,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Desert.jpg',
url: `http://www.${host}.com/Desert.jpg`,
directory: "./downloads/May/2020",

@@ -238,3 +274,4 @@ // cloneFiles: true

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Koala.jpg')

@@ -250,3 +287,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Koala.jpg',
url: `http://www.${host}.com/Koala.jpg`,
directory: "./downloads",

@@ -277,3 +314,4 @@ // onProgress: (p) => { }

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Lighthouse.jpg')

@@ -289,3 +327,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Lighthouse.jpg',
url: `http://www.${host}.com/Lighthouse.jpg`,
directory: "./downloads",

@@ -316,3 +354,4 @@ })

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/contentDisposition')

@@ -329,3 +368,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/contentDisposition',
url: `http://www.${host}.com/contentDisposition`,
directory: "./downloads"

@@ -357,3 +396,4 @@ })

nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Hydrangeas.jpg?width=400&height=300')

@@ -370,3 +410,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Hydrangeas.jpg?width=400&height=300',
url: `http://www.${host}.com/Hydrangeas.jpg?width=400&height=300`,
directory: "./downloads"

@@ -398,3 +438,4 @@ })

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Koala.jpg')

@@ -410,3 +451,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Koala.jpg',
url: `http://www.${host}.com/Koala.jpg`,
directory: "./downloads",

@@ -422,3 +463,3 @@ cloneFiles: false

const downloader2 = new Downloader({
url: 'http://www.dummyurl.com/Koala.jpg',
url: `http://www.${host}.com/Koala.jpg`,
directory: "./downloads",

@@ -462,3 +503,4 @@ })

// )
nock('http://www.dummyurl.com')
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Koala.jpg')

@@ -476,3 +518,3 @@ .reply(200, (uri, requestBody) => {

const downloader = new Downloader({
url: 'http://www.dummyurl.com/Koala.jpg',
url: `http://www.${host}.com/Koala.jpg`,
directory: "./downloads",

@@ -490,6 +532,6 @@ cloneFiles: false,

throw error;
debugger;
// debugger;
} finally {
debugger
// debugger
await verifyFile('./downloads/buffer.jpeg', 29051);

@@ -507,4 +549,5 @@ }

const host = randomHost()
// mock.onGet("/400").reply(400)
nock('http://www.dummyurl.com')
nock(`http://www.${host}.com`)
.get('/400')

@@ -516,8 +559,9 @@ .reply(400).persist()

const downloader = new Downloader({
url: 'http://www.dummyurl.com/400',
url: `http://www.${host}.com/400`,
directory: "./downloads",
maxAttempts: 3,
onError:function(){
onError: function () {
counter++;
}
},
})

@@ -528,3 +572,3 @@ // console.log(downloader)

// await downloader.request();
debugger;
// debugger;
// await downloader.save();

@@ -534,2 +578,3 @@

} catch (error) {
// expect(counter).toBe(3)
expect(counter).toBe(3)

@@ -546,10 +591,58 @@ expect(error.message).toBe('Request failed with status code 400')

it('Should repeat fail after first attempt, because of shouldStop hook', async () => {
const host = randomHost()
// mock.onGet("/400").reply(400)
nock(`http://www.${host}.com`)
.get('/404')
.reply(404).persist()
try {
var counter = 0;
const downloader = new Downloader({
url: `http://www.${host}.com/404`,
directory: "./downloads",
maxAttempts: 3,
onError: function () {
counter++;
},
shouldStop:function(e){
debugger
if(e.statusCode && e.statusCode === 404){
return true;
}
}
})
// console.log(downloader)
// debugger;
await downloader.download();
// await downloader.request();
// debugger;
// await downloader.save();
// await verifyFile('./downloads/Koala.jpg', 29051);
} catch (error) {
// expect(counter).toBe(3)
expect(counter).toBe(1)
expect(error.message).toBe('Request failed with status code 404')
expect(error.statusCode).toBe(404)
// debugger;
}
})
it('Should fail once and finally fail', async () => {
const host = randomHost()
// mock.onGet("/500").reply(500);
nock('http://www.dummyurl.com')
nock(`http://www.${host}.com`)
.get('/500')

@@ -561,3 +654,3 @@ .reply(500).persist()

timeout: 1000,
url: 'http://www.dummyurl.com/500',
url: `http://www.${host}.com/500`,
directory: "./downloads",

@@ -598,12 +691,6 @@ maxAttempts: 1,

// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// mock.onGet("/koala.jpg").reply(function (config) {
// return [
// 200,
// stream,
// {'message':'terminate'}
// ];
// });
nock('http://www.dummyurl.com')
const host = randomHost()
fs.unlinkSync('./downloads/Koala.jpg')
nock(`http://www.${host}.com`)
.get('/Koala.jpg')

@@ -613,3 +700,2 @@ .reply(200, (uri, requestBody) => {

return fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'))
// fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback
}, {

@@ -624,11 +710,11 @@ 'message': 'terminate'

maxAttempts: 4,
fileName: 'yoyo',
// fileName: 'yoyo',
onResponse: function (response) {
// debugger;
if (response.headers['message'] !== 'terminate') {
// return true
if (response.headers['message'] === 'terminate') {
return false;//Stop the download
}
return false;
// return true;
},
url: 'http://www.dummyurl.com/Koala.jpg',
url: `http://www.${host}.com/Koala.jpg`,
directory: "./downloads",

@@ -638,18 +724,19 @@

let fileExists= false
await downloader.download();
try {
await downloader.download();
// debugger;
await verifyFile('./downloads/Koala.jpg', 29051);
fileExists = true//Aint supposed to reach this, verifyFile should throw an error.
} catch (error) {
// debugger;
throw error
}
debugger
//The "error" should be caught here, and the test should pass
debugger
try {
await verifyFile('./downloads/yoyo', 29051);
} catch (error) {
// expect(true).toBe(true)
// debugger
// return;
}
debugger
if(fileExists)throw new Error("Download hasn't stopped")
// throw new Error();

@@ -674,7 +761,11 @@

// });
nock('http://www.dummyurl.com')
// debugger
// fs.unlinkSync('./downloads/Koala.jpg')
// debugger
const host = randomHost()
nock(`http://www.${host}.com`)
.get('/Koala.jpg')
.reply(200, (uri, requestBody) => {
// debugger
// console.log('YOYO')
return fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'))

@@ -692,10 +783,11 @@ // fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback

// return true
debugger;
// debugger;
return;
}
debugger
// debugger
return false;
},
url: 'http://www.dummyurl.com/Koala.jpg',
fileName:'yoyo.jpg',
url: `http://www.${host}.com/Koala.jpg`,
directory: "./downloads",

@@ -706,6 +798,14 @@

const prom = await downloader.download();
debugger;
// debugger;
// try {
await verifyFile('./downloads/koala.jpg', 29051);
try {
const prom = await downloader.download();
} catch (error) {
debugger
} finally {
// debugger
await verifyFile('./downloads/yoyo.jpg', 29051);
}
// } catch (error) {

@@ -724,2 +824,55 @@ // debugger

// it('Should fail three times, then succeed', async function () {
// try {
// let counter = 0
// var onErrorCount = 0
// const host = randomHost()
// nock(`http://www.${host}.com`)
// .get('/Koala.jpg')
// .reply(function (uri, requestBody) {
// debugger
// counter++
// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// const code = counter <= 3 ? 500 : 200;
// return [
// code,
// stream,
// {}
// ];
// })
// .persist()
// // .reply(500)
// const downloader = new Downloader({
// // timeout: 1000,
// maxAttempts: 4,
// url: `http://www.${host}.com/Koala.jpg`,
// directory: "./downloads",
// onError: function (e) {
// debugger;
// onErrorCount++;
// },
// onProgress:(p)=>{
// debugger
// console.log(p)
// }
// })
// await downloader.download();
// } catch (error) {
// debugger;
// } finally {
// debugger;
// expect(onErrorCount).toBe(4)
// }
// })
// it('Should fail three times during stream, and then succeed', async function () {

@@ -760,18 +913,23 @@ // // this.timeout(10000)

// var onErrorCount = 0
// nock('http://www.dummyurl.com')
// const host = randomHost()
// nock(`http://www.${host}.com`)
// .get('/Koala.jpg')
// .reply(function(uri, requestBody) {
// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// // stream.emit('error')
// // stream.emit('close')
// const modifiedStream = Readable.from((async function* () {
// counter++
// debugger;
// // await timeout(1000);
// debugger
// // if (counter === 4) {
// // for await (const chunk of stream) {
// // yield chunk;
// for await (const chunk of stream) {
// await timeout(1000);
// yield chunk;
// // }
// }
// // } else {
// debugger;
// throw new Error('LOL');
// // debugger;
// // throw new Error('LOL');
// // modifiedStream.emit('error','yoyo')

@@ -786,2 +944,3 @@ // // }

// modifiedStream,
// // stream,
// {}

@@ -793,3 +952,3 @@ // ];

// const downloader = new Downloader({
// timeout: 1000,
// timeout: 500,
// // debugMode:true,

@@ -803,3 +962,3 @@ // maxAttempts: 1,

// // },
// url: 'http://www.dummyurl.com/Koala.jpg',
// url: `http://www.${host}.com/Koala.jpg`,
// directory: "./downloads",

@@ -845,71 +1004,71 @@ // onError: function (e) {

// it('Should fail twice and finally succeed', async () => {
// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// it('Should fail twice and finally succeed', async () => {
// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// let counter = 0;
// // mock.onGet("http://www.dummyurl.com/400").reply(function (config) {
// // // debugger;
// // let status;
// // counter++
// // if (counter < 3) {
// // status = 400
// // } else {
// // status = 200
// // }
// // return [
// // status,
// // stream,
// // { 'Content-Type': 'image/jpeg' }
// // ];
// // });
// nock('http://www.dummyurl.com')
// .get('/400')
// .reply(200, (uri, requestBody) => {
// let counter = 0;
// // mock.onGet("http://www.${host}.com/400").reply(function (config) {
// // // debugger;
// // let status;
// // counter++
// // if (counter < 3) {
// // status = 400
// // } else {
// // status = 200
// // }
// // return [
// // status,
// // stream,
// // { 'Content-Type': 'image/jpeg' }
// // ];
// // });
// nock(`http://www.${host}.com`)
// .get('/400')
// .reply(200, (uri, requestBody) => {
// }, {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '29051'
// })
// }, {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '29051'
// })
// try {
// var onErrorCount = 0
// try {
// var onErrorCount = 0
// const downloader = new Downloader({
// timeout: 1000,
// url: 'http://www.dummyurl.com/400',
// directory: "./downloads",
// maxAttempts: 3,
// onError: (e) => {
// // debugger;
// onErrorCount++;
// // console.log(e.message)
// }
// const downloader = new Downloader({
// timeout: 1000,
// url: 'http://www.${host}.com/400',
// directory: "./downloads",
// maxAttempts: 3,
// onError: (e) => {
// // debugger;
// onErrorCount++;
// // console.log(e.message)
// }
// })
// // console.log(downloader)
// // debugger;
// // var onErrorCount = 0
// // downloader.on('error', (e) => {
// // debugger;
// // onErrorCount++;
// // // console.log(e.message)
// // })
// await downloader.download();
// // const request = await downloader.request()
// // debugger;
// // await downloader.save()
// // debugger;
// // var s = request.data;
// // debugger;
// })
// // console.log(downloader)
// // debugger;
// // var onErrorCount = 0
// // downloader.on('error', (e) => {
// // debugger;
// // onErrorCount++;
// // // console.log(e.message)
// // })
// await downloader.download();
// // const request = await downloader.request()
// // debugger;
// // await downloader.save()
// // debugger;
// // var s = request.data;
// // debugger;
// } catch (error) {
// debugger;
// } finally {
// debugger;
// // expect(s.constructor.name).toBe('ReadStream')
// expect(onErrorCount).toBe(2)
// await verifyFile('./downloads/400.jpeg', 29051);
// }
// } catch (error) {
// debugger;
// } finally {
// debugger;
// // expect(s.constructor.name).toBe('ReadStream')
// expect(onErrorCount).toBe(2)
// await verifyFile('./downloads/400.jpeg', 29051);
// }

@@ -919,3 +1078,22 @@

// })
// })
function randomHost(length = 5) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function timeout(mil) {
return new Promise((res) => {
setTimeout(() => {
res();
}, mil)
})
}
{
"name": "nodejs-file-downloader",
"version": "4.2.0",
"version": "4.3.0",
"description": "A file downloader for NodeJs",

@@ -5,0 +5,0 @@ "main": "Downloader.js",

@@ -18,2 +18,3 @@ nodejs-file-downloader is a simple utility for downloading files. It hides the complexity of dealing with streams, redirects, paths and duplicate file names. Can automatically repeat failed downloads.

* [Repeat failed downloads automatically](#repeat-failed-downloads-automatically)
* [Prevent unnecessary repetition](#prevent-unnecessary-repetition)
* [Use a Proxy](#use-a-proxy)

@@ -54,2 +55,4 @@ - [Error handling](#error-handling)

If the response headers contain information about the file size, onProgress hook can be used. If the file size cannot be determined, "percentage" and "remainingSize" arguments will be called with NaN.
```javascript

@@ -63,4 +66,6 @@ const Downloader = require('nodejs-file-downloader');

directory: "./downloads/2020/May",//Sub directories will also be automatically created if they do not exist.
onProgress:function(percentage){//Gets called with each chunk.
onProgress:function(percentage,chunk,remainingSize){//Gets called with each chunk.
console.log('% ',percentage)
console.log('Current chunk of data: ',chunk)
console.log('Remaining bytes: ',remainingSize)
}

@@ -176,2 +181,37 @@ })

#### Prevent unnecessary repetition
If you use the auto-repeat option, by setting the maxAttempts to greater than 1, "shouldStop" hook can be used, To decide
whether the repetition should continue. This is useful in cases where you're generating many dynamic url's, some of which can result in a 404 http status code(for example), and there is no point in repeating that request.
```javascript
const downloader = new Downloader({
url: 'http://212.183.159.230/200MB.zip',
directory: "./",
maxAttempts:3,//We set it to 3, but in the case of status code 404, it will run only once.
shouldStop:function(error){
//A request that results in a status code of 400 and above, will throw an Error, that contains a custom property
//"statusCode".
//Note that an error that is thrown during the stream itself(after a valid http response was already received. It's quite rare, but happens), will not have a "statusCode" property.
if(e.statusCode && e.statusCode === 404){
return true;//If you return true, the repetition will not happen. Returning anything else, including undefined, will let the downloader know that you want to continue repeating.
}
}
})
try {
await downloader.download();
} catch (error) {//If all attempts fail, the last error is thrown.
console.log('Final fail',error)
}
```
&nbsp;
#### Use a proxy

@@ -197,5 +237,5 @@

downloader.download() should be put within a try-catch block. The program will throw an error, just like Axios, in case of network problems
downloader.download() will throw an error, just like Axios, in case of network problems
or an http status code of 400 or higher.
If the auto-repeat feature is enabled(by setting the maxAttempts to higher than 1), then only a failure of the final attempt will throw an error.

@@ -46,3 +46,5 @@ // const { read } = require('fs');

res.resume();
return reject(new Error(`Request failed with status code ${res.statusCode}`))
const error = new Error(`Request failed with status code ${res.statusCode}`)
error.statusCode = res.statusCode
return reject(error)
}

@@ -49,0 +51,0 @@ resolve(readStream)

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc