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 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 | AsyncIterator | Blob | Buffer | File | FromData | Iterator | Object | Readable |
125
- Uint8Array | URLSearchParams}** The body to send with the request
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 (_util.types.isUint8Array(body) || Buffer.isBuffer(body) || body !== Object(body)) {
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 = _interopRequireDefault(require("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 as readable stream.`));
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
- if (options.retry?.attempts && options.retry?.statusCodes.includes(ex.statusCode)) {
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
- } = options.retry;
271
+ } = retry;
263
272
 
264
- if (options.retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
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 > options.maxRetryAfter) {
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(${options.retry.backoffStrategy});`)(interval);
283
+ interval = new Function('interval', `return Math.ceil(${retry.backoffStrategy});`)(interval);
275
284
  }
276
285
 
277
- options.retry.attempts--;
278
- options.retry.interval = interval;
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.5",
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.0",
16
- "eslint": "^8.10.0",
17
- "eslint-config-ultra-refined": "^2.4.1",
18
- "mocha": "^9.2.1"
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.1"
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 (types.isUint8Array(body) || Buffer.isBuffer(body) || body !== Object(body)) {
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 as readable stream.`));
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
- if (options.retry?.attempts && options.retry?.statusCodes.includes(ex.statusCode)) {
209
- let { interval } = options.retry;
208
+ const { maxRetryAfter, retry } = options;
210
209
 
211
- if (options.retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
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 > options.maxRetryAfter) {
216
+ if (interval > maxRetryAfter) {
215
217
  throw maxRetryAfterError(interval, { cause: ex });
216
218
  }
217
219
  } else {
218
- interval = new Function('interval', `return Math.ceil(${ options.retry.backoffStrategy });`)(interval);
220
+ interval = new Function('interval', `return Math.ceil(${ retry.backoffStrategy });`)(interval);
219
221
  }
220
222
 
221
- options.retry.attempts--;
222
- options.retry.interval = interval;
223
+ retry.attempts--;
224
+ retry.interval = interval;
223
225
 
224
226
  return setTimeoutPromise(interval).then(() => rekwest(url, options));
225
227
  }