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 2.1.1 to 3.0.0

73

Downloader.js

@@ -81,11 +81,11 @@ const fs = require('fs');

timeout: 6000,
maxAttempts:1,
maxAttempts: 1,
useSynchronousMode: false,
httpsAgent:undefined,
headers:undefined,
cloneFiles: true,
httpsAgent: undefined,
headers: undefined,
cloneFiles: true,
shouldBufferResponse: false,
onResponse:undefined,
onError:undefined,
onProgress:undefined
onResponse: undefined,
onError: undefined,
onProgress: undefined
}

@@ -98,4 +98,4 @@

if(this.config.filename){
this.config.fileName = this.config.filename
if (this.config.filename) {
this.config.fileName = this.config.filename
}

@@ -113,17 +113,36 @@

//For EventEmitter backwards compatibility
on(event,callback){
on(event, callback) {
this.config[`on${capitalize(event)}`] = callback
}
/**
* @return {Promise<void>}
*/
async download() {
await this._makeUntilSuccessful(async () => {
const response = await this._request();
// debugger;
if (this.config.onResponse) {
const shouldContinue = await this.config.onResponse(response);
if(shouldContinue === false){
return;
}
}
await this._save()
})
}
/**
* @return {Promise<axios.AxiosResponse>}
*/
async request() {
// const response = await this._makeRequest();
async _request() {
const response = await this._makeRequest();
// const response = await this._makeRequestUntilSuccessful();
const response = await this._makeUntilSuccessful(this._makeRequest);
// const response = await this._makeUntilSuccessful(this._makeRequest);
this.response = response;
if (this.config.onResponse) {
await this.config.onResponse(response);
}
const contentLength = response.headers['content-length'] || response.headers['Content-Length'];

@@ -138,3 +157,3 @@ this.fileSize = parseInt(contentLength);

*/
async save() {
async _save() {
if (this.config.shouldBufferResponse) {

@@ -151,14 +170,4 @@ // debugger;

/**
* @return {Promise<void>}
*/
async download() {
await this.request();
// debugger;
await this.save()
}
/**

@@ -179,3 +188,3 @@ * @param {Function} asyncFunc

}, {
onError: async(e) => {
onError: async (e) => {
// debugger;

@@ -186,3 +195,3 @@ if (this.config.onError) {

},
maxAttempts:this.config.maxAttempts
maxAttempts: this.config.maxAttempts
// maxAttempts:1

@@ -251,2 +260,3 @@ })

// yoyo
// debugger;
const fileName = await this._getFinalFileName();

@@ -256,4 +266,5 @@

const write = this._createWriteStream(`${this.config.directory}/${fileName}`)
// debugger
await pipeline(read, progress, write)
// debugger;

@@ -260,0 +271,0 @@ }

@@ -10,5 +10,7 @@

const Downloader = require('./Downloader');
const { Readable } = require('stream');
describe('Downloader tests', () => {

@@ -71,3 +73,3 @@

cloneFiles: false,
onProgress:(p, chunk) => {
onProgress: (p, chunk) => {
// console.log(p, chunk)

@@ -78,3 +80,3 @@ expect(!isNaN(parseFloat(p)) && isFinite(p)).toBe(true)

},
onResponse:(r) => {
onResponse: (r) => {
// console.log(Object.getPrototypeOf(r).constructor.name)

@@ -86,13 +88,13 @@ expect(r).toHaveProperty('data');

})
// .on('progress', (p, chunk) => {
// // console.log(p, chunk)
// expect(!isNaN(parseFloat(p)) && isFinite(p)).toBe(true)
// expect(Object.getPrototypeOf(chunk).constructor.name).toBe('Buffer')
// .on('progress', (p, chunk) => {
// // console.log(p, chunk)
// expect(!isNaN(parseFloat(p)) && isFinite(p)).toBe(true)
// expect(Object.getPrototypeOf(chunk).constructor.name).toBe('Buffer')
// })
// .on('response', (r) => {
// // console.log(Object.getPrototypeOf(r).constructor.name)
// expect(r).toHaveProperty('data');
// expect(r).toHaveProperty('headers');
// })
// })
// .on('response', (r) => {
// // console.log(Object.getPrototypeOf(r).constructor.name)
// expect(r).toHaveProperty('data');
// expect(r).toHaveProperty('headers');
// })
// console.log(downloader)

@@ -105,3 +107,3 @@ // debugger;

})

@@ -132,3 +134,3 @@

})

@@ -158,3 +160,3 @@

})

@@ -185,3 +187,3 @@

})

@@ -213,3 +215,3 @@

})

@@ -240,3 +242,3 @@

})

@@ -268,3 +270,3 @@

})

@@ -296,3 +298,3 @@

})

@@ -336,3 +338,3 @@

} catch (error) {

@@ -376,8 +378,8 @@ console.log(error)

} catch (error) {
// debugger;
}finally{
await verifyFile('./downloads/Koala.jpg', 29051);
} finally {
await verifyFile('./downloads/Koala.jpg', 29051);
}

@@ -400,3 +402,3 @@

directory: "./downloads",
maxAttempts:3
maxAttempts: 3
})

@@ -439,3 +441,3 @@ // console.log(downloader)

stream,
{'Content-Type': 'image/jpeg'}
{ 'Content-Type': 'image/jpeg' }
];

@@ -451,5 +453,5 @@ });

directory: "./downloads",
maxAttempts:3,
onError:(e) => {
debugger;
maxAttempts: 3,
onError: (e) => {
// debugger;
onErrorCount++;

@@ -468,16 +470,17 @@ // console.log(e.message)

// })
// await downloader.download();
const request = await downloader.request()
await downloader.save()
await downloader.download();
// const request = await downloader.request()
// debugger;
var s = request.data;
// await downloader.save()
// debugger;
// var s = request.data;
// debugger;
} catch (error) {
// debugger;
}finally{
// debugger;
expect(s.constructor.name).toBe('ReadStream')
debugger;
} finally {
debugger;
// expect(s.constructor.name).toBe('ReadStream')
expect(onErrorCount).toBe(2)

@@ -493,5 +496,5 @@ await verifyFile('./downloads/400.jpeg', 29051);

it('Should fail once and finally fail', async () => {
mock.onGet("/500").reply(500);

@@ -504,3 +507,3 @@ var onErrorCount = 0;

directory: "./downloads",
maxAttempts:1,
maxAttempts: 1,
onError: (e) => {

@@ -524,3 +527,3 @@ // debugger;

// debugger;
}finally{
} finally {
// debugger;

@@ -536,52 +539,175 @@ // expect(s.constructor.name).toBe('ReadStream')

// it('Should fail three times during stream', async function() {
// // this.timeout(10000)
it('Should fail three times during stream, and then succeed', async function () {
// this.timeout(10000)
let counter = 0
const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
mock.onGet("/koala.jpg").reply(function (config) {
// const { Readable } = require('stream');
const modifiedStream = Readable.from((async function* () {
counter++
if (counter === 4) {
for await (const chunk of stream) {
yield chunk;
}
} else {
throw new Error('LOL');
}
})());
return [
200,
modifiedStream,
{}
];
});
try {
let error;
const downloader = new Downloader({
timeout: 1000,
// debugMode:true,
maxAttempts: 4,
// onResponse:function(r){
// if(r.headers=== 'yoyo'){
// error='yoyo'
// return false
// }
// },
url: '/koala.jpg',
directory: "./downloads",
})
var onErrorCount = 0
downloader.on('error', (e) => {
// debugger;
onErrorCount++;
})
// const response = await downloader.request()
// debugger;
// await downloader.save()
// debugger;
await downloader.download();
} catch (error) {
debugger;
// console.log(error)
} finally {
debugger;
expect(onErrorCount).toBe(3)
// await verifyFile('./downloads/koala.jpg', 29051);
}
})
it('Should use onResponse to stop download', async function () {
// mock.onGet("/fileThatDoesntExist").reply(function (config) {
// // debugger;
// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg'));
// stream.destroy();
// return [
// 200,
// stream,
// {}
// ];
// });
const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
mock.onGet("/koala.jpg").reply(function (config) {
return [
200,
stream,
{'message':'terminate'}
];
});
// try {
// const downloader = new Downloader({
// timeout: 1000,
// url: '/fileThatDoesntExist',
// directory: "./downloads",
// })
const downloader = new Downloader({
timeout: 1000,
// debugMode:true,
maxAttempts: 4,
fileName:'yoyo',
onResponse: function (response) {
if (response.headers['message'] !== 'terminate') {
// return true
}
return false;
},
url: '/koala.jpg',
directory: "./downloads",
// var onErrorCount = 0
// downloader.on('error', (e) => {
// onErrorCount++;
// })
// const request = await downloader.request()
// debugger;
// await downloader.save()
// debugger;
// // await downloader.download();
// } catch (error) {
// debugger;
// // console.log(error)
// }finally{
// debugger;
// expect(onErrorCount).toBe(3)
// }
})
try {
await downloader.download();
debugger;
} catch (error) {
debugger;
throw error
}
try {
await verifyFile('./downloads/yoyo', 29051);
} catch (error) {
debugger
return;
}
throw new Error();
// })
})
it('Should use onResponse to continue download', async function () {
const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
mock.onGet("/koala.jpg").reply(function (config) {
return [
200,
stream,
{'message':'do not terminate'}
];
});
const downloader = new Downloader({
timeout: 1000,
// debugMode:true,
maxAttempts: 4,
onResponse: function (response) {
if (response.headers['message'] !== 'terminate') {
// return true
return;
}
return false;
},
url: '/koala.jpg',
directory: "./downloads",
})
const prom = await downloader.download();
debugger;
// try {
await verifyFile('./downloads/koala.jpg', 29051);
// } catch (error) {
// debugger
// return;
// }
// throw new Error();
})
})
{
"name": "nodejs-file-downloader",
"version": "2.1.1",
"version": "3.0.0",
"description": "A file downloader for NodeJs",

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

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

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

@@ -16,4 +16,4 @@ If you encounter any bugs or have a question, please don't hesitate to open an issue.

* [Overwrite existing files](#overwrite-existing-files)
* [Get response and then download](#get-response-and-then-download)
* [Repeat failed requests automatically](#repeat-failed-requests-automatically)
* [Hook into response](#hook-into-response)
* [Repeat failed downloads automatically](#repeat-failed-downloads-automatically)

@@ -100,25 +100,27 @@ ## Examples

#### Get response and then download
#### Hook into response
There is an alternative way to using Downloader.download():
If you need to get the underlying response, in order to decide whether the download should continue, or perform any other operations, use the onReponse hook.
```javascript
//The response object is an Axios response object. Refer to their docs for more details.
function onResponse(response){
//Now you can do something with the response, like check the headers
if(response.headers['content-length'] > 1000000){
console.log('File is too big!')
return false;//If you return false, the download process is stopped, and downloader.download() is resolved.
}
//Returning any other value, including undefined, will tell the downloader to proceed as usual.
}
const downloader = new Downloader({
url: 'http://212.183.159.230/200MB.zip',
directory: "./",
directory: "./",
onResponse
})
const response = await downloader.request()//This function just performs the request. The file isn't actually being downloaded yet. It returns an Axios response object. You can refer to their docs for more details.
const response = await downloader.download()
//Now you can do something with the response, like check the headers
if(response.headers['content-length'] < 1000000){
await downloader.save()
}else{
console.log('File is too big!')
}
//Note that Downloader.download() simply combines these two function calls.
```

@@ -130,7 +132,6 @@

#### Repeat failed requests automatically
#### Repeat failed downloads automatically
The program can repeat any failed http request automatically. Only if the provided config.maxAttempts number is exceeded, an Error is thrown.
The program can repeat any failed downloads automatically. Only if the provided config.maxAttempts number is exceeded, an Error is thrown.
Note that currently only the http requests will be repeated in case of an error, BUT NOT THE STREAM ITSELF. If a stream fails on its first attempt, an error is thrown as usual. I will change this behavior in the future.

@@ -143,3 +144,3 @@ ```javascript

maxAttempts:3,//Default is 1.
onError:function(error){//You can also hook into each failed http request attempt.
onError:function(error){//You can also hook into each failed attempt.
console.log('Error from attempt ',error)

@@ -146,0 +147,0 @@ }

@@ -9,2 +9,3 @@ const sanitize = require('sanitize-filename');

/**

@@ -11,0 +12,0 @@ *

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