nodejs-file-downloader
Advanced tools
Comparing version 3.0.1 to 4.0.0
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); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
153850
2
13
1278
2
- Removedaxios@^0.19.2
- Removedaxios@0.19.2(transitive)
- Removedfollow-redirects@1.5.10(transitive)