UNPKG

1.52 kBJavaScriptView Raw
1'use strict';
2const {Transform} = require('stream');
3const decompressResponse = require('decompress-response');
4const is = require('@sindresorhus/is');
5const mimicResponse = require('mimic-response');
6
7module.exports = (response, options, emitter, redirects) => {
8 const downloadBodySize = Number(response.headers['content-length']) || null;
9 let downloaded = 0;
10
11 const progressStream = new Transform({
12 transform(chunk, encoding, callback) {
13 downloaded += chunk.length;
14
15 const percent = downloadBodySize ? downloaded / downloadBodySize : 0;
16
17 // Let `flush()` be responsible for emitting the last event
18 if (percent < 1) {
19 emitter.emit('downloadProgress', {
20 percent,
21 transferred: downloaded,
22 total: downloadBodySize
23 });
24 }
25
26 callback(null, chunk);
27 },
28
29 flush(callback) {
30 emitter.emit('downloadProgress', {
31 percent: 1,
32 transferred: downloaded,
33 total: downloadBodySize
34 });
35
36 callback();
37 }
38 });
39
40 mimicResponse(response, progressStream);
41 progressStream.redirectUrls = redirects;
42
43 const newResponse = options.decompress === true &&
44 is.function(decompressResponse) &&
45 options.method !== 'HEAD' ? decompressResponse(progressStream) : progressStream;
46
47 if (!options.decompress && ['gzip', 'deflate'].includes(response.headers['content-encoding'])) {
48 options.encoding = null;
49 }
50
51 emitter.emit('response', newResponse);
52
53 emitter.emit('downloadProgress', {
54 percent: 0,
55 transferred: 0,
56 total: downloadBodySize
57 });
58
59 response.pipe(progressStream);
60};