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 3.0.1 to 4.0.0

request.js

212

Downloader.js
const fs = require('fs');
const axios = require('axios');
// const axios = require('axios');
const { request } = require('./request');
const stream = require('stream');
// const {WritableStream}= fs;
const { Transform } = require('stream')
const util = require('util');
const FileProcessor = require('./utils/FileProcessor');
const pipeline = util.promisify(stream.pipeline);
const pipelinePromisified = util.promisify(stream.pipeline);
const mkdir = util.promisify(fs.mkdir);

@@ -12,5 +14,8 @@ const writeFile = util.promisify(fs.writeFile);

const rpur = require('./utils/rpur');
// const { resolve } = require('path');
// const {IncomingMessage} = require('http')
const unlink = util.promisify(fs.unlink)
const rename = util.promisify(fs.rename)
const configTypes = {

@@ -102,8 +107,10 @@ url: {

this.response = null;
this.readStream = null;
// this.readStream = null;
// this.buffer = null;
// this.responseHeaders = null;
// this.response = null;
this.fileSize = null;
this.currentDataSize = 0;
// this.config.httpsAgent = new HttpsProxyAgent(this.config.proxy)

@@ -118,31 +125,38 @@ }

/**
* @return {Promise<void>}
*/
/**
* @return {Promise<void>}
*/
async download() {
await this._verifyDirectoryExists(this.config.directory)
await this._makeUntilSuccessful(async () => {
const response = await this._request();
// debugger;
// const readStream = response.readStream
if (this.config.onResponse) {
// debugger
const shouldContinue = await this.config.onResponse(response);
if(shouldContinue === false){
if (shouldContinue === false) {
return;
}
}
await this._save()
// const finalName = await this._getFinalFileName(response.headers);
// const finalPath = `${this.config.directory}/${finalName}`;
await this._save(response)
})
// debugger
}
async _verifyDirectoryExists(directory) {
await mkdir(directory, { recursive: true });
}
/**
* @return {Promise<axios.AxiosResponse>}
* @return {Promise<IncomingMessage} response
*/
async _request() {
const response = await this._makeRequest();
// const response = await this._makeRequestUntilSuccessful();
// const response = await this._makeUntilSuccessful(this._makeRequest);
this.response = response;
// debugger;
const contentLength = response.headers['content-length'] || response.headers['Content-Length'];

@@ -155,18 +169,38 @@ this.fileSize = parseInt(contentLength);

/**
* @param {IncomingMessage} response
* @return {Promise<void>}
*/
async _save() {
if (this.config.shouldBufferResponse) {
async _save(response) {
try {
// debugger
const finalName = await this._getFinalFileName(response.headers);
const finalPath = `${this.config.directory}/${finalName}`;
var tempPath = this._getTempFilePath(finalPath);
if (this.config.shouldBufferResponse) {
const buffer = await this._createBufferFromResponseStream(response);
await this._saveFromBuffer(buffer, tempPath);
// await this._saveFromBuffer(buffer, finalPath);
}else{
await this._saveFromReadableStream(response, tempPath);
// await this._saveFromReadableStream(response, finalPath);
}
// debugger;
return this._saveFromBuffer(this.response.data);
// return this._makeUntilSuccessful(async()=>{await this._saveFromBuffer(this.response.data)});
await this._renameTempFileToFinalName(tempPath,finalPath)
} catch (error) {
// debugger
await this._removeFailedFile(tempPath)
throw error;
}
// debugger;
await this._saveFromReadableStream(this.response.data);
// await this._makeUntilSuccessful(async()=>{await this._saveFromReadableStream(this.response.data)});
}
/**

@@ -182,6 +216,4 @@ * @param {Function} asyncFunc

await rpur(async () => {
// debugger;
data = await func();
// debugger;
}, {

@@ -195,5 +227,3 @@ onError: async (e) => {

maxAttempts: this.config.maxAttempts
// maxAttempts:1
})
// debugger;
return data;

@@ -205,19 +235,17 @@

*
* @return {Promise<axios.AxiosResponse>}
* @return {Promise<IncomingMessage>}
*/
async _makeRequest() {
// debugger;
const shouldBuffer = this.config.shouldBufferResponse
const httpsAgent = this.config.httpsAgent;
const response = await axios({
method: 'get',
url: this.config.url,
// debugger
const response = await request(this.config.url, {
timeout: this.config.timeout,
headers: this.config.headers,
httpsAgent,
responseType: shouldBuffer ? 'arraybuffer' : 'stream'
})
// debugger;
// this.response = response;
});
return response;

@@ -228,12 +256,26 @@ }

/**
*
* @param {string} fullPath
* @return {Promie<WritableStream>}
*/
_createWriteStream(fullPath) {
// console.log(fullPath)
// debugger
return fs.createWriteStream(fullPath)
}
async _createBufferFromResponseStream(stream) {
const chunks = []
for await (let chunk of stream) {
chunks.push(chunk)
}
const buffer = Buffer.concat(chunks)
return buffer;
}
_getProgressStream() {
const that = this;
const progress = new Transform({
// writableObjectMode: true,

@@ -259,24 +301,59 @@ transform(chunk, encoding, callback) {

async _saveFromReadableStream(read) {
// yoyo
async _pipeStreams(arrayOfStreams) {
// try {
await pipelinePromisified(...arrayOfStreams);
// } catch (error) {
// debugger;
const fileName = await this._getFinalFileName();
// }
const progress = this._getProgressStream();
const write = this._createWriteStream(`${this.config.directory}/${fileName}`)
// debugger
await pipeline(read, progress, write)
}
async _saveFromReadableStream(read, path) {
// debugger;
const streams = [read];
const write = this._createWriteStream(path)
if (this.config.onProgress) {
const progressStream = this._getProgressStream()
streams.push(progressStream);
}
streams.push(write)
await this._pipeStreams(streams)
}
async _saveFromBuffer(buffer) {
async _saveFromBuffer(buffer, path) {
// debugger;
// const response = await this._makeRequest(true);
// this.response = response;
const fileName = await this._getFinalFileName();
// const tempPath = this._getTempFilePath(path);
await writeFile(path, buffer)
}
async _removeFailedFile(path) {
await unlink(path);
}
async _renameTempFileToFinalName(temp, final) {
// debugger;
// const write = this.createWriteStream(`${this.config.directory}/${fileName}`)
await writeFile(`${this.config.directory}/${fileName}`, buffer)
await rename(temp, final)
}
/**
*
* @param {string} finalpath
*/
_getTempFilePath(finalpath) {
return `${finalpath}.download`;
}

@@ -286,4 +363,6 @@

async _getFinalFileName() {
// debugger;
/**
* @param {object} responseHeaders
*/
async _getFinalFileName(responseHeaders) {
let fileName;

@@ -293,23 +372,10 @@ if (this.config.fileName) {

} else {
fileName = deduceFileName(this.config.url, this.response.headers)
fileName = deduceFileName(this.config.url, responseHeaders)
}
// debugger;
var fileProcessor = new FileProcessor({ useSynchronousMode: this.config.useSynchronousMode, fileName, path: this.config.directory })
// debugger;
// if (! await fileProcessor.pathExists(this.config.directory)) {
if (!await fileProcessor.pathExists(this.config.directory)) {
// debugger;
try {
await mkdir(this.config.directory, { recursive: true });
} catch (error) {
// debugger;
}
}
if (this.config.cloneFiles) {
var fileProcessor = new FileProcessor({ useSynchronousMode: this.config.useSynchronousMode, fileName, path: this.config.directory })
// debugger;
fileName = await fileProcessor.getAvailableFileName()
// fileName = fileProcessor.getAvailableFileName()
}

@@ -316,0 +382,0 @@

const axios = require('axios');
// const axios = require('axios');
const expect = require('expect')
var MockAdapter = require("axios-mock-adapter");
var mock = new MockAdapter(axios);
// var MockAdapter = require("axios-mock-adapter");
// var mock = new MockAdapter(axios);
const fs = require('fs');

@@ -11,2 +11,5 @@ const Path = require('path');

const { Readable } = require('stream');
// const http = require('http')
// const https = require('https')
const nock = require('nock')

@@ -16,2 +19,4 @@

describe('Downloader tests', () => {

@@ -61,17 +66,28 @@

it('Should download a picture and use content-type', async () => {
mock.onGet("/contentType").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
{
// mock.onGet("/contentType").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '23642'
// }
// )
// debugger;
nock('http://www.dummyurl.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',
'Content-Length': '23642'
}
)
})
const downloader = new Downloader({
url: '/contentType',
url: 'http://www.dummyurl.com/contentType',
directory: "./downloads",
cloneFiles: false,
onProgress: (p, chunk) => {
// console.log(p, chunk)
// debugger;
expect(!isNaN(parseFloat(p)) && isFinite(p)).toBe(true)

@@ -82,23 +98,10 @@ expect(Object.getPrototypeOf(chunk).constructor.name).toBe('Buffer')

onResponse: (r) => {
// console.log(Object.getPrototypeOf(r).constructor.name)
expect(r).toHaveProperty('data');
expect(r).toHaveProperty('headers');
expect(r.constructor.name).toBe('IncomingMessage');
}
// fileName:'yoyo2.jpg'
})
// .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');
// })
// console.log(downloader)
// debugger;
await downloader.download();
// debugger
await verifyFile('./downloads/contentType.jpeg', 23642);

@@ -111,13 +114,24 @@ // console.log(verify)

it('Should download a picture and overwrite the name', async () => {
mock.onGet("/Desert.jpg").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
{
// mock.onGet("/Desert.jpg").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '23642'
// }
// )
nock('http://www.dummyurl.com')
.get('/Desert.jpg')
.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',
'Content-Length': '23642'
}
)
})
const downloader = new Downloader({
url: '/Desert.jpg',
url: 'http://www.dummyurl.com/Desert.jpg',
directory: "./downloads",

@@ -138,13 +152,24 @@ cloneFiles: false,

it('Should download into a nested non-existing path', async () => {
mock.onGet("/Desert.jpg").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
{
// mock.onGet("/Desert.jpg").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '23642'
// }
// )
nock('http://www.dummyurl.com')
.get('/Desert.jpg')
.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',
'Content-Length': '23642'
}
)
})
const downloader = new Downloader({
url: '/Desert.jpg',
url: 'http://www.dummyurl.com/Desert.jpg',
directory: "./downloads/May/2020",

@@ -165,13 +190,23 @@ cloneFiles: false

it('Should create a number-appended file', async () => {
mock.onGet("/Desert.jpg").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
{
// mock.onGet("/Desert.jpg").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Desert.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '845941'
// }
// )
nock('http://www.dummyurl.com')
.get('/Desert.jpg')
.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',
'Content-Length': '845941'
}
)
'Content-Length': '23642'
})
const downloader = new Downloader({
url: '/Desert.jpg',
url: 'http://www.dummyurl.com/Desert.jpg',
directory: "./downloads/May/2020",

@@ -184,3 +219,3 @@ // cloneFiles: true

await verifyFile('./downloads/May/2020/Desert2.jpg', 23642);
await verifyFile('./downloads/May/2020/Desert_2.jpg', 23642);
// console.log(verify)

@@ -193,13 +228,23 @@

mock.onGet("/Koala.jpg").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg')),
{
// mock.onGet("/Koala.jpg").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// // 'Content-Length': '845941'
// }
// )
nock('http://www.dummyurl.com')
.get('/Koala.jpg')
.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
}, {
'Content-Type': 'image/jpeg',
// 'Content-Length': '845941'
}
)
'Content-Length': '845941'
})
const downloader = new Downloader({
url: '/Koala.jpg',
url: 'http://www.dummyurl.com/Koala.jpg',
directory: "./downloads",

@@ -221,13 +266,23 @@ // onProgress: (p) => { }

mock.onGet("/Lighthouse.jpg").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Lighthouse.jpg')),
{
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '845941'
}
// mock.onGet("/Lighthouse.jpg").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Lighthouse.jpg')),
// {
// // 'Content-Type': 'image/jpeg',
// // 'Content-Length': '845941'
// }
)
// )
nock('http://www.dummyurl.com')
.get('/Lighthouse.jpg')
.reply(200, (uri, requestBody) => {
return fs.createReadStream(Path.join(__dirname, 'fixtures/Lighthouse.jpg'))
// fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback
}, {
'Content-Type': 'image/jpeg',
'Content-Length': '845941'
})
const downloader = new Downloader({
url: '/Lighthouse.jpg',
url: 'http://www.dummyurl.com/Lighthouse.jpg',
directory: "./downloads",

@@ -248,14 +303,25 @@ })

// rimraf.sync('./')
mock.onGet("/contentDisposition").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Hydrangeas.jpg')),
{
'Content-Disposition': 'Content-Disposition: attachment; filename="contentDispositionFile.jpg"'
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '845941'
}
// mock.onGet("/contentDisposition").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Hydrangeas.jpg')),
// {
// 'Content-Disposition': 'Content-Disposition: attachment; filename="contentDispositionFile.jpg"'
// // 'Content-Type': 'image/jpeg',
// // 'Content-Length': '845941'
// }
)
// )
nock('http://www.dummyurl.com')
.get('/contentDisposition')
.reply(200, (uri, requestBody) => {
return fs.createReadStream(Path.join(__dirname, 'fixtures/Hydrangeas.jpg'))
// fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback
}, {
'Content-Type': 'image/jpeg',
'Content-Disposition': 'Content-Disposition: attachment; filename="contentDispositionFile.jpg"',
'Content-Length': '845941'
})
const downloader = new Downloader({
url: '/contentDisposition',
url: 'http://www.dummyurl.com/contentDisposition',
directory: "./downloads"

@@ -277,13 +343,25 @@ })

mock.onGet("/Hydrangeas.jpg?width=400&height=300").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Hydrangeas.jpg')),
{
// mock.onGet("/Hydrangeas.jpg?width=400&height=300").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Hydrangeas.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// // 'Content-Length': '845941'
// }
// )
nock('http://www.dummyurl.com')
.get('/Hydrangeas.jpg?width=400&height=300')
.reply(200, (uri, requestBody) => {
return fs.createReadStream(Path.join(__dirname, 'fixtures/Hydrangeas.jpg'))
// fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback
}, {
'Content-Type': 'image/jpeg',
// 'Content-Length': '845941'
}
'Content-Length': '845941'
})
)
const downloader = new Downloader({
url: '/Hydrangeas.jpg?width=400&height=300',
url: 'http://www.dummyurl.com/Hydrangeas.jpg?width=400&height=300',
directory: "./downloads"

@@ -306,13 +384,23 @@ })

try {
mock.onGet("/Koala.jpg").reply(
200,
fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg')),
{
// mock.onGet("/Koala.jpg").reply(
// 200,
// fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg')),
// {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '29051'
// }
// )
nock('http://www.dummyurl.com')
.get('/Koala.jpg')
.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
}, {
'Content-Type': 'image/jpeg',
'Content-Length': '29051'
}
)
}).persist()
const downloader = new Downloader({
url: '/Koala.jpg',
url: 'http://www.dummyurl.com/Koala.jpg',
directory: "./downloads",

@@ -328,3 +416,3 @@ cloneFiles: false

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

@@ -349,2 +437,3 @@ })

it('Should download an image, with shouldBufferResponse', async () => {
// rimraf.sync(Path.join(__dirname, 'fixtures/Koala.jpg'))
const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));

@@ -359,17 +448,28 @@ // const buffer=[]

mock.onGet("/Koala.jpg").reply(
200,
buffer,
{
// mock.onGet("/Koala.jpg").reply(
// 200,
// buffer,
// {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '29051'
// }
// )
nock('http://www.dummyurl.com')
.get('/Koala.jpg')
.reply(200, (uri, requestBody) => {
return buffer
// fs.readFile(Path.join(__dirname, 'fixtures/Desert.jpg'), cb) // Error-first callback
}, {
'Content-Type': 'image/jpeg',
'Content-Length': '29051'
}
})
)
try {
const downloader = new Downloader({
url: '/Koala.jpg',
url: 'http://www.dummyurl.com/Koala.jpg',
directory: "./downloads",
cloneFiles: false,
fileName: 'buffer.jpeg',
shouldBufferResponse: true

@@ -383,6 +483,8 @@ })

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

@@ -399,9 +501,16 @@

mock.onGet("/400").reply(400)
// mock.onGet("/400").reply(400)
nock('http://www.dummyurl.com')
.get('/400')
.reply(400).persist()
try {
var counter = 0;
const downloader = new Downloader({
url: '/400',
url: 'http://www.dummyurl.com/400',
directory: "./downloads",
maxAttempts: 3
maxAttempts: 3,
onError:function(){
counter++;
}
})

@@ -417,3 +526,3 @@ // console.log(downloader)

} catch (error) {
// expect(1+2).toBe(1)
expect(counter).toBe(3)
expect(error.message).toBe('Request failed with status code 400')

@@ -429,69 +538,4 @@ // debugger;

it('Should fail twice and finally succeed', async () => {
const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
let counter = 0;
mock.onGet("/400").reply(function (config) {
// debugger;
let status;
counter++
if (counter < 3) {
status = 400
} else {
status = 200
}
return [
status,
stream,
{ 'Content-Type': 'image/jpeg' }
];
});
try {
var onErrorCount = 0
const downloader = new Downloader({
timeout: 1000,
url: '/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;
} catch (error) {
debugger;
} finally {
debugger;
// expect(s.constructor.name).toBe('ReadStream')
expect(onErrorCount).toBe(2)
await verifyFile('./downloads/400.jpeg', 29051);
}
})
it('Should fail once and finally fail', async () => {

@@ -501,3 +545,6 @@

mock.onGet("/500").reply(500);
// mock.onGet("/500").reply(500);
nock('http://www.dummyurl.com')
.get('/500')
.reply(500).persist()
var onErrorCount = 0;

@@ -507,3 +554,3 @@ try {

timeout: 1000,
url: '/500',
url: 'http://www.dummyurl.com/500',
directory: "./downloads",

@@ -540,86 +587,26 @@ maxAttempts: 1,

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;
it('Should use onResponse to stop download', async function () {
}
} else {
throw new Error('LOL');
}
// 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')
.get('/Koala.jpg')
.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
}, {
'message': 'terminate'
}).persist()
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 () {
const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
mock.onGet("/koala.jpg").reply(function (config) {
return [
200,
stream,
{'message':'terminate'}
];
});
const downloader = new Downloader({

@@ -629,4 +616,5 @@ timeout: 1000,

maxAttempts: 4,
fileName:'yoyo',
fileName: 'yoyo',
onResponse: function (response) {
// debugger;
if (response.headers['message'] !== 'terminate') {

@@ -637,3 +625,3 @@ // return true

},
url: '/koala.jpg',
url: 'http://www.dummyurl.com/Koala.jpg',
directory: "./downloads",

@@ -643,21 +631,22 @@

try {
await downloader.download();
debugger;
} catch (error) {
debugger;
throw error
}
try {
await verifyFile('./downloads/yoyo', 29051);
await downloader.download();
// debugger;
} catch (error) {
debugger
return;
}
// debugger;
throw error
}
throw new Error();
try {
await verifyFile('./downloads/yoyo', 29051);
} catch (error) {
// expect(true).toBe(true)
// debugger
// return;
}
// throw new Error();
// debugger;

@@ -669,13 +658,21 @@

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 stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// mock.onGet("/koala.jpg").reply(function (config) {
// return [
// 200,
// stream,
// {'message':'do not terminate'}
// ];
// });
nock('http://www.dummyurl.com')
.get('/Koala.jpg')
.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
}, { 'message': 'do not terminate' }).persist()
const downloader = new Downloader({

@@ -688,7 +685,10 @@ timeout: 1000,

// return true
debugger;
return;
}
debugger
return false;
},
url: '/koala.jpg',
url: 'http://www.dummyurl.com/Koala.jpg',
directory: "./downloads",

@@ -698,10 +698,10 @@

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

@@ -717,5 +717,192 @@

// 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 counter = 0
// var onErrorCount = 0
// nock('http://www.dummyurl.com')
// .get('/Koala.jpg')
// .reply(function(uri, requestBody) {
// const stream = fs.createReadStream(Path.join(__dirname, 'fixtures/Koala.jpg'));
// const modifiedStream = Readable.from((async function* () {
// counter++
// debugger;
// // if (counter === 4) {
// // for await (const chunk of stream) {
// // yield chunk;
// // }
// // } else {
// debugger;
// throw new Error('LOL');
// // modifiedStream.emit('error','yoyo')
// // }
// })());
// return [
// 200,
// modifiedStream,
// {}
// ];
// })
// .persist()
// let error;
// const downloader = new Downloader({
// timeout: 1000,
// // debugMode:true,
// maxAttempts: 1,
// // onResponse:function(r){
// // if(r.headers=== 'yoyo'){
// // error='yoyo'
// // return false
// // }
// // },
// url: 'http://www.dummyurl.com/Koala.jpg',
// directory: "./downloads",
// onError: function (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(1)
// // await verifyFile('./downloads/koala.jpg', 29051);
// }
// })
})
// 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) => {
// }, {
// 'Content-Type': 'image/jpeg',
// 'Content-Length': '29051'
// })
// 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)
// }
// })
// // 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);
// }
// })
{
"name": "nodejs-file-downloader",
"version": "3.0.1",
"version": "4.0.0",
"description": "A file downloader for NodeJs",

@@ -23,3 +23,2 @@ "main": "Downloader.js",

"dependencies": {
"axios": "^0.19.2",
"mime-types": "^2.1.27",

@@ -30,5 +29,5 @@ "sanitize-filename": "^1.6.3"

"@types/jest": "^25.2.2",
"axios-mock-adapter": "^1.18.1",
"expect": "^26.0.1",
"mocha": "^7.1.2",
"nock": "^13.0.4",
"rimraf": "^3.0.2"

@@ -35,0 +34,0 @@ },

@@ -105,3 +105,3 @@ 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.

//The response object is an Axios response object. Refer to their docs for more details.
//The response object is a node response(http.IncomingMessage)
function onResponse(response){

@@ -108,0 +108,0 @@ //Now you can do something with the response, like check the headers

@@ -91,3 +91,3 @@ const path = require('path');

counter = counter + 1;
let newFileName = this.fileNameWithoutExtension + counter + this.fileExtension;
let newFileName = this.fileNameWithoutExtension + "_"+ counter + this.fileExtension;

@@ -107,3 +107,3 @@ return this.createNewFileNameSync(newFileName, counter);

counter = counter + 1;
let newFileName = this.fileNameWithoutExtension + counter + this.fileExtension;
let newFileName = this.fileNameWithoutExtension + "_"+ counter + this.fileExtension;

@@ -110,0 +110,0 @@ return await this.createNewFileName(newFileName, counter);

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