@ezs/basics 1.16.0 → 1.18.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
@@ -3,6 +3,39 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.18.0](https://github.com/Inist-CNRS/ezs/compare/@ezs/basics@1.17.1...@ezs/basics@1.18.0) (2022-06-21)
7
+
8
+
9
+ ### Features
10
+
11
+ * 🎸 add [FILESave] ([2e7dfd7](https://github.com/Inist-CNRS/ezs/commit/2e7dfd76f769418a56f7b9b6cb23d156f37b6789))
12
+
13
+
14
+
15
+
16
+
17
+ ## [1.17.1](https://github.com/Inist-CNRS/ezs/compare/@ezs/basics@1.17.0...@ezs/basics@1.17.1) (2022-04-01)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * erratic error with store ([a26febc](https://github.com/Inist-CNRS/ezs/commit/a26febc4fe7bc0a66a7d32781dc6ef175f707f0a))
23
+
24
+
25
+
26
+
27
+
28
+ # [1.17.0](https://github.com/Inist-CNRS/ezs/compare/@ezs/basics@1.16.0...@ezs/basics@1.17.0) (2022-03-25)
29
+
30
+
31
+ ### Features
32
+
33
+ * 🎸 add retry feature ([166c913](https://github.com/Inist-CNRS/ezs/commit/166c913302b4d305ea34d3b84f9b8be6b5188cbb))
34
+
35
+
36
+
37
+
38
+
6
39
  # [1.16.0](https://github.com/Inist-CNRS/ezs/compare/@ezs/basics@1.15.5...@ezs/basics@1.16.0) (2022-02-07)
7
40
 
8
41
 
package/README.md CHANGED
@@ -18,6 +18,7 @@ npm install @ezs/basics
18
18
  - [CSVObject](#csvobject)
19
19
  - [CSVParse](#csvparse)
20
20
  - [CSVString](#csvstring)
21
+ - [FILESave](#filesave)
21
22
  - [INIString](#inistring)
22
23
  - [JSONParse](#jsonparse)
23
24
  - [JSONString](#jsonstring)
@@ -189,6 +190,43 @@ a;b;c
189
190
 
190
191
  Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
191
192
 
193
+ ### FILESave
194
+
195
+ Take data, convert it to buffer and append it to file
196
+
197
+ ##### Example
198
+
199
+ Input:
200
+
201
+ ```json
202
+ [
203
+ {"a": "a"},
204
+ {"a": "b"},
205
+ {"a": "c" }
206
+ ]
207
+ ```
208
+
209
+ Script:
210
+
211
+ ```ini
212
+ [FILESave]
213
+ location = /tmp
214
+ identifier = toto
215
+ ```
216
+
217
+ Output:
218
+
219
+ ```json
220
+ ["/tmp/truc.json"]
221
+ ```
222
+
223
+ #### Parameters
224
+
225
+ - `location` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Directory location (optional, default `TMPDIR`)
226
+ - `identifier` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** File name
227
+
228
+ Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
229
+
192
230
  ### INIString
193
231
 
194
232
  Take `Object` and generate INI
@@ -548,6 +586,7 @@ Useful to send JSON data to an API and get results.
548
586
  - `json` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Parse as JSON the content of URL (optional, default `false`)
549
587
  - `timeout` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Timeout in milliseconds (optional, default `1000`)
550
588
  - `noerror` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Ignore all errors (optional, default `false`)
589
+ - `retries` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The maximum amount of times to retry the connection (optional, default `5`)
551
590
 
552
591
  Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
553
592
 
@@ -566,6 +605,7 @@ Or if no target is specified, the output will be the returned content of URL.
566
605
  - `timeout` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** timeout in milliseconds (optional, default `1000`)
567
606
  - `mimetype` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** mimetype for value of path (if presents) (optional, default `"application/json"`)
568
607
  - `noerror` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** ignore all errors, the target field will remain undefined (optional, default `false`)
608
+ - `retries` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The maximum amount of times to retry the connection (optional, default `5`)
569
609
 
570
610
  Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
571
611
 
@@ -660,6 +700,7 @@ Output:
660
700
  - `path` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** choose the path to split JSON result (optional, default `"*"`)
661
701
  - `timeout` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Timeout in milliseconds (optional, default `1000`)
662
702
  - `noerror` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Ignore all errors, the target field will remain undefined (optional, default `false`)
703
+ - `retries` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The maximum amount of times to retry the connection (optional, default `5`)
663
704
 
664
705
  Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
665
706
 
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = FILESave;
7
+
8
+ var _fs = require("fs");
9
+
10
+ var _path = _interopRequireDefault(require("path"));
11
+
12
+ var _os = require("os");
13
+
14
+ var _pathExists = _interopRequireDefault(require("path-exists"));
15
+
16
+ var _makeDir = _interopRequireDefault(require("make-dir"));
17
+
18
+ var _streamWrite = _interopRequireDefault(require("stream-write"));
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ /**
23
+ * Take data, convert it to buffer and append it to file
24
+ *
25
+ * #### Example
26
+ *
27
+ * Input:
28
+ *
29
+ * ```json
30
+ * [
31
+ * {"a": "a"},
32
+ * {"a": "b"},
33
+ * {"a": "c" }
34
+ * ]
35
+ * ```
36
+ *
37
+ * Script:
38
+ *
39
+ * ```ini
40
+ * [FILESave]
41
+ * location = /tmp
42
+ * identifier = toto
43
+ * ```
44
+ *
45
+ * Output:
46
+ *
47
+ * ```json
48
+ * ["/tmp/truc.json"]
49
+ * ```
50
+ *
51
+ * @name FILESave
52
+ * @param {String} [location=TMPDIR] Directory location
53
+ * @param {Number} [identifier] File name
54
+ * @returns {Object}
55
+ */
56
+ async function FILESave(data, feed) {
57
+ if (!this.handle) {
58
+ const identifier = String(this.getParam('identifier'));
59
+ const location = this.getParam('location', (0, _os.tmpdir)());
60
+
61
+ if (!_pathExists.default.sync(location)) {
62
+ _makeDir.default.sync(location);
63
+ }
64
+
65
+ this.filename = _path.default.resolve(location, identifier);
66
+ this.handle = (0, _fs.createWriteStream)(this.filename);
67
+ }
68
+
69
+ if (this.isLast()) {
70
+ this.handle.close();
71
+ return (0, _fs.lstat)(this.filename, (err, stat) => {
72
+ feed.write({
73
+ filename: this.filename,
74
+ ...stat
75
+ });
76
+ return feed.close();
77
+ });
78
+ }
79
+
80
+ (0, _streamWrite.default)(this.handle, Buffer.from(String(data)), () => feed.end());
81
+ }
package/lib/index.js CHANGED
@@ -53,6 +53,8 @@ var _zipExtract = _interopRequireDefault(require("./zip-extract"));
53
53
 
54
54
  var _iniString = _interopRequireDefault(require("./ini-string"));
55
55
 
56
+ var _fileSave = _interopRequireDefault(require("./file-save"));
57
+
56
58
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
57
59
 
58
60
  const funcs = {
@@ -80,6 +82,7 @@ const funcs = {
80
82
  TXTZip: _txtZip.default,
81
83
  ZIPExtract: _zipExtract.default,
82
84
  INIString: _iniString.default,
85
+ FILESave: _fileSave.default,
83
86
  // aliases
84
87
  bufferify: _bufObject.default.BUFObject,
85
88
  concat: _txtConcat.default.TXTConcat,
package/lib/request.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _fetchWithProxy = _interopRequireDefault(require("fetch-with-proxy"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ const request = (url, parameters) => async () => {
13
+ const response = await (0, _fetchWithProxy.default)(url, parameters);
14
+
15
+ if (!response.ok) {
16
+ throw new Error(response.statusText);
17
+ }
18
+
19
+ return response;
20
+ };
21
+
22
+ var _default = request;
23
+ exports.default = _default;
@@ -13,10 +13,12 @@ var _streamWrite = _interopRequireDefault(require("stream-write"));
13
13
 
14
14
  var _nodeAbortController = _interopRequireDefault(require("node-abort-controller"));
15
15
 
16
- var _fetchWithProxy = _interopRequireDefault(require("fetch-with-proxy"));
17
-
18
16
  var _parseHeaders = _interopRequireDefault(require("parse-headers"));
19
17
 
18
+ var _asyncRetry = _interopRequireDefault(require("async-retry"));
19
+
20
+ var _request = _interopRequireDefault(require("./request"));
21
+
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
23
 
22
24
  /**
@@ -31,10 +33,12 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
31
33
  * @param {String} [json=false] Parse as JSON the content of URL
32
34
  * @param {Number} [timeout=1000] Timeout in milliseconds
33
35
  * @param {Boolean} [noerror=false] Ignore all errors
36
+ * @param {Number} [retries=5] The maximum amount of times to retry the connection
34
37
  * @returns {Object}
35
38
  */
36
- function URLConnect(data, feed) {
39
+ async function URLConnect(data, feed) {
37
40
  const url = this.getParam('url');
41
+ const retries = Number(this.getParam('retries', 5));
38
42
  const noerror = Boolean(this.getParam('noerror', false));
39
43
  const json = this.getParam('json', true);
40
44
  const {
@@ -46,29 +50,23 @@ function URLConnect(data, feed) {
46
50
  const headers = (0, _parseHeaders.default)([].concat(this.getParam('header')).filter(Boolean).join('\n'));
47
51
  const controller = new _nodeAbortController.default();
48
52
  this.input = ezs.createStream(ezs.objectMode());
49
- this.whenReady = (0, _fetchWithProxy.default)(url, {
53
+ const output = ezs.createStream(ezs.objectMode());
54
+ this.whenFinish = feed.flow(output);
55
+ (0, _streamWrite.default)(this.input, data, () => feed.end());
56
+ const bodyIn = this.input.pipe(ezs('dump')).pipe(ezs.toBuffer());
57
+ const parameters = {
50
58
  method: 'POST',
51
- body: this.input.pipe(ezs('dump')).pipe(ezs.toBuffer()),
59
+ body: bodyIn,
52
60
  timeout,
53
61
  headers,
54
62
  signal: controller.signal
55
- }).then(({
56
- body,
57
- status,
58
- statusText
59
- }) => {
60
- if (status !== 200) {
61
- const msg = `Received status code ${status} (${statusText})`;
62
- throw new Error(msg);
63
- }
63
+ };
64
+ const options = {
65
+ retries
66
+ };
64
67
 
65
- const output = json ? body.pipe(_JSONStream.default.parse('*')) : body;
66
- output.once('error', () => controller.abort());
67
- this.whenFinish = feed.flow(output);
68
- return Promise.resolve(true);
69
- }).catch(e => {
68
+ const onError = e => {
70
69
  controller.abort();
71
- this.whenFinish = Promise.resolve(true);
72
70
 
73
71
  if (!noerror) {
74
72
  (0, _debug.default)('ezs')(`Break item #${this.getIndex()} [URLConnect] <${e}>`);
@@ -77,13 +75,26 @@ function URLConnect(data, feed) {
77
75
  (0, _debug.default)('ezs')(`Ignore item #${this.getIndex()} [URLConnect] <${e}>`);
78
76
  }
79
77
 
80
- return Promise.resolve(true);
81
- });
78
+ output.end();
79
+ };
80
+
81
+ try {
82
+ const response = await (0, _asyncRetry.default)((0, _request.default)(url, parameters), options);
83
+ const bodyOut = json ? response.body.pipe(_JSONStream.default.parse('*')) : response.body;
84
+ bodyOut.once('error', onError);
85
+ bodyOut.pipe(output);
86
+ } catch (e) {
87
+ onError(e);
88
+ }
89
+
90
+ ;
91
+ return;
82
92
  }
83
93
 
84
94
  if (this.isLast()) {
85
- this.whenReady.finally(() => this.whenFinish.finally(() => feed.close()));
86
- return this.input.end();
95
+ this.input.end();
96
+ this.whenFinish.finally(() => feed.close());
97
+ return;
87
98
  }
88
99
 
89
100
  (0, _streamWrite.default)(this.input, data, () => feed.end());
package/lib/url-fetch.js CHANGED
@@ -13,10 +13,12 @@ var _lodash2 = _interopRequireDefault(require("lodash.set"));
13
13
 
14
14
  var _nodeAbortController = _interopRequireDefault(require("node-abort-controller"));
15
15
 
16
- var _fetchWithProxy = _interopRequireDefault(require("fetch-with-proxy"));
17
-
18
16
  var _parseHeaders = _interopRequireDefault(require("parse-headers"));
19
17
 
18
+ var _asyncRetry = _interopRequireDefault(require("async-retry"));
19
+
20
+ var _request = _interopRequireDefault(require("./request"));
21
+
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
23
 
22
24
  /**
@@ -32,6 +34,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
32
34
  * @param {Number} [timeout=1000] timeout in milliseconds
33
35
  * @param {String} [mimetype="application/json"] mimetype for value of path (if presents)
34
36
  * @param {Boolean} [noerror=false] ignore all errors, the target field will remain undefined
37
+ * @param {Number} [retries=5] The maximum amount of times to retry the connection
35
38
  * @returns {Object}
36
39
  */
37
40
  async function URLFetch(data, feed) {
@@ -43,6 +46,7 @@ async function URLFetch(data, feed) {
43
46
  const path = this.getParam('path');
44
47
  const target = this.getParam('target');
45
48
  const json = Boolean(this.getParam('json', false));
49
+ const retries = Number(this.getParam('retries', 5));
46
50
  const noerror = Boolean(this.getParam('noerror', false));
47
51
  const timeout = Number(this.getParam('timeout')) || 1000;
48
52
  const headers = (0, _parseHeaders.default)([].concat(this.getParam('header')).filter(Boolean).join('\n'));
@@ -55,6 +59,9 @@ async function URLFetch(data, feed) {
55
59
  headers,
56
60
  signal: controller.signal
57
61
  };
62
+ const options = {
63
+ retries
64
+ };
58
65
 
59
66
  if (body) {
60
67
  (0, _lodash2.default)(parameters, 'method', 'POST');
@@ -63,13 +70,7 @@ async function URLFetch(data, feed) {
63
70
  }
64
71
 
65
72
  try {
66
- const response = await (0, _fetchWithProxy.default)(url, parameters);
67
-
68
- if (!response.ok) {
69
- const msg = `Received status code ${response.status} (${response.statusText})`;
70
- throw new Error(msg);
71
- }
72
-
73
+ const response = await (0, _asyncRetry.default)((0, _request.default)(url, parameters), options);
73
74
  const func = json ? 'json' : 'text';
74
75
  const value = await response[func]();
75
76
 
package/lib/url-stream.js CHANGED
@@ -13,10 +13,12 @@ var _nodeAbortController = _interopRequireDefault(require("node-abort-controller
13
13
 
14
14
  var _JSONStream = _interopRequireDefault(require("JSONStream"));
15
15
 
16
- var _fetchWithProxy = _interopRequireDefault(require("fetch-with-proxy"));
17
-
18
16
  var _parseHeaders = _interopRequireDefault(require("parse-headers"));
19
17
 
18
+ var _asyncRetry = _interopRequireDefault(require("async-retry"));
19
+
20
+ var _request = _interopRequireDefault(require("./request"));
21
+
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
23
 
22
24
  /**
@@ -82,6 +84,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
82
84
  * @param {String} [path="*"] choose the path to split JSON result
83
85
  * @param {Number} [timeout=1000] Timeout in milliseconds
84
86
  * @param {Boolean} [noerror=false] Ignore all errors, the target field will remain undefined
87
+ * @param {Number} [retries=5] The maximum amount of times to retry the connection
85
88
  * @returns {Object}
86
89
  */
87
90
  async function URLStream(data, feed) {
@@ -91,32 +94,26 @@ async function URLStream(data, feed) {
91
94
 
92
95
  const url = this.getParam('url');
93
96
  const path = this.getParam('path', '*');
97
+ const retries = Number(this.getParam('retries', 5));
94
98
  const noerror = Boolean(this.getParam('noerror', false));
95
99
  const timeout = Number(this.getParam('timeout')) || 1000;
96
100
  const headers = (0, _parseHeaders.default)([].concat(this.getParam('header')).filter(Boolean).join('\n'));
97
101
  const cURL = new _url.URL(url || data);
98
102
  const controller = new _nodeAbortController.default();
103
+ const parameters = {
104
+ timeout,
105
+ headers,
106
+ signal: controller.signal
107
+ };
108
+ const options = {
109
+ retries
110
+ };
99
111
 
100
112
  if (url) {
101
113
  cURL.search = new _url.URLSearchParams(data);
102
114
  }
103
115
 
104
- try {
105
- const response = await (0, _fetchWithProxy.default)(cURL.href, {
106
- timeout,
107
- headers,
108
- signal: controller.signal
109
- });
110
-
111
- if (!response.ok) {
112
- const msg = `Received status code ${response.status} (${response.statusText})`;
113
- throw new Error(msg);
114
- }
115
-
116
- const output = path ? response.body.pipe(_JSONStream.default.parse(path)) : response.body;
117
- output.once('error', () => controller.abort());
118
- await feed.flow(output);
119
- } catch (e) {
116
+ const onError = e => {
120
117
  controller.abort();
121
118
 
122
119
  if (noerror) {
@@ -126,5 +123,14 @@ async function URLStream(data, feed) {
126
123
 
127
124
  (0, _debug.default)('ezs')(`Break item #${this.getIndex()} [URLStream] <${e}>`);
128
125
  return feed.send(e);
126
+ };
127
+
128
+ try {
129
+ const response = await (0, _asyncRetry.default)((0, _request.default)(cURL.href, parameters), options);
130
+ const output = path ? response.body.pipe(_JSONStream.default.parse(path)) : response.body;
131
+ output.once('error', onError);
132
+ await feed.flow(output);
133
+ } catch (e) {
134
+ onError(e);
129
135
  }
130
136
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ezs/basics",
3
3
  "description": "Basics statements for EZS",
4
- "version": "1.16.0",
4
+ "version": "1.18.0",
5
5
  "author": "Nicolas Thouvenin <nthouvenin@gmail.com>",
6
6
  "bugs": "https://github.com/Inist-CNRS/ezs/issues",
7
7
  "dependencies": {
8
8
  "JSONStream": "1.3.5",
9
+ "async-retry": "1.3.3",
9
10
  "better-https-proxy-agent": "1.0.9",
10
11
  "csv-string": "3.2.0",
11
12
  "debug": "4.3.3",
@@ -17,9 +18,11 @@
17
18
  "lodash.mapvalues": "4.6.0",
18
19
  "lodash.set": "4.3.2",
19
20
  "lodash.zipobject": "4.1.3",
21
+ "make-dir": "3.1.0",
20
22
  "micromatch": "4.0.4",
21
23
  "node-abort-controller": "1.1.0",
22
24
  "parse-headers": "2.0.4",
25
+ "path-exists": "4.0.0",
23
26
  "stream-write": "1.0.1",
24
27
  "tmp-filepath": "2.0.0",
25
28
  "unzipper": "0.10.11",
@@ -33,7 +36,7 @@
33
36
  "directories": {
34
37
  "test": "test"
35
38
  },
36
- "gitHead": "b0ced7e413e748195400608f9d3dc33d4487f112",
39
+ "gitHead": "346fbfb891990dda7dd2d445e1f32ab2276c7020",
37
40
  "homepage": "https://github.com/Inist-CNRS/ezs/tree/master/packages/basics#readme",
38
41
  "keywords": [
39
42
  "ezs"