@xhmikosr/downloader 11.0.2 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +50 -35
  2. package/package.json +7 -7
  3. package/readme.md +7 -1
package/index.js CHANGED
@@ -4,12 +4,14 @@ import process from 'node:process';
4
4
  import contentDisposition from 'content-disposition';
5
5
  import archiveType from '@xhmikosr/archive-type';
6
6
  import decompress from '@xhmikosr/decompress';
7
+ import extName from 'ext-name';
8
+ import {fileTypeFromBuffer} from 'file-type';
7
9
  import filenamify from 'filenamify';
8
10
  import getStream from 'get-stream';
9
11
  import got from 'got';
12
+ // TODO replace with `defaults` package when we drop Node.js < 16 support
13
+ import mergeOptions from 'merge-options';
10
14
  import {pEvent} from 'p-event';
11
- import fileType from 'file-type';
12
- import extName from 'ext-name';
13
15
 
14
16
  const filenameFromPath = res => path.basename(new URL(res.requestUrl).pathname);
15
17
 
@@ -29,13 +31,13 @@ const getExtFromMime = res => {
29
31
  return exts[0].ext;
30
32
  };
31
33
 
32
- const getFilename = (res, data) => {
34
+ const getFilename = async (res, data) => {
33
35
  const header = res.headers['content-disposition'];
34
36
 
35
37
  if (header) {
36
38
  const parsed = contentDisposition.parse(header);
37
39
 
38
- if (parsed.parameters && parsed.parameters.filename) {
40
+ if (parsed.parameters?.filename) {
39
41
  return parsed.parameters.filename;
40
42
  }
41
43
  }
@@ -43,7 +45,8 @@ const getFilename = (res, data) => {
43
45
  let filename = filenameFromPath(res);
44
46
 
45
47
  if (!path.extname(filename)) {
46
- const ext = (fileType(data) || {}).ext || getExtFromMime(res);
48
+ const fileType = await fileTypeFromBuffer(data);
49
+ const ext = fileType?.ext || getExtFromMime(res);
47
50
 
48
51
  if (ext) {
49
52
  filename = `${filename}.${ext}`;
@@ -59,39 +62,51 @@ const download = (uri, output, options) => {
59
62
  output = null;
60
63
  }
61
64
 
62
- options = {
63
- responseType: 'buffer',
64
- https: {
65
- rejectUnauthorized: process.env.npm_config_strict_ssl !== 'false',
65
+ const defaultOptions = {
66
+ got: {
67
+ responseType: 'buffer',
68
+ https: {
69
+ rejectUnauthorized: process.env.npm_config_strict_ssl !== 'false',
70
+ },
66
71
  },
67
- ...options,
72
+ decompress: {},
68
73
  };
69
74
 
70
- const stream = got.stream(uri, options);
71
-
72
- const promise = pEvent(stream, 'response').then(res => {
73
- const encoding = options.responseType === 'buffer' ? 'buffer' : options.encoding;
74
- return Promise.all([getStream(stream, {encoding}), res]);
75
- }).then(result => {
76
- const [data, res] = result;
77
-
78
- if (!output) {
79
- return options.extract && archiveType(data) ? decompress(data, options) : data;
80
- }
81
-
82
- const filename = options.filename || filenamify(getFilename(res, data));
83
- const outputFilepath = path.join(output, filename);
84
-
85
- if (options.extract && archiveType(data)) {
86
- return decompress(data, path.dirname(outputFilepath), options);
87
- }
88
-
89
- return fs.mkdir(path.dirname(outputFilepath), {recursive: true})
90
- .then(() => fs.writeFile(outputFilepath, data))
91
- .then(() => data);
92
- });
93
-
94
- stream.then = promise.then.bind(promise); // eslint-disable-line unicorn/no-thenable
75
+ options = mergeOptions(defaultOptions, options);
76
+
77
+ const stream = got.stream(uri, options.got);
78
+
79
+ const promise = pEvent(stream, 'response')
80
+ .then(res => {
81
+ const encoding = options.got.responseType === 'buffer' ? 'buffer' : options.got.encoding;
82
+ return Promise.all([getStream(stream, {encoding}), res]);
83
+ })
84
+ .then(async ([data, res]) => {
85
+ if (!output) {
86
+ return options.extract && await archiveType(data)
87
+ ? decompress(data, options.decompress)
88
+ : data;
89
+ }
90
+
91
+ const filename = options.filename || filenamify(await getFilename(res, data));
92
+ const outputFilepath = path.join(output, filename);
93
+
94
+ if (options.extract && await archiveType(data)) {
95
+ return decompress(
96
+ data,
97
+ path.dirname(outputFilepath),
98
+ options.decompress,
99
+ );
100
+ }
101
+
102
+ return fs
103
+ .mkdir(path.dirname(outputFilepath), {recursive: true})
104
+ .then(() => fs.writeFile(outputFilepath, data))
105
+ .then(() => data);
106
+ });
107
+
108
+ // eslint-disable-next-line unicorn/no-thenable
109
+ stream.then = promise.then.bind(promise);
95
110
  stream.catch = promise.catch.bind(promise);
96
111
 
97
112
  return stream;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xhmikosr/downloader",
3
- "version": "11.0.2",
3
+ "version": "12.0.0",
4
4
  "description": "Download and extract files",
5
5
  "license": "MIT",
6
6
  "repository": "XhmikosR/download",
@@ -39,23 +39,23 @@
39
39
  "url"
40
40
  ],
41
41
  "dependencies": {
42
- "@xhmikosr/archive-type": "^5.0.0",
43
- "@xhmikosr/decompress": "^7.0.0",
42
+ "@xhmikosr/archive-type": "^6.0.1",
43
+ "@xhmikosr/decompress": "^8.0.0",
44
44
  "content-disposition": "^0.5.4",
45
45
  "ext-name": "^5.0.0",
46
- "file-type": "^12.4.2",
46
+ "file-type": "^18.5.0",
47
47
  "filenamify": "^5.1.1",
48
48
  "get-stream": "^6.0.1",
49
- "got": "^11.8.6",
49
+ "got": "^12.6.1",
50
+ "merge-options": "^3.0.4",
50
51
  "p-event": "^5.0.1"
51
52
  },
52
53
  "devDependencies": {
53
- "ava": "^5.3.0",
54
+ "ava": "^4.3.3",
54
55
  "c8": "^7.14.0",
55
56
  "is-zip": "^1.0.0",
56
57
  "nock": "^13.3.1",
57
58
  "path-exists": "^5.0.0",
58
- "random-buffer": "^0.1.0",
59
59
  "xo": "^0.54.2"
60
60
  },
61
61
  "xo": {
package/readme.md CHANGED
@@ -57,9 +57,15 @@ Path to where your file will be written.
57
57
 
58
58
  #### options
59
59
 
60
+ ##### options.got
61
+
60
62
  Type: `Object`
61
63
 
62
- Same options as [`got`](https://github.com/sindresorhus/got#options) and [`decompress`](https://github.com/XhmikosR/decompress#options) in addition to the ones below.
64
+ Same options as [`got`](https://github.com/sindresorhus/got#options).
65
+
66
+ ##### options.decompress
67
+
68
+ Same options as [`decompress`](https://github.com/XhmikosR/decompress#options).
63
69
 
64
70
  ##### extract
65
71