rekwest 3.0.1 → 3.2.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/README.md +3 -3
- package/dist/helpers.js +7 -5
- package/dist/index.js +20 -11
- package/package.json +9 -7
- package/src/helpers.mjs +7 -5
- package/src/index.mjs +12 -10
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ and [http2.request](https://nodejs.org/api/http2.html#http2_clienthttp2session_r
|
|
|
7
7
|
## Abstract
|
|
8
8
|
|
|
9
9
|
* Fetch-alike
|
|
10
|
-
* Cool-beans config options (with defaults)
|
|
10
|
+
* Cool-beans 🫐 config options (with defaults)
|
|
11
11
|
* Automatic HTTP/2 support (ALPN negotiation)
|
|
12
12
|
* Automatic or opt-in body parse (with non-UTF-8 charset decoding)
|
|
13
13
|
* Automatic and simplistic `Cookies` treatment (with built-in jar)
|
|
@@ -121,8 +121,8 @@ console.log(res.body);
|
|
|
121
121
|
& [http2.ClientSessionRequestOptions](https://nodejs.org/api/http2.html#http2_clienthttp2session_request_headers_options)
|
|
122
122
|
and [tls.ConnectionOptions](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
|
|
123
123
|
for HTTP/2 attunes
|
|
124
|
-
* `body` **{string | Array |
|
|
125
|
-
|
|
124
|
+
* `body` **{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File |
|
|
125
|
+
FormData | Iterator | Object | Readable | SharedArrayBuffer | URLSearchParams}** The body to send with the request
|
|
126
126
|
* `cookies` **{boolean | Array<[k, v]> | Cookies | Object | URLSearchParams}** `Default: true` The cookies to add to
|
|
127
127
|
the request
|
|
128
128
|
* `digest` **{boolean}** `Default: true` Controls whether to read the response stream or simply add a mixin
|
package/dist/helpers.js
CHANGED
|
@@ -126,10 +126,6 @@ const dispatch = (req, {
|
|
|
126
126
|
body,
|
|
127
127
|
headers
|
|
128
128
|
}) => {
|
|
129
|
-
if (_util.types.isUint8Array(body)) {
|
|
130
|
-
return req.end(body);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
129
|
if (body === Object(body) && !Buffer.isBuffer(body)) {
|
|
134
130
|
if (body.pipe?.constructor !== Function && (Reflect.has(body, Symbol.asyncIterator) || Reflect.has(body, Symbol.iterator))) {
|
|
135
131
|
body = _stream.Readable.from(body);
|
|
@@ -350,6 +346,12 @@ async function* tap(value) {
|
|
|
350
346
|
const transform = (body, options) => {
|
|
351
347
|
let headers = {};
|
|
352
348
|
|
|
349
|
+
if (_util.types.isAnyArrayBuffer(body) && !Buffer.isBuffer(body)) {
|
|
350
|
+
body = Buffer.from(body);
|
|
351
|
+
} else if (_util.types.isArrayBufferView(body) && !Buffer.isBuffer(body)) {
|
|
352
|
+
body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
|
|
353
|
+
}
|
|
354
|
+
|
|
353
355
|
if (_file.File.alike(body)) {
|
|
354
356
|
headers = {
|
|
355
357
|
[HTTP2_HEADER_CONTENT_LENGTH]: body.size,
|
|
@@ -374,7 +376,7 @@ const transform = (body, options) => {
|
|
|
374
376
|
body = JSON.stringify(body);
|
|
375
377
|
}
|
|
376
378
|
|
|
377
|
-
if (
|
|
379
|
+
if (Buffer.isBuffer(body) || body !== Object(body)) {
|
|
378
380
|
if (options.headers[HTTP2_HEADER_CONTENT_ENCODING]) {
|
|
379
381
|
body = compress(body, options.headers[HTTP2_HEADER_CONTENT_ENCODING]);
|
|
380
382
|
}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.default = rekwest;
|
|
|
9
9
|
|
|
10
10
|
var _http = _interopRequireDefault(require("http"));
|
|
11
11
|
|
|
12
|
-
var _http2 =
|
|
12
|
+
var _http2 = _interopRequireWildcard(require("http2"));
|
|
13
13
|
|
|
14
14
|
exports.constants = _http2.constants;
|
|
15
15
|
|
|
@@ -73,6 +73,10 @@ Object.keys(_formdata).forEach(function (key) {
|
|
|
73
73
|
exports[key] = _formdata[key];
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
77
|
+
|
|
78
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
79
|
+
|
|
76
80
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
77
81
|
|
|
78
82
|
const {
|
|
@@ -199,14 +203,14 @@ async function rekwest(url, options = {}) {
|
|
|
199
203
|
|
|
200
204
|
if (follow && /^3\d{2}$/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
201
205
|
if (redirect === _helpers.redirects.error) {
|
|
202
|
-
res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
|
|
206
|
+
return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
|
|
203
207
|
}
|
|
204
208
|
|
|
205
209
|
if (redirect === _helpers.redirects.follow) {
|
|
206
210
|
options.url = new URL(res.headers[HTTP2_HEADER_LOCATION], url).href;
|
|
207
211
|
|
|
208
212
|
if (res.statusCode !== HTTP_STATUS_SEE_OTHER && body === Object(body) && body.pipe?.constructor === Function) {
|
|
209
|
-
res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with body
|
|
213
|
+
return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
|
|
210
214
|
}
|
|
211
215
|
|
|
212
216
|
options.follow--;
|
|
@@ -224,7 +228,7 @@ async function rekwest(url, options = {}) {
|
|
|
224
228
|
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
225
229
|
|
|
226
230
|
if (interval > options.maxRetryAfter) {
|
|
227
|
-
res.emit('error', maxRetryAfterError(interval, {
|
|
231
|
+
return res.emit('error', maxRetryAfterError(interval, {
|
|
228
232
|
cause: (0, _helpers.mixin)(res, options)
|
|
229
233
|
}));
|
|
230
234
|
}
|
|
@@ -256,26 +260,31 @@ async function rekwest(url, options = {}) {
|
|
|
256
260
|
|
|
257
261
|
return res;
|
|
258
262
|
} catch (ex) {
|
|
259
|
-
|
|
263
|
+
const {
|
|
264
|
+
maxRetryAfter,
|
|
265
|
+
retry
|
|
266
|
+
} = options;
|
|
267
|
+
|
|
268
|
+
if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
|
|
260
269
|
let {
|
|
261
270
|
interval
|
|
262
|
-
} =
|
|
271
|
+
} = retry;
|
|
263
272
|
|
|
264
|
-
if (
|
|
273
|
+
if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
265
274
|
interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
266
275
|
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
267
276
|
|
|
268
|
-
if (interval >
|
|
277
|
+
if (interval > maxRetryAfter) {
|
|
269
278
|
throw maxRetryAfterError(interval, {
|
|
270
279
|
cause: ex
|
|
271
280
|
});
|
|
272
281
|
}
|
|
273
282
|
} else {
|
|
274
|
-
interval = new Function('interval', `return Math.ceil(${
|
|
283
|
+
interval = new Function('interval', `return Math.ceil(${retry.backoffStrategy});`)(interval);
|
|
275
284
|
}
|
|
276
285
|
|
|
277
|
-
|
|
278
|
-
|
|
286
|
+
retry.attempts--;
|
|
287
|
+
retry.interval = interval;
|
|
279
288
|
return (0, _promises.setTimeout)(interval).then(() => rekwest(url, options));
|
|
280
289
|
}
|
|
281
290
|
|
package/package.json
CHANGED
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@babel/cli": "^7.17.6",
|
|
12
|
-
"@babel/core": "^7.17.
|
|
12
|
+
"@babel/core": "^7.17.9",
|
|
13
13
|
"@babel/eslint-parser": "^7.17.0",
|
|
14
14
|
"@babel/preset-env": "^7.16.11",
|
|
15
|
-
"c8": "^7.11.
|
|
16
|
-
"eslint": "^8.
|
|
17
|
-
"eslint-config-ultra-refined": "^2.
|
|
18
|
-
"mocha": "^9.2.
|
|
15
|
+
"c8": "^7.11.2",
|
|
16
|
+
"eslint": "^8.14.0",
|
|
17
|
+
"eslint-config-ultra-refined": "^2.5.0",
|
|
18
|
+
"mocha": "^9.2.2"
|
|
19
19
|
},
|
|
20
20
|
"description": "The robust request library that humanity deserves 🌐",
|
|
21
21
|
"engines": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"homepage": "https://github.com/bricss/rekwest#readme",
|
|
33
33
|
"keywords": [
|
|
34
|
+
"backoff",
|
|
34
35
|
"fetch",
|
|
35
36
|
"fetch-alike",
|
|
36
37
|
"formdata",
|
|
@@ -40,7 +41,8 @@
|
|
|
40
41
|
"h2c",
|
|
41
42
|
"http2",
|
|
42
43
|
"multipart",
|
|
43
|
-
"request"
|
|
44
|
+
"request",
|
|
45
|
+
"retry"
|
|
44
46
|
],
|
|
45
47
|
"license": "MIT",
|
|
46
48
|
"main": "./dist/index.js",
|
|
@@ -60,5 +62,5 @@
|
|
|
60
62
|
"test:bail": "mocha --bail",
|
|
61
63
|
"test:cover": "c8 --include=src --reporter=lcov --reporter=text npm test"
|
|
62
64
|
},
|
|
63
|
-
"version": "3.0
|
|
65
|
+
"version": "3.2.0"
|
|
64
66
|
}
|
package/src/helpers.mjs
CHANGED
|
@@ -109,10 +109,6 @@ export const decompress = (buf, encoding, { async = false } = {}) => {
|
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
export const dispatch = (req, { body, headers }) => {
|
|
112
|
-
if (types.isUint8Array(body)) {
|
|
113
|
-
return req.end(body);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
112
|
if (body === Object(body) && !Buffer.isBuffer(body)) {
|
|
117
113
|
if (body.pipe?.constructor !== Function
|
|
118
114
|
&& (Reflect.has(body, Symbol.asyncIterator) || Reflect.has(body, Symbol.iterator))) {
|
|
@@ -333,6 +329,12 @@ export async function* tap(value) {
|
|
|
333
329
|
export const transform = (body, options) => {
|
|
334
330
|
let headers = {};
|
|
335
331
|
|
|
332
|
+
if (types.isAnyArrayBuffer(body) && !Buffer.isBuffer(body)) {
|
|
333
|
+
body = Buffer.from(body);
|
|
334
|
+
} else if (types.isArrayBufferView(body) && !Buffer.isBuffer(body)) {
|
|
335
|
+
body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
|
|
336
|
+
}
|
|
337
|
+
|
|
336
338
|
if (File.alike(body)) {
|
|
337
339
|
headers = {
|
|
338
340
|
[HTTP2_HEADER_CONTENT_LENGTH]: body.size,
|
|
@@ -352,7 +354,7 @@ export const transform = (body, options) => {
|
|
|
352
354
|
body = JSON.stringify(body);
|
|
353
355
|
}
|
|
354
356
|
|
|
355
|
-
if (
|
|
357
|
+
if (Buffer.isBuffer(body) || body !== Object(body)) {
|
|
356
358
|
if (options.headers[HTTP2_HEADER_CONTENT_ENCODING]) {
|
|
357
359
|
body = compress(body, options.headers[HTTP2_HEADER_CONTENT_ENCODING]);
|
|
358
360
|
}
|
package/src/index.mjs
CHANGED
|
@@ -149,7 +149,7 @@ export default async function rekwest(url, options = {}) {
|
|
|
149
149
|
|
|
150
150
|
if (follow && /^3\d{2}$/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
151
151
|
if (redirect === redirects.error) {
|
|
152
|
-
res.emit('error', new RequestError(`Unexpected redirect, redirect mode is set to '${ redirect }'.`));
|
|
152
|
+
return res.emit('error', new RequestError(`Unexpected redirect, redirect mode is set to '${ redirect }'.`));
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
if (redirect === redirects.follow) {
|
|
@@ -157,7 +157,7 @@ export default async function rekwest(url, options = {}) {
|
|
|
157
157
|
|
|
158
158
|
if (res.statusCode !== HTTP_STATUS_SEE_OTHER
|
|
159
159
|
&& body === Object(body) && body.pipe?.constructor === Function) {
|
|
160
|
-
res.emit('error', new RequestError(`Unable to ${ redirect } redirect with body
|
|
160
|
+
return res.emit('error', new RequestError(`Unable to ${ redirect } redirect with streamable body.`));
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
options.follow--;
|
|
@@ -176,7 +176,7 @@ export default async function rekwest(url, options = {}) {
|
|
|
176
176
|
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
177
177
|
|
|
178
178
|
if (interval > options.maxRetryAfter) {
|
|
179
|
-
res.emit('error', maxRetryAfterError(interval, { cause: mixin(res, options) }));
|
|
179
|
+
return res.emit('error', maxRetryAfterError(interval, { cause: mixin(res, options) }));
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
return setTimeoutPromise(interval).then(() => rekwest(options.url, options).then(resolve, reject));
|
|
@@ -205,21 +205,23 @@ export default async function rekwest(url, options = {}) {
|
|
|
205
205
|
|
|
206
206
|
return res;
|
|
207
207
|
} catch (ex) {
|
|
208
|
-
|
|
209
|
-
let { interval } = options.retry;
|
|
208
|
+
const { maxRetryAfter, retry } = options;
|
|
210
209
|
|
|
211
|
-
|
|
210
|
+
if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
|
|
211
|
+
let { interval } = retry;
|
|
212
|
+
|
|
213
|
+
if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
212
214
|
interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
213
215
|
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
214
|
-
if (interval >
|
|
216
|
+
if (interval > maxRetryAfter) {
|
|
215
217
|
throw maxRetryAfterError(interval, { cause: ex });
|
|
216
218
|
}
|
|
217
219
|
} else {
|
|
218
|
-
interval = new Function('interval', `return Math.ceil(${
|
|
220
|
+
interval = new Function('interval', `return Math.ceil(${ retry.backoffStrategy });`)(interval);
|
|
219
221
|
}
|
|
220
222
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
retry.attempts--;
|
|
224
|
+
retry.interval = interval;
|
|
223
225
|
|
|
224
226
|
return setTimeoutPromise(interval).then(() => rekwest(url, options));
|
|
225
227
|
}
|