@ezs/basics
Version:
Basics statements for EZS
179 lines (158 loc) • 4.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = URLPager;
var _debug = _interopRequireDefault(require("debug"));
var _url = require("url");
var _nodeAbortController = _interopRequireDefault(require("node-abort-controller"));
var _lodash = _interopRequireDefault(require("lodash.get"));
var _parseHeaders = _interopRequireDefault(require("parse-headers"));
var _asyncRetry = _interopRequireDefault(require("async-retry"));
var _request = _interopRequireDefault(require("./request"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Take `Object` as parameters of URL, throw each chunk from the result
*
*
* Input:
*
* ```json
* [{"q": "a"}]
* ```
*
* Script:
*
* ```ini
* [URLPager]
* url = https://api.search.net
* path = total
* ```
*
* Output:
*
* ```json
* [
* {
* "q": "a",
* "total": 22
* "offset": 0,
* "pageNumber": 1,
* "totalPages", 3,
* "maxPages": 1000,
* "limit": 10
* },
* {
* "q": "a",
* "total": 22
* "offset": 10,
* "pageNumber": 2,
* "totalPages", 3,
* "maxPages": 1000,
* "limit": 10
* },
* {
* "q": "a",
* "total": 22
* "offset": 20,
* "pageNumber": 3,
* "totalPages", 3,
* "maxPages": 1000,
* "limit": 10
* }
* ]
* ```
*
* #### Example with URLs
*
* Input:
*
* ```json
* [
* "https://httpbin.org/get?a=a",
* "https://httpbin.org/get?a=b",
* "https://httpbin.org/get?a=c"
* ]
* ```
*
* Script:
*
* ```ini
* [URLPager]
* path = .args
* ```
*
* Output:
*
* ```json
* [{"a": "a"}, {"a": "b"}, {"a": "c" }]
* ```
*
* @name URLPager
* @param {String} [url] URL to fetch (by default input string is taken)
* @param {String} [path=total] choose the path to find the number of result
* @param {Number} [timeout=1000] Timeout in milliseconds
* @param {Boolean} [noerror=false] Ignore all errors, the target field will remain undefined
* @param {Number} [retries=5] The maximum amount of times to retry the connection
* @returns {Object}
*/
async function URLPager(data, feed) {
if (this.isLast()) {
return feed.close();
}
const url = this.getParam('url');
const path = this.getParam('path', 'total');
const limit = Number(this.getParam('limit', 10));
const maxPages = Number(this.getParam('maxPages', 1000));
const retries = Number(this.getParam('retries', 5));
const noerror = Boolean(this.getParam('noerror', false));
const timeout = Number(this.getParam('timeout')) || 1000;
const headers = (0, _parseHeaders.default)([].concat(this.getParam('header')).filter(Boolean).join('\n'));
const cURL = new _url.URL(url || data);
const controller = new _nodeAbortController.default();
const parameters = {
timeout,
headers,
signal: controller.signal
};
const options = {
retries
};
cURL.search = new _url.URLSearchParams(data);
const onError = e => {
controller.abort();
if (noerror) {
(0, _debug.default)('ezs')(`Ignore item #${this.getIndex()} [URLPager] <${e}>`);
return feed.send(data);
}
(0, _debug.default)('ezs')(`Break item #${this.getIndex()} [URLPager] <${e}>`);
return feed.send(e);
};
try {
const response = await (0, _asyncRetry.default)((0, _request.default)(cURL.href, parameters), options);
const json = await response.json();
const total = (0, _lodash.default)(json, path);
if (total === 0) {
return onError(new Error('No result.'));
}
if (total === undefined) {
return onError(new Error('Unexpected response.'));
}
let totalPages = Math.ceil(json.total / limit);
if (totalPages > maxPages) {
totalPages = maxPages;
}
for (let pageNumber = 1; pageNumber <= totalPages; pageNumber += 1) {
feed.write({ ...data,
offset: (pageNumber - 1) * limit,
pageNumber,
totalPages,
maxPages,
limit
});
}
feed.end();
} catch (e) {
onError(e);
}
}