@anmiles/downloader 2.0.5 → 2.1.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.
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.1.0](../../tags/v2.1.0) - 2023-08-23
|
|
9
|
+
### Added
|
|
10
|
+
- Append mode for file stream
|
|
11
|
+
|
|
12
|
+
## [2.0.6](../../tags/v2.0.6) - 2023-05-26
|
|
13
|
+
### Changed
|
|
14
|
+
- Re-initialize emitter instance before each test
|
|
15
|
+
|
|
8
16
|
## [2.0.5](../../tags/v2.0.5) - 2023-05-08
|
|
9
17
|
### Changed
|
|
10
18
|
- Use shared eslint config * explicitly specify ignorePatterns
|
package/README.md
CHANGED
|
@@ -20,6 +20,11 @@ import { download } from '@anmiles/downloader';
|
|
|
20
20
|
await download('http://url/file', '/path/to/file');
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
```js
|
|
24
|
+
import { download } from '@anmiles/downloader';
|
|
25
|
+
await download('http://url/file', '/path/to/file', { append: true });
|
|
26
|
+
```
|
|
27
|
+
|
|
23
28
|
```js
|
|
24
29
|
import { downloadString } from '@anmiles/downloader';
|
|
25
30
|
const str = downloadString('http://url/string');
|
package/dist/lib/downloader.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ declare const _default: {
|
|
|
8
8
|
export default _default;
|
|
9
9
|
type BufferEncoding = Parameters<Buffer['toString']>[0];
|
|
10
10
|
declare function download(url: string): Promise<Buffer>;
|
|
11
|
-
declare function download(url: string, file: string
|
|
11
|
+
declare function download(url: string, file: string, options?: {
|
|
12
|
+
append?: boolean;
|
|
13
|
+
}): Promise<void>;
|
|
12
14
|
declare function downloadString(url: string, encoding?: BufferEncoding): Promise<string>;
|
|
13
15
|
declare function downloadJSON(url: string, encoding?: BufferEncoding): Promise<any>;
|
package/dist/lib/downloader.js
CHANGED
|
@@ -10,7 +10,7 @@ const https_1 = __importDefault(require("https"));
|
|
|
10
10
|
const iconv_lite_1 = __importDefault(require("iconv-lite"));
|
|
11
11
|
const downloader_1 = __importDefault(require("./downloader"));
|
|
12
12
|
exports.default = { download, downloadString, downloadJSON };
|
|
13
|
-
function download(url, file) {
|
|
13
|
+
function download(url, file, options) {
|
|
14
14
|
return new Promise((resolve, reject) => {
|
|
15
15
|
let protocol;
|
|
16
16
|
if (url.startsWith('https://')) {
|
|
@@ -22,12 +22,12 @@ function download(url, file) {
|
|
|
22
22
|
else {
|
|
23
23
|
throw `Unknown protocol in url ${url}, expected one of "http" or "https"`;
|
|
24
24
|
}
|
|
25
|
-
const
|
|
25
|
+
const reqOptions = {
|
|
26
26
|
headers: {
|
|
27
27
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
|
-
protocol.get(url,
|
|
30
|
+
protocol.get(url, reqOptions, function (res) {
|
|
31
31
|
if (res.statusCode !== 200) {
|
|
32
32
|
reject(`Request to ${url} returned with status code: ${res.statusCode}`);
|
|
33
33
|
res.resume();
|
|
@@ -42,7 +42,7 @@ function download(url, file) {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
res.pipe(fs_1.default.createWriteStream(file));
|
|
45
|
+
res.pipe(fs_1.default.createWriteStream(file, { flags: (options === null || options === void 0 ? void 0 : options.append) ? 'a' : 'w' }));
|
|
46
46
|
res.on('end', function () {
|
|
47
47
|
resolve();
|
|
48
48
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/lib/downloader.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,kDAA0B;AAC1B,4DAA+B;AAE/B,8DAAsC;AAGtC,kBAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AAM1D,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAa;
|
|
1
|
+
{"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/lib/downloader.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,kDAA0B;AAC1B,4DAA+B;AAE/B,8DAAsC;AAGtC,kBAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AAM1D,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAa,EAAE,OAA8B;IAC3E,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrD,IAAI,QAAqC,CAAC;QAE1C,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;YAC/B,QAAQ,GAAG,eAAK,CAAC;SACjB;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;YACrC,QAAQ,GAAG,cAAI,CAAC;SAChB;aAAM;YACN,MAAM,2BAA2B,GAAG,qCAAqC,CAAC;SAC1E;QAED,MAAM,UAAU,GAAG;YAClB,OAAO,EAAG;gBACT,YAAY,EAAG,iHAAiH;aAChI;SACD,CAAC;QAEF,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,UAAS,GAAG;YACzC,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE;gBAC3B,MAAM,CAAC,cAAc,GAAG,+BAA+B,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;gBACzE,GAAG,CAAC,MAAM,EAAE,CAAC;aACb;YAED,MAAM,MAAM,GAAiB,EAAE,CAAC;YAEhC,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE;gBAChC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,UAAS,KAAK;oBAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE;oBACb,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;aACH;iBAAM;gBACN,GAAG,CAAC,IAAI,CAAC,YAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAE9E,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE;oBACb,OAAO,EAAE,CAAC;gBACX,CAAC,CAAC,CAAC;aACH;QACF,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACpB,MAAM,CAAC,cAAc,GAAG,uBAAuB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AApDQ,4BAAQ;AAsDjB,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,WAA2B,MAAM;IAC3E,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QACjC,MAAM,oBAAoB,QAAQ,EAAE,CAAC;KACrC;IAED,MAAM,MAAM,GAAG,MAAM,oBAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,oBAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AA7DkB,wCAAc;AA+DjC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,WAA2B,MAAM;IACzE,MAAM,IAAI,GAAG,MAAM,oBAAU,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAlEkC,oCAAY"}
|
package/package.json
CHANGED
|
@@ -12,10 +12,8 @@ jest.mock<Partial<typeof downloader>>('../downloader', () => ({
|
|
|
12
12
|
downloadString : jest.fn().mockImplementation((...args: Parameters<typeof original.downloadString>) => original.downloadString(...args)),
|
|
13
13
|
}));
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
response.pipe = jest.fn();
|
|
18
|
-
response.resume = jest.fn();
|
|
15
|
+
let request: http.ClientRequest;
|
|
16
|
+
let response: http.IncomingMessage;
|
|
19
17
|
|
|
20
18
|
function get(url: string | URL, options: https.RequestOptions, callback?: ((res: http.IncomingMessage) => void) | undefined): http.ClientRequest {
|
|
21
19
|
if (callback) {
|
|
@@ -26,6 +24,12 @@ function get(url: string | URL, options: https.RequestOptions, callback?: ((res:
|
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
beforeEach(() => {
|
|
27
|
+
request = emitter() as typeof request;
|
|
28
|
+
response = emitter() as typeof response;
|
|
29
|
+
|
|
30
|
+
response.pipe = jest.fn();
|
|
31
|
+
response.resume = jest.fn();
|
|
32
|
+
|
|
29
33
|
response.statusCode = 200;
|
|
30
34
|
});
|
|
31
35
|
|
|
@@ -100,7 +104,7 @@ describe('src/lib/downloader', () => {
|
|
|
100
104
|
expect(result).toEqual(Buffer.from([ 10, 11, 12, 20, 21, 22, 30, 31, 32 ]));
|
|
101
105
|
});
|
|
102
106
|
|
|
103
|
-
it('should pipe response stream to file if specified', async () => {
|
|
107
|
+
it('should pipe response stream to file if specified with write mode', async () => {
|
|
104
108
|
const stream = {} as fs.WriteStream;
|
|
105
109
|
const createWriteStreamSpy = jest.spyOn(fs, 'createWriteStream').mockReturnValue(stream);
|
|
106
110
|
const promise = original.download('http://url', 'file');
|
|
@@ -109,7 +113,22 @@ describe('src/lib/downloader', () => {
|
|
|
109
113
|
response.emit('data', new Uint8Array([ 30, 31, 32 ]));
|
|
110
114
|
response.emit('end');
|
|
111
115
|
const result = await promise;
|
|
112
|
-
expect(createWriteStreamSpy).toHaveBeenCalledWith('file');
|
|
116
|
+
expect(createWriteStreamSpy).toHaveBeenCalledWith('file', { flags : 'w' });
|
|
117
|
+
expect(response.pipe).toHaveBeenCalledWith(stream);
|
|
118
|
+
expect(result).toEqual(undefined);
|
|
119
|
+
createWriteStreamSpy.mockRestore();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should pipe response stream to file if specified with append mode', async () => {
|
|
123
|
+
const stream = {} as fs.WriteStream;
|
|
124
|
+
const createWriteStreamSpy = jest.spyOn(fs, 'createWriteStream').mockReturnValue(stream);
|
|
125
|
+
const promise = original.download('http://url', 'file', { append : true });
|
|
126
|
+
response.emit('data', new Uint8Array([ 10, 11, 12 ]));
|
|
127
|
+
response.emit('data', new Uint8Array([ 20, 21, 22 ]));
|
|
128
|
+
response.emit('data', new Uint8Array([ 30, 31, 32 ]));
|
|
129
|
+
response.emit('end');
|
|
130
|
+
const result = await promise;
|
|
131
|
+
expect(createWriteStreamSpy).toHaveBeenCalledWith('file', { flags : 'a' });
|
|
113
132
|
expect(response.pipe).toHaveBeenCalledWith(stream);
|
|
114
133
|
expect(result).toEqual(undefined);
|
|
115
134
|
createWriteStreamSpy.mockRestore();
|
package/src/lib/downloader.ts
CHANGED
|
@@ -11,8 +11,8 @@ export default { download, downloadString, downloadJSON };
|
|
|
11
11
|
type BufferEncoding = Parameters<Buffer['toString']>[0];
|
|
12
12
|
|
|
13
13
|
function download(url: string): Promise<Buffer>;
|
|
14
|
-
function download(url: string, file: string): Promise<void>;
|
|
15
|
-
function download(url: string, file?: string): Promise<Buffer | void> {
|
|
14
|
+
function download(url: string, file: string, options?: { append?: boolean }): Promise<void>;
|
|
15
|
+
function download(url: string, file?: string, options?: { append?: boolean }): Promise<Buffer | void> {
|
|
16
16
|
return new Promise<Buffer | void>((resolve, reject) => {
|
|
17
17
|
let protocol : typeof https | typeof http;
|
|
18
18
|
|
|
@@ -24,13 +24,13 @@ function download(url: string, file?: string): Promise<Buffer | void> {
|
|
|
24
24
|
throw `Unknown protocol in url ${url}, expected one of "http" or "https"`;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const reqOptions = {
|
|
28
28
|
headers : {
|
|
29
29
|
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
protocol.get(url,
|
|
33
|
+
protocol.get(url, reqOptions, function(res) {
|
|
34
34
|
if (res.statusCode !== 200) {
|
|
35
35
|
reject(`Request to ${url} returned with status code: ${res.statusCode}`);
|
|
36
36
|
res.resume();
|
|
@@ -47,7 +47,7 @@ function download(url: string, file?: string): Promise<Buffer | void> {
|
|
|
47
47
|
resolve(Buffer.concat(chunks));
|
|
48
48
|
});
|
|
49
49
|
} else {
|
|
50
|
-
res.pipe(fs.createWriteStream(file));
|
|
50
|
+
res.pipe(fs.createWriteStream(file, { flags : options?.append ? 'a' : 'w' }));
|
|
51
51
|
|
|
52
52
|
res.on('end', function() {
|
|
53
53
|
resolve();
|