@anmiles/downloader 2.0.0 → 2.0.2
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/.eslintrc.js +1 -88
- package/CHANGELOG.md +9 -1
- package/dist/lib/downloader.d.ts +3 -2
- package/dist/lib/downloader.js.map +1 -1
- package/package.json +5 -3
- package/src/lib/__tests__/downloader.test.ts +17 -38
- package/src/lib/downloader.ts +4 -2
- package/file +0 -0
package/.eslintrc.js
CHANGED
|
@@ -1,93 +1,6 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
root : true,
|
|
3
3
|
extends : [
|
|
4
|
-
'eslint
|
|
5
|
-
'plugin:jest/recommended',
|
|
4
|
+
'./node_modules/@anmiles/eslint-config/.eslintrc.js',
|
|
6
5
|
],
|
|
7
|
-
parser : '@typescript-eslint/parser',
|
|
8
|
-
parserOptions : {
|
|
9
|
-
ecmaVersion : 2019,
|
|
10
|
-
sourceType : 'module',
|
|
11
|
-
},
|
|
12
|
-
plugins : [
|
|
13
|
-
'@typescript-eslint',
|
|
14
|
-
'align-assignments',
|
|
15
|
-
'import',
|
|
16
|
-
'jest',
|
|
17
|
-
],
|
|
18
|
-
env : {
|
|
19
|
-
node : true,
|
|
20
|
-
jest : true,
|
|
21
|
-
},
|
|
22
|
-
ignorePatterns : [
|
|
23
|
-
'**/node_modules/',
|
|
24
|
-
'coverage/',
|
|
25
|
-
'dist/',
|
|
26
|
-
],
|
|
27
|
-
rules : {
|
|
28
|
-
'no-unused-vars' : [ 'off' ],
|
|
29
|
-
'@typescript-eslint/no-redeclare' : [ 'error' ],
|
|
30
|
-
'@typescript-eslint/no-unused-vars' : [ 'error' ],
|
|
31
|
-
'align-assignments/align-assignments' : [ 'error' ],
|
|
32
|
-
'array-bracket-spacing' : [ 'error', 'always' ],
|
|
33
|
-
'arrow-body-style' : [ 'error' ],
|
|
34
|
-
'arrow-parens' : [ 'error' ],
|
|
35
|
-
'arrow-spacing' : [ 'error' ],
|
|
36
|
-
'block-spacing' : [ 'error' ],
|
|
37
|
-
'brace-style' : [ 'error' ],
|
|
38
|
-
'camelcase' : [ 'error' ],
|
|
39
|
-
'comma-dangle' : [ 'error', 'always-multiline' ],
|
|
40
|
-
'comma-spacing' : [ 'error' ],
|
|
41
|
-
'comma-style' : [ 'error' ],
|
|
42
|
-
'complexity' : [ 'error' ],
|
|
43
|
-
'computed-property-spacing' : [ 'error', 'never' ],
|
|
44
|
-
'curly' : [ 'error' ],
|
|
45
|
-
'dot-location' : [ 'error', 'property' ],
|
|
46
|
-
'eol-last' : [ 'error' ],
|
|
47
|
-
'func-call-spacing' : [ 'error' ],
|
|
48
|
-
'func-style' : [ 'error', 'declaration', { allowArrowFunctions : true } ],
|
|
49
|
-
'generator-star-spacing' : [ 'error', 'neither' ],
|
|
50
|
-
'import/order' : [ 'error', { groups : [ 'builtin', 'external', 'unknown', 'internal', 'parent', 'sibling', 'index' ] } ],
|
|
51
|
-
'indent' : [ 'error', 'tab', { SwitchCase : 1 } ],
|
|
52
|
-
'jest/no-standalone-expect' : [ 'error' ],
|
|
53
|
-
'key-spacing' : [ 'error', { beforeColon : true, afterColon : true, align : 'colon' } ],
|
|
54
|
-
'keyword-spacing' : [ 'error' ],
|
|
55
|
-
'linebreak-style' : [ 'error', 'unix' ],
|
|
56
|
-
'max-params' : [ 'error', { max : 5 } ],
|
|
57
|
-
'new-parens' : [ 'error' ],
|
|
58
|
-
'no-eval' : [ 'error' ],
|
|
59
|
-
'no-extra-bind' : [ 'error' ],
|
|
60
|
-
'no-floating-decimal' : [ 'error' ],
|
|
61
|
-
'no-implied-eval' : [ 'error' ],
|
|
62
|
-
'no-loop-func' : [ 'error' ],
|
|
63
|
-
'no-mixed-spaces-and-tabs' : [ 'error', 'smart-tabs' ],
|
|
64
|
-
'no-multiple-empty-lines' : [ 'error', { max : 1, maxEOF : 1, maxBOF : 0 } ],
|
|
65
|
-
'no-redeclare' : [ 'off' ],
|
|
66
|
-
'no-return-await' : [ 'error' ],
|
|
67
|
-
'no-trailing-spaces' : [ 'error' ],
|
|
68
|
-
'no-useless-rename' : [ 'error' ],
|
|
69
|
-
'no-var' : [ 'error' ],
|
|
70
|
-
'no-whitespace-before-property' : [ 'error' ],
|
|
71
|
-
'object-curly-spacing' : [ 'error', 'always' ],
|
|
72
|
-
'object-property-newline' : [ 'error', { allowMultiplePropertiesPerLine : true } ],
|
|
73
|
-
'object-shorthand' : [ 'error' ],
|
|
74
|
-
'operator-linebreak' : [ 'error', 'before' ],
|
|
75
|
-
'prefer-const' : [ 'error' ],
|
|
76
|
-
'prefer-numeric-literals' : [ 'error' ],
|
|
77
|
-
'prefer-spread' : [ 'error' ],
|
|
78
|
-
'prefer-template' : [ 'error' ],
|
|
79
|
-
'quote-props' : [ 'error', 'consistent-as-needed' ],
|
|
80
|
-
'quotes' : [ 'error', 'single', { avoidEscape : true } ],
|
|
81
|
-
'semi-spacing' : [ 'error' ],
|
|
82
|
-
'semi' : [ 'error' ],
|
|
83
|
-
'space-before-blocks' : [ 'error' ],
|
|
84
|
-
'space-before-function-paren' : [ 'error', { anonymous : 'never', named : 'never', asyncArrow : 'always' } ],
|
|
85
|
-
'space-in-parens' : [ 'error' ],
|
|
86
|
-
'space-infix-ops' : [ 'error' ],
|
|
87
|
-
'space-unary-ops' : [ 'error' ],
|
|
88
|
-
'spaced-comment' : [ 'error' ],
|
|
89
|
-
'template-curly-spacing' : [ 'error' ],
|
|
90
|
-
'yield-star-spacing' : [ 'error' ],
|
|
91
|
-
'yoda' : [ 'error' ],
|
|
92
|
-
},
|
|
93
6
|
};
|
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,15 @@ 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
|
-
## [
|
|
8
|
+
## [2.0.2](../../tags/v2.0.2) - 2023-05-06
|
|
9
|
+
### Changed
|
|
10
|
+
- Use shared eslint config
|
|
11
|
+
|
|
12
|
+
## [2.0.1](../../tags/v2.0.1) - 2023-05-04
|
|
13
|
+
### Changed
|
|
14
|
+
- Use `event-emitter` to mock subscriptions on request/response
|
|
15
|
+
|
|
16
|
+
## [2.0.0](../../tags/v2.0.0) - 2023-05-03
|
|
9
17
|
### Changed
|
|
10
18
|
- Ready to release
|
|
11
19
|
|
package/dist/lib/downloader.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ declare const _default: {
|
|
|
6
6
|
downloadJSON: typeof downloadJSON;
|
|
7
7
|
};
|
|
8
8
|
export default _default;
|
|
9
|
+
type BufferEncoding = Parameters<Buffer['toString']>[0];
|
|
9
10
|
declare function download(url: string): Promise<Buffer>;
|
|
10
11
|
declare function download(url: string, file: string): Promise<void>;
|
|
11
|
-
declare function downloadString(url: string, encoding?:
|
|
12
|
-
declare function downloadJSON(url: string, encoding?:
|
|
12
|
+
declare function downloadString(url: string, encoding?: BufferEncoding): Promise<string>;
|
|
13
|
+
declare function downloadJSON(url: string, encoding?: BufferEncoding): Promise<any>;
|
|
@@ -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;
|
|
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;IAC3C,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,OAAO,GAAG;YACf,OAAO,EAAG;gBACT,YAAY,EAAG,iHAAiH;aAChI;SACD,CAAC;QAEF,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,UAAS,GAAG;YACtC,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,CAAC,CAAC,CAAC;gBAErC,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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anmiles/downloader",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Wrapper for downloading data as string, buffer or complex types",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"download",
|
|
@@ -27,17 +27,19 @@
|
|
|
27
27
|
"test:report:coverage": "nyc report --nycrc-path ./coverage.config.js -t ./coverage --report-dir ./coverage"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"colorette": "^2.0.19",
|
|
31
30
|
"iconv-lite": "^0.6.3"
|
|
32
31
|
},
|
|
33
32
|
"devDependencies": {
|
|
33
|
+
"@anmiles/eslint-config": "^1.0.4",
|
|
34
|
+
"@types/event-emitter": "^0.3.3",
|
|
34
35
|
"@types/jest": "^29.5.1",
|
|
35
36
|
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
|
36
37
|
"@typescript-eslint/parser": "^5.59.2",
|
|
37
|
-
"eslint": "^8.
|
|
38
|
+
"eslint": "^8.40.0",
|
|
38
39
|
"eslint-plugin-align-assignments": "^1.1.2",
|
|
39
40
|
"eslint-plugin-import": "^2.27.5",
|
|
40
41
|
"eslint-plugin-jest": "^27.2.1",
|
|
42
|
+
"event-emitter": "^0.3.5",
|
|
41
43
|
"jest": "^29.5.0",
|
|
42
44
|
"nyc": "^15.1.0",
|
|
43
45
|
"rimraf": "^5.0.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import http from 'http';
|
|
3
3
|
import https from 'https';
|
|
4
|
+
import emitter from 'event-emitter';
|
|
4
5
|
import iconv from 'iconv-lite';
|
|
5
6
|
|
|
6
7
|
import downloader from '../downloader';
|
|
@@ -11,20 +12,10 @@ jest.mock<Partial<typeof downloader>>('../downloader', () => ({
|
|
|
11
12
|
downloadString : jest.fn().mockImplementation((...args: Parameters<typeof original.downloadString>) => original.downloadString(...args)),
|
|
12
13
|
}));
|
|
13
14
|
|
|
14
|
-
const request
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
requestError = listener;
|
|
19
|
-
break;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const response = {} as http.IncomingMessage;
|
|
24
|
-
|
|
25
|
-
let data: (data: Uint8Array) => void = () => {};
|
|
26
|
-
let end: () => void = () => {};
|
|
27
|
-
let requestError: (e: Error) => void = () => {};
|
|
15
|
+
const request = emitter() as http.ClientRequest;
|
|
16
|
+
const response = emitter() as http.IncomingMessage;
|
|
17
|
+
response.pipe = jest.fn();
|
|
18
|
+
response.resume = jest.fn();
|
|
28
19
|
|
|
29
20
|
function get(url: string | URL, options: https.RequestOptions, callback?: ((res: http.IncomingMessage) => void) | undefined): http.ClientRequest {
|
|
30
21
|
if (callback) {
|
|
@@ -36,18 +27,6 @@ function get(url: string | URL, options: https.RequestOptions, callback?: ((res:
|
|
|
36
27
|
|
|
37
28
|
beforeEach(() => {
|
|
38
29
|
response.statusCode = 200;
|
|
39
|
-
response.on = jest.fn().mockImplementation((ev: string, listener: () => void) => {
|
|
40
|
-
switch (ev) {
|
|
41
|
-
case 'data':
|
|
42
|
-
data = listener;
|
|
43
|
-
break;
|
|
44
|
-
case 'end':
|
|
45
|
-
end = listener;
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
response.pipe = jest.fn();
|
|
50
|
-
response.resume = jest.fn();
|
|
51
30
|
});
|
|
52
31
|
|
|
53
32
|
let httpGetSpy: jest.SpyInstance;
|
|
@@ -76,21 +55,21 @@ describe('src/lib/downloader', () => {
|
|
|
76
55
|
|
|
77
56
|
it('should call http.get if url protocol is http', async () => {
|
|
78
57
|
const promise = original.download('http://url');
|
|
79
|
-
end
|
|
58
|
+
response.emit('end');
|
|
80
59
|
await promise;
|
|
81
60
|
expect(httpGetSpy.mock.calls[0][0]).toEqual('http://url');
|
|
82
61
|
});
|
|
83
62
|
|
|
84
63
|
it('should call https.get if url protocol is https', async () => {
|
|
85
64
|
const promise = original.download('https://url');
|
|
86
|
-
end
|
|
65
|
+
response.emit('end');
|
|
87
66
|
await promise;
|
|
88
67
|
expect(httpsGetSpy.mock.calls[0][0]).toEqual('https://url');
|
|
89
68
|
});
|
|
90
69
|
|
|
91
70
|
it('should pass user-agent in options', async () => {
|
|
92
71
|
const promise = original.download('http://url');
|
|
93
|
-
end
|
|
72
|
+
response.emit('end');
|
|
94
73
|
await promise;
|
|
95
74
|
expect(httpGetSpy.mock.calls[0][1]).toEqual(expect.objectContaining({
|
|
96
75
|
headers : {
|
|
@@ -107,16 +86,16 @@ describe('src/lib/downloader', () => {
|
|
|
107
86
|
|
|
108
87
|
it('should reject if response errored', async () => {
|
|
109
88
|
const promise = original.download('http://url');
|
|
110
|
-
|
|
89
|
+
request.emit('error', new Error('request error'));
|
|
111
90
|
await expect(() => promise).rejects.toEqual('Request to http://url failed with error: request error');
|
|
112
91
|
});
|
|
113
92
|
|
|
114
93
|
it('should concat and resolve received data if no file specified', async () => {
|
|
115
94
|
const promise = original.download('http://url');
|
|
116
|
-
data
|
|
117
|
-
data
|
|
118
|
-
data
|
|
119
|
-
end
|
|
95
|
+
response.emit('data', new Uint8Array([ 10, 11, 12 ]));
|
|
96
|
+
response.emit('data', new Uint8Array([ 20, 21, 22 ]));
|
|
97
|
+
response.emit('data', new Uint8Array([ 30, 31, 32 ]));
|
|
98
|
+
response.emit('end');
|
|
120
99
|
const result = await promise;
|
|
121
100
|
expect(result).toEqual(Buffer.from([ 10, 11, 12, 20, 21, 22, 30, 31, 32 ]));
|
|
122
101
|
});
|
|
@@ -125,10 +104,10 @@ describe('src/lib/downloader', () => {
|
|
|
125
104
|
const stream = {} as fs.WriteStream;
|
|
126
105
|
const createWriteStreamSpy = jest.spyOn(fs, 'createWriteStream').mockReturnValue(stream);
|
|
127
106
|
const promise = original.download('http://url', 'file');
|
|
128
|
-
data
|
|
129
|
-
data
|
|
130
|
-
data
|
|
131
|
-
end
|
|
107
|
+
response.emit('data', new Uint8Array([ 10, 11, 12 ]));
|
|
108
|
+
response.emit('data', new Uint8Array([ 20, 21, 22 ]));
|
|
109
|
+
response.emit('data', new Uint8Array([ 30, 31, 32 ]));
|
|
110
|
+
response.emit('end');
|
|
132
111
|
const result = await promise;
|
|
133
112
|
expect(createWriteStreamSpy).toHaveBeenCalledWith('file');
|
|
134
113
|
expect(response.pipe).toHaveBeenCalledWith(stream);
|
package/src/lib/downloader.ts
CHANGED
|
@@ -8,6 +8,8 @@ import downloader from './downloader';
|
|
|
8
8
|
export { download, downloadString, downloadJSON };
|
|
9
9
|
export default { download, downloadString, downloadJSON };
|
|
10
10
|
|
|
11
|
+
type BufferEncoding = Parameters<Buffer['toString']>[0];
|
|
12
|
+
|
|
11
13
|
function download(url: string): Promise<Buffer>;
|
|
12
14
|
function download(url: string, file: string): Promise<void>;
|
|
13
15
|
function download(url: string, file?: string): Promise<Buffer | void> {
|
|
@@ -57,7 +59,7 @@ function download(url: string, file?: string): Promise<Buffer | void> {
|
|
|
57
59
|
});
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
async function downloadString(url: string, encoding:
|
|
62
|
+
async function downloadString(url: string, encoding: BufferEncoding = 'utf8') {
|
|
61
63
|
if (!Buffer.isEncoding(encoding)) {
|
|
62
64
|
throw `Unknown encoding ${encoding}`;
|
|
63
65
|
}
|
|
@@ -66,7 +68,7 @@ async function downloadString(url: string, encoding: Parameters<Buffer['toString
|
|
|
66
68
|
return iconv.decode(buffer, encoding);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
async function downloadJSON(url: string, encoding:
|
|
71
|
+
async function downloadJSON(url: string, encoding: BufferEncoding = 'utf8') {
|
|
70
72
|
const json = await downloader.downloadString(url, encoding);
|
|
71
73
|
return JSON.parse(json);
|
|
72
74
|
}
|
package/file
DELETED
|
File without changes
|