rekwest 6.2.0 → 7.0.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.
Files changed (45) hide show
  1. package/README.md +11 -10
  2. package/dist/codecs.cjs +55 -0
  3. package/dist/{config.js → config.cjs} +15 -19
  4. package/dist/{cookies.js → cookies.cjs} +2 -2
  5. package/dist/{formdata.js → formdata.cjs} +8 -11
  6. package/dist/{index.js → index.cjs} +27 -15
  7. package/dist/{mixin.js → mixin.cjs} +22 -17
  8. package/dist/postflight.cjs +60 -0
  9. package/dist/{preflight.js → preflight.cjs} +11 -9
  10. package/dist/redirects.cjs +63 -0
  11. package/dist/retries.cjs +57 -0
  12. package/dist/{transfer.js → transfer.cjs} +13 -40
  13. package/dist/transform.cjs +105 -0
  14. package/dist/utils.cjs +140 -0
  15. package/dist/{validation.js → validation.cjs} +1 -1
  16. package/package.json +15 -14
  17. package/src/{ackn.mjs → ackn.js} +33 -33
  18. package/src/codecs.js +55 -0
  19. package/src/{config.mjs → config.js} +88 -93
  20. package/src/{constants.mjs → constants.js} +29 -29
  21. package/src/{cookies.mjs → cookies.js} +100 -100
  22. package/src/{formdata.mjs → formdata.js} +8 -14
  23. package/src/{index.mjs → index.js} +22 -22
  24. package/src/{mediatypes.mjs → mediatypes.js} +6 -6
  25. package/src/{mixin.mjs → mixin.js} +25 -26
  26. package/src/postflight.js +56 -0
  27. package/src/{preflight.mjs → preflight.js} +100 -91
  28. package/src/redirects.js +79 -0
  29. package/src/retries.js +51 -0
  30. package/src/transfer.js +92 -0
  31. package/src/transform.js +109 -0
  32. package/src/utils.js +152 -0
  33. package/src/{validation.mjs → validation.js} +33 -33
  34. package/dist/postflight.js +0 -117
  35. package/dist/transform.js +0 -79
  36. package/dist/utils.js +0 -188
  37. package/src/postflight.mjs +0 -136
  38. package/src/transfer.mjs +0 -121
  39. package/src/transform.mjs +0 -82
  40. package/src/utils.mjs +0 -205
  41. /package/dist/{ackn.js → ackn.cjs} +0 -0
  42. /package/dist/{constants.js → constants.cjs} +0 -0
  43. /package/dist/{errors.js → errors.cjs} +0 -0
  44. /package/dist/{mediatypes.js → mediatypes.cjs} +0 -0
  45. /package/src/{errors.mjs → errors.js} +0 -0
package/README.md CHANGED
@@ -10,11 +10,12 @@ and [http2.request](https://nodejs.org/api/http2.html#clienthttp2sessionrequesth
10
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
- * Automatic and simplistic `Cookies` treatment (with built-in **jar** & **ttl**) 🍪
14
- * Automatic decompression (with opt-in body compression) 🗜️
13
+ * Automatic and simplistic `Cookies` treatment (with **TTL** support) 🍪
14
+ * Automatic body decoding (and opt-in request body encoding) 🗜️
15
+ * Better error management 🚥
15
16
  * Built-in streamable `FormData` interface 🔌
16
17
  * Support redirects & retries with fine-grained tune-ups 🪛
17
- * Support all legit request body types (include blobs & streams) 📦
18
+ * Support plenty request body types (include blobs & streams) 📦
18
19
  * Support both CJS and ESM module systems 🧩
19
20
  * Fully promise-able and pipe-able 🔗
20
21
  * Zero dependencies 🗽
@@ -47,7 +48,7 @@ const res = await rekwest(url, {
47
48
  body: { celestial: 'payload' },
48
49
  headers: {
49
50
  [HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',
50
- [HTTP2_HEADER_CONTENT_ENCODING]: 'br', // enables: body compression
51
+ [HTTP2_HEADER_CONTENT_ENCODING]: 'br', // enables: body encoding
51
52
  /** [HTTP2_HEADER_CONTENT_TYPE]
52
53
  * is undue for
53
54
  * Array/Blob/File/FormData/Object/URLSearchParams body types
@@ -99,7 +100,7 @@ const res = await rekwest(url, {
99
100
  body: fd,
100
101
  headers: {
101
102
  [HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',
102
- [HTTP2_HEADER_CONTENT_ENCODING]: 'zstd', // enables: body compression
103
+ [HTTP2_HEADER_CONTENT_ENCODING]: 'zstd', // enables: body encoding
103
104
  },
104
105
  method: HTTP2_METHOD_POST,
105
106
  });
@@ -120,21 +121,21 @@ console.log(res.body);
120
121
  & [http2.ClientSessionRequestOptions](https://nodejs.org/api/http2.html#clienthttp2sessionrequestheaders-options)
121
122
  and [tls.ConnectionOptions](https://nodejs.org/api/tls.html#tlsconnectoptions-callback)
122
123
  for HTTP/2 attunes
123
- * `compression` **{Object}** Configures compression options, e.g.: `brotliOptions`, `zstdOptions`,
124
- `zlibOptions`
125
124
  * `baseURL` **{string | URL}** The base URL to use in cases where `url` is a relative URL
126
125
  * `body` **{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File |
127
126
  FormData | Iterator | Object | Readable | ReadableStream | SharedArrayBuffer | URLSearchParams}** The body to send
128
127
  with the request
128
+ * `bufferBody` **{boolean}** `Default: false` Toggles the buffering of the streamable request bodies for redirects and
129
+ retries
129
130
  * `cookies` **{boolean | Array<[k, v]> | Array<string\> | Cookies | Object | URLSearchParams}** `Default: true` The
130
131
  cookies to add to
131
132
  the request
132
133
  * `cookiesTTL` **{boolean}** `Default: false` Controls enablement of TTL for the cookies cache
133
134
  * `credentials` **{include | omit | same-origin}** `Default: same-origin` Controls credentials in case of cross-origin
134
135
  redirects
135
- * `decompression` **{Object}** Configures decompression options, e.g.: `brotliOptions`, `zstdOptions`,
136
- `zlibOptions`
136
+ * `decodersOptions` **{Object}** Configures decoders options, e.g.: `brotli`, `zstd`, `zlib`
137
137
  * `digest` **{boolean}** `Default: true` Controls whether to read the response stream or add a mixin
138
+ * `encodersOptions` **{Object}** Configures encoders options, e.g.: `brotli`, `zstd`, `zlib`
138
139
  * `follow` **{number}** `Default: 20` The number of redirects to follow
139
140
  * `h2` **{boolean}** `Default: false` Forces the use of HTTP/2 protocol
140
141
  * `headers` **{Object}** The headers to add to the request
@@ -146,7 +147,7 @@ console.log(res.body);
146
147
  * `backoffStrategy` **{string}** `Default: interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)`
147
148
  The backoff strategy algorithm that increases logarithmically. To fixate set value to `interval * 1`
148
149
  * `errorCodes` **{string[]}**
149
- `Default: ['EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'EPIPE', 'ERR_HTTP2_STREAM_ERROR']`
150
+ `Default: ['ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'ERR_HTTP2_STREAM_ERROR']`
150
151
  The list of error codes to retry on
151
152
  * `interval` **{number}** `Default: 1e3` The initial retry interval
152
153
  * `retryAfter` **{boolean}** `Default: true` Controls `retry-after` header receptiveness
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.encodeCodecs = exports.encode = exports.decodeCodecs = exports.decode = void 0;
7
+ var _nodeStream = require("node:stream");
8
+ var _nodeZlib = _interopRequireDefault(require("node:zlib"));
9
+ var _config = require("./config.cjs");
10
+ var _utils = require("./utils.cjs");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ const decodeCodecs = exports.decodeCodecs = {
13
+ br: opts => _nodeZlib.default.createBrotliDecompress(opts?.brotli),
14
+ deflate: opts => _nodeZlib.default.createInflate(opts?.zlib),
15
+ 'deflate-raw': opts => _nodeZlib.default.createInflateRaw(opts?.zlib),
16
+ gzip: opts => _nodeZlib.default.createGunzip(opts?.zlib),
17
+ zstd: opts => _config.isZstdSupported && _nodeZlib.default.createZstdDecompress(opts?.zstd)
18
+ };
19
+ const decode = (readable, encodings = '', {
20
+ decodersOptions
21
+ } = {}) => {
22
+ const decoders = [];
23
+ encodings = (0, _utils.unwind)(encodings).reverse();
24
+ for (const encoding of encodings) {
25
+ const decoder = decodeCodecs[encoding]?.(decodersOptions);
26
+ if (!decoder) {
27
+ return readable;
28
+ }
29
+ decoders.push(decoder);
30
+ }
31
+ return (0, _nodeStream.pipeline)(readable, ...decoders, () => void 0);
32
+ };
33
+ exports.decode = decode;
34
+ const encodeCodecs = exports.encodeCodecs = {
35
+ br: opts => _nodeZlib.default.createBrotliCompress(opts?.brotli),
36
+ deflate: opts => _nodeZlib.default.createDeflate(opts?.zlib),
37
+ 'deflate-raw': opts => _nodeZlib.default.createDeflateRaw(opts?.zlib),
38
+ gzip: opts => _nodeZlib.default.createGzip(opts?.zlib),
39
+ zstd: opts => _config.isZstdSupported && _nodeZlib.default.createZstdCompress(opts?.zstd)
40
+ };
41
+ const encode = (readable, encodings = '', {
42
+ encodersOptions
43
+ } = {}) => {
44
+ const encoders = [];
45
+ encodings = (0, _utils.unwind)(encodings);
46
+ for (const encoding of encodings) {
47
+ const encoder = encodeCodecs[encoding]?.(encodersOptions);
48
+ if (!encoder) {
49
+ return readable;
50
+ }
51
+ encoders.push(encoder);
52
+ }
53
+ return (0, _nodeStream.pipeline)(readable, ...encoders, () => void 0);
54
+ };
55
+ exports.encode = encode;
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.isZstdSupported = exports.default = void 0;
7
7
  var _nodeHttp = _interopRequireDefault(require("node:http2"));
8
8
  var _nodeZlib = _interopRequireDefault(require("node:zlib"));
9
- var _constants = require("./constants");
10
- var _mediatypes = require("./mediatypes");
11
- var _utils = require("./utils");
9
+ var _constants = require("./constants.cjs");
10
+ var _mediatypes = require("./mediatypes.cjs");
12
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ const isZstdSupported = exports.isZstdSupported = !!_nodeZlib.default.constants.ZSTD_CLEVEL_DEFAULT;
13
13
  const {
14
14
  HTTP2_HEADER_ACCEPT,
15
15
  HTTP2_HEADER_ACCEPT_ENCODING,
@@ -20,36 +20,32 @@ const {
20
20
  HTTP_STATUS_SERVICE_UNAVAILABLE,
21
21
  HTTP_STATUS_TOO_MANY_REQUESTS
22
22
  } = _nodeHttp.default.constants;
23
- const isZstdSupported = exports.isZstdSupported = !!_nodeZlib.default.constants.ZSTD_CLEVEL_DEFAULT;
23
+ const timeout = 3e5;
24
24
  const defaults = {
25
- compression: {
26
- brotliOptions: {
25
+ bufferBody: false,
26
+ cookiesTTL: false,
27
+ credentials: _constants.requestCredentials.sameOrigin,
28
+ decodersOptions: {},
29
+ digest: true,
30
+ encodersOptions: {
31
+ brotli: {
27
32
  params: {
28
33
  [_nodeZlib.default.constants.BROTLI_PARAM_QUALITY]: 4
29
34
  }
30
35
  },
31
- zstdOptions: {
36
+ zstd: {
32
37
  params: {
33
38
  [_nodeZlib.default.constants.ZSTD_c_compressionLevel]: 6
34
39
  }
35
40
  }
36
41
  },
37
- cookiesTTL: false,
38
- credentials: _constants.requestCredentials.sameOrigin,
39
- decompression: {},
40
- digest: true,
41
42
  follow: 20,
42
43
  h2: false,
43
44
  headers: {
44
45
  [HTTP2_HEADER_ACCEPT]: `${_mediatypes.APPLICATION_JSON}, ${_mediatypes.TEXT_PLAIN}, ${_mediatypes.WILDCARD}`,
45
46
  [HTTP2_HEADER_ACCEPT_ENCODING]: `br,${isZstdSupported ? ' zstd, ' : ' '}gzip, deflate, deflate-raw`
46
47
  },
47
- get maxRetryAfter() {
48
- return this[_utils.maxRetryAfter] ?? this.timeout;
49
- },
50
- set maxRetryAfter(value) {
51
- this[_utils.maxRetryAfter] = value;
52
- },
48
+ maxRetryAfter: timeout,
53
49
  method: HTTP2_METHOD_GET,
54
50
  parse: true,
55
51
  redirect: _constants.requestRedirect.follow,
@@ -57,14 +53,14 @@ const defaults = {
57
53
  retry: {
58
54
  attempts: 0,
59
55
  backoffStrategy: 'interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)',
60
- errorCodes: ['EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'EPIPE', 'ERR_HTTP2_STREAM_ERROR'],
56
+ errorCodes: ['ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'ERR_HTTP2_STREAM_ERROR'],
61
57
  interval: 1e3,
62
58
  retryAfter: true,
63
59
  statusCodes: [HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_BAD_GATEWAY, HTTP_STATUS_SERVICE_UNAVAILABLE, HTTP_STATUS_GATEWAY_TIMEOUT]
64
60
  },
65
61
  stripTrailingSlash: false,
66
62
  thenable: false,
67
- timeout: 3e5,
63
+ timeout,
68
64
  trimTrailingSlashes: false
69
65
  };
70
66
  var _default = exports.default = {
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Cookies = void 0;
7
- var _utils = require("./utils");
7
+ var _utils = require("./utils.cjs");
8
8
  const lifetimeCap = 3456e7; // pragma: 400 days
9
9
 
10
10
  class Cookies extends URLSearchParams {
@@ -35,7 +35,7 @@ class Cookies extends URLSearchParams {
35
35
  const [cookie, ...attrs] = it.split(';').map(it => it.trim());
36
36
  const ttl = {};
37
37
  for (const val of attrs) {
38
- if (/(?:Expires|Max-Age)=/i.test(val)) {
38
+ if (/(?:expires|max-age)=/i.test(val)) {
39
39
  const [key, value] = val.toLowerCase().split('=');
40
40
  const ms = Number.isFinite(Number(value)) ? value * 1e3 : Date.parse(value) - Date.now();
41
41
  ttl[(0, _utils.toCamelCase)(key)] = Math.min(ms, lifetimeCap);
@@ -8,8 +8,8 @@ var _nodeBuffer = require("node:buffer");
8
8
  var _nodeCrypto = require("node:crypto");
9
9
  var _nodeHttp = _interopRequireDefault(require("node:http2"));
10
10
  var _nodeUtil = require("node:util");
11
- var _mediatypes = require("./mediatypes");
12
- var _utils = require("./utils");
11
+ var _mediatypes = require("./mediatypes.cjs");
12
+ var _utils = require("./utils.cjs");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  const CRLF = '\r\n';
15
15
  const {
@@ -40,8 +40,8 @@ class FormData {
40
40
  }
41
41
  };
42
42
  }
43
- static alike(instance) {
44
- return FormData.name === instance?.[Symbol.toStringTag];
43
+ static alike(value) {
44
+ return FormData.name === value?.[Symbol.toStringTag];
45
45
  }
46
46
  static #enfoldEntry(name, value, filename) {
47
47
  name = (0, _nodeUtil.toUSVString)(name);
@@ -60,25 +60,22 @@ class FormData {
60
60
  };
61
61
  }
62
62
  static #ensureInstance(value) {
63
- return (0, _utils.isFileLike)(value) || value === Object(value) && Reflect.has(value, Symbol.asyncIterator);
63
+ return (0, _utils.isFileLike)(value) || Object(value) === value && Reflect.has(value, Symbol.asyncIterator);
64
64
  }
65
65
  #entries = [];
66
66
  get [Symbol.toStringTag]() {
67
67
  return this.constructor.name;
68
68
  }
69
69
  constructor(input) {
70
- if (input === Object(input) && (input?.constructor === Object || Reflect.has(input, Symbol.iterator))) {
71
- if (input.constructor !== Object) {
72
- input = Array.from(input);
73
- }
70
+ if (Object(input) === input) {
74
71
  if (Array.isArray(input)) {
75
72
  if (!input.every(it => Array.isArray(it))) {
76
73
  throw new TypeError(`Failed to construct '${this[Symbol.toStringTag]}': The provided value cannot be converted to a sequence.`);
77
74
  } else if (!input.every(it => it.length === 2)) {
78
75
  throw new TypeError(`Failed to construct '${this[Symbol.toStringTag]}': Sequence initializer must only contain pair elements.`);
79
76
  }
80
- }
81
- if (input.constructor === Object) {
77
+ input = Array.from(input);
78
+ } else if (!Reflect.has(input, Symbol.iterator)) {
82
79
  input = Object.entries(input);
83
80
  }
84
81
  for (const [key, value] of input) {
@@ -32,8 +32,8 @@ exports.mediatypes = void 0;
32
32
  var _nodeHttp = _interopRequireDefault(require("node:http"));
33
33
  var _nodeHttp2 = _interopRequireWildcard(require("node:http2"));
34
34
  var _nodeHttps = _interopRequireDefault(require("node:https"));
35
- var _config = _interopRequireDefault(require("./config"));
36
- var _constants = require("./constants");
35
+ var _config = _interopRequireDefault(require("./config.cjs"));
36
+ var _constants = require("./constants.cjs");
37
37
  Object.keys(_constants).forEach(function (key) {
38
38
  if (key === "default" || key === "__esModule") return;
39
39
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -45,12 +45,12 @@ Object.keys(_constants).forEach(function (key) {
45
45
  }
46
46
  });
47
47
  });
48
- var _mediatypes2 = _interopRequireWildcard(require("./mediatypes"));
48
+ var _mediatypes2 = _interopRequireWildcard(require("./mediatypes.cjs"));
49
49
  var _mediatypes = _mediatypes2;
50
50
  exports.mediatypes = _mediatypes2;
51
- var _preflight = require("./preflight");
52
- var _transfer = require("./transfer");
53
- var _utils = require("./utils");
51
+ var _preflight = require("./preflight.cjs");
52
+ var _transfer = require("./transfer.cjs");
53
+ var _utils = require("./utils.cjs");
54
54
  Object.keys(_utils).forEach(function (key) {
55
55
  if (key === "default" || key === "__esModule") return;
56
56
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -62,7 +62,7 @@ Object.keys(_utils).forEach(function (key) {
62
62
  }
63
63
  });
64
64
  });
65
- var _validation = require("./validation");
65
+ var _validation = require("./validation.cjs");
66
66
  Object.keys(_validation).forEach(function (key) {
67
67
  if (key === "default" || key === "__esModule") return;
68
68
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -75,7 +75,7 @@ Object.keys(_validation).forEach(function (key) {
75
75
  });
76
76
  });
77
77
  var _nodeBuffer = require("node:buffer");
78
- var _ackn = require("./ackn");
78
+ var _ackn = require("./ackn.cjs");
79
79
  Object.keys(_ackn).forEach(function (key) {
80
80
  if (key === "default" || key === "__esModule") return;
81
81
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -87,7 +87,19 @@ Object.keys(_ackn).forEach(function (key) {
87
87
  }
88
88
  });
89
89
  });
90
- var _cookies = require("./cookies");
90
+ var _codecs = require("./codecs.cjs");
91
+ Object.keys(_codecs).forEach(function (key) {
92
+ if (key === "default" || key === "__esModule") return;
93
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
94
+ if (key in exports && exports[key] === _codecs[key]) return;
95
+ Object.defineProperty(exports, key, {
96
+ enumerable: true,
97
+ get: function () {
98
+ return _codecs[key];
99
+ }
100
+ });
101
+ });
102
+ var _cookies = require("./cookies.cjs");
91
103
  Object.keys(_cookies).forEach(function (key) {
92
104
  if (key === "default" || key === "__esModule") return;
93
105
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -99,7 +111,7 @@ Object.keys(_cookies).forEach(function (key) {
99
111
  }
100
112
  });
101
113
  });
102
- var _errors = require("./errors");
114
+ var _errors = require("./errors.cjs");
103
115
  Object.keys(_errors).forEach(function (key) {
104
116
  if (key === "default" || key === "__esModule") return;
105
117
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -111,7 +123,7 @@ Object.keys(_errors).forEach(function (key) {
111
123
  }
112
124
  });
113
125
  });
114
- var _formdata = require("./formdata");
126
+ var _formdata = require("./formdata.cjs");
115
127
  Object.keys(_formdata).forEach(function (key) {
116
128
  if (key === "default" || key === "__esModule") return;
117
129
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -123,7 +135,7 @@ Object.keys(_formdata).forEach(function (key) {
123
135
  }
124
136
  });
125
137
  });
126
- var _mixin = require("./mixin");
138
+ var _mixin = require("./mixin.cjs");
127
139
  Object.keys(_mixin).forEach(function (key) {
128
140
  if (key === "default" || key === "__esModule") return;
129
141
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -141,7 +153,7 @@ const {
141
153
  HTTP2_HEADER_CONTENT_TYPE
142
154
  } = _nodeHttp2.default.constants;
143
155
  function rekwest(url, options) {
144
- return (0, _transfer.transfer)((0, _validation.validation)((0, _utils.normalize)(url, options)), rekwest);
156
+ return (0, _transfer.transfer)((0, _validation.validation)((0, _utils.normalize)(url, options)));
145
157
  }
146
158
  Reflect.defineProperty(rekwest, 'defaults', {
147
159
  enumerable: true,
@@ -177,14 +189,14 @@ Reflect.defineProperty(rekwest, 'stream', {
177
189
  } = options.url.protocol === 'http:' ? _nodeHttp.default : _nodeHttps.default;
178
190
  req = request(options.url, options);
179
191
  }
180
- (0, _utils.affix)(client, req, options);
192
+ (0, _utils.snoop)(client, req, options);
181
193
  req.once('response', res => {
182
194
  let headers;
183
195
  if (options.h2) {
184
196
  headers = res;
185
197
  res = req;
186
198
  }
187
- (0, _utils.admix)(res, headers, options);
199
+ (0, _utils.augment)(res, headers, options);
188
200
  });
189
201
  return req;
190
202
  }
@@ -6,14 +6,17 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.mixin = void 0;
7
7
  var _nodeBuffer = require("node:buffer");
8
8
  var _nodeHttp = _interopRequireDefault(require("node:http2"));
9
- var _utils = require("./utils");
9
+ var _consumers = require("node:stream/consumers");
10
+ var _nodeUtil = require("node:util");
11
+ var _codecs = require("./codecs.cjs");
12
+ var _utils = require("./utils.cjs");
10
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
14
  const {
12
15
  HTTP2_HEADER_CONTENT_ENCODING,
13
16
  HTTP2_HEADER_CONTENT_TYPE
14
17
  } = _nodeHttp.default.constants;
15
18
  const mixin = (res, {
16
- decompression,
19
+ decodersOptions,
17
20
  digest = false,
18
21
  parse = false
19
22
  } = {}) => {
@@ -71,28 +74,30 @@ const mixin = (res, {
71
74
  value: async function () {
72
75
  (0, _utils.brandCheck)(this, res?.constructor);
73
76
  if (this.bodyUsed) {
74
- throw new TypeError('Response stream already read');
77
+ throw new TypeError('Response stream already read.');
75
78
  }
76
- let body = [];
77
- for await (const chunk of (0, _utils.decompress)(this, this.headers[HTTP2_HEADER_CONTENT_ENCODING], {
78
- decompression
79
- })) {
80
- body.push(chunk);
81
- }
82
- body = Buffer.concat(body);
79
+ let body = await (0, _consumers.buffer)((0, _codecs.decode)(this, this.headers[HTTP2_HEADER_CONTENT_ENCODING], {
80
+ decodersOptions
81
+ }));
83
82
  if (!body.length && parse) {
84
83
  return null;
85
84
  }
86
85
  if (body.length && parse) {
87
86
  const contentType = this.headers[HTTP2_HEADER_CONTENT_TYPE] ?? '';
88
- const charset = contentType.split(';').find(it => /charset=/i.test(it))?.toLowerCase().replace('charset=', '').replace('iso-8859-1', 'latin1').trim() || 'utf-8';
89
- if (/\bjson\b/i.test(contentType)) {
90
- body = JSON.parse(body.toString(charset));
91
- } else if (/\b(?:text|xml)\b/i.test(contentType)) {
92
- if (/\b(?:latin1|ucs-2|utf-(?:8|16le))\b/i.test(charset)) {
93
- body = body.toString(charset);
87
+ let isTextual, mimeType;
88
+ try {
89
+ mimeType = contentType ? new _nodeUtil.MIMEType(contentType) : null;
90
+ } finally {
91
+ isTextual = mimeType && (mimeType.type === 'text' || mimeType.subtype.match(/\bcsv\b|\bjson\b|\bxml\b|\byaml\b/) || mimeType.essence.match(/\becmascript\b|\bjavascript\b|\bx-www-form-urlencoded\b/));
92
+ }
93
+ if (isTextual) {
94
+ if (/\bjson\b/i.test(contentType)) {
95
+ body = JSON.parse(body.toString());
94
96
  } else {
95
- body = new TextDecoder(charset).decode(body);
97
+ const charset = mimeType.params.get('charset')?.toLowerCase() ?? 'utf-8';
98
+ body = new TextDecoder(charset, {
99
+ fatal: true
100
+ }).decode(body);
96
101
  }
97
102
  }
98
103
  }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.postflight = void 0;
7
+ var _nodeHttp = _interopRequireDefault(require("node:http2"));
8
+ var _cookies = require("./cookies.cjs");
9
+ var _mixin = require("./mixin.cjs");
10
+ var _redirects = require("./redirects.cjs");
11
+ var _utils = require("./utils.cjs");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const {
14
+ HTTP2_HEADER_SET_COOKIE,
15
+ HTTP_STATUS_BAD_REQUEST
16
+ } = _nodeHttp.default.constants;
17
+ const postflight = (req, res, options, {
18
+ reject,
19
+ resolve
20
+ }) => {
21
+ const {
22
+ cookies,
23
+ h2,
24
+ url
25
+ } = options;
26
+ let headers;
27
+ if (h2) {
28
+ headers = res;
29
+ res = req;
30
+ } else {
31
+ res.once('error', reject);
32
+ }
33
+ (0, _utils.augment)(res, headers, options);
34
+ if (cookies !== false && res.headers[HTTP2_HEADER_SET_COOKIE]) {
35
+ if (_cookies.Cookies.jar.has(url.origin)) {
36
+ const cookie = new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE], options);
37
+ _cookies.Cookies.jar.get(url.origin).forEach((val, key) => {
38
+ if (!cookie.has(key)) {
39
+ cookie.set(key, val);
40
+ }
41
+ });
42
+ _cookies.Cookies.jar.set(url.origin, cookie);
43
+ } else {
44
+ _cookies.Cookies.jar.set(url.origin, new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE], options));
45
+ }
46
+ }
47
+ Reflect.defineProperty(res, 'cookies', {
48
+ enumerable: true,
49
+ value: cookies !== false && _cookies.Cookies.jar.has(url.origin) ? _cookies.Cookies.jar.get(url.origin) : void 0
50
+ });
51
+ const willRedirect = (0, _redirects.redirects)(res, options);
52
+ if (Object(willRedirect) === willRedirect) {
53
+ return willRedirect.then(resolve, reject);
54
+ }
55
+ if (res.statusCode >= HTTP_STATUS_BAD_REQUEST) {
56
+ return reject((0, _mixin.mixin)(res, options));
57
+ }
58
+ resolve((0, _mixin.mixin)(res, options));
59
+ };
60
+ exports.postflight = postflight;
@@ -5,9 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.preflight = void 0;
7
7
  var _nodeHttp = _interopRequireDefault(require("node:http2"));
8
- var _config = require("./config");
9
- var _constants = require("./constants");
10
- var _cookies = require("./cookies");
8
+ var _config = require("./config.cjs");
9
+ var _constants = require("./constants.cjs");
10
+ var _cookies = require("./cookies.cjs");
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
12
  const {
13
13
  HTTP2_HEADER_ACCEPT_ENCODING,
@@ -34,7 +34,7 @@ const preflight = options => {
34
34
  }
35
35
  if (cookies !== false && credentials !== _constants.requestCredentials.omit) {
36
36
  let cookie = _cookies.Cookies.jar.has(url.origin);
37
- if (cookies === Object(cookies) && [_constants.requestCredentials.include, _constants.requestCredentials.sameOrigin].includes(credentials)) {
37
+ if (Object(cookies) === cookies && [_constants.requestCredentials.include, _constants.requestCredentials.sameOrigin].includes(credentials)) {
38
38
  if (cookie) {
39
39
  cookie = new _cookies.Cookies(cookies, options);
40
40
  _cookies.Cookies.jar.get(url.origin).forEach((val, key) => {
@@ -58,17 +58,19 @@ const preflight = options => {
58
58
  };
59
59
  }
60
60
  if (credentials === _constants.requestCredentials.omit) {
61
+ [HTTP2_HEADER_AUTHORIZATION, HTTP2_HEADER_COOKIE].forEach(key => Reflect.deleteProperty(options.headers, key));
61
62
  options.cookies = false;
62
- for (const it of Object.keys(options.headers ?? {}).filter(val => new RegExp(`^(${HTTP2_HEADER_AUTHORIZATION}|${HTTP2_HEADER_COOKIE})$`, 'i').test(val))) {
63
- Reflect.deleteProperty(options.headers, it);
64
- }
65
63
  url.password = url.username = '';
66
64
  }
65
+ if (!h2) {
66
+ [HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_METHOD, HTTP2_HEADER_PATH, HTTP2_HEADER_SCHEME].forEach(key => Reflect.deleteProperty(options.headers, key));
67
+ }
67
68
  options.headers = {
68
69
  ...Object.entries(options.headers ?? {}).reduce((acc, [key, val]) => {
69
70
  acc[key.toLowerCase()] = val;
70
- if (acc[HTTP2_HEADER_ACCEPT_ENCODING]?.match(/\bzstd\b/i) && !_config.isZstdSupported) {
71
- acc[HTTP2_HEADER_ACCEPT_ENCODING] = val.replace(/\s?zstd,?/gi, '').trim();
71
+ const rex = /\s?zstd,?/gi;
72
+ if (acc[HTTP2_HEADER_ACCEPT_ENCODING]?.match(rex) && !_config.isZstdSupported) {
73
+ acc[HTTP2_HEADER_ACCEPT_ENCODING] = val.replace(rex, '').trim();
72
74
  if (!acc[HTTP2_HEADER_ACCEPT_ENCODING]) {
73
75
  Reflect.deleteProperty(acc, HTTP2_HEADER_ACCEPT_ENCODING);
74
76
  }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.redirects = void 0;
7
+ var _nodeHttp = _interopRequireDefault(require("node:http2"));
8
+ var _nodeStream = require("node:stream");
9
+ var _constants = require("./constants.cjs");
10
+ var _errors = require("./errors.cjs");
11
+ var _index = _interopRequireDefault(require("./index.cjs"));
12
+ var _utils = require("./utils.cjs");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ const {
15
+ HTTP2_HEADER_LOCATION,
16
+ HTTP2_METHOD_GET,
17
+ HTTP2_METHOD_HEAD,
18
+ HTTP2_METHOD_POST,
19
+ HTTP_STATUS_FOUND,
20
+ HTTP_STATUS_MOVED_PERMANENTLY,
21
+ HTTP_STATUS_PERMANENT_REDIRECT,
22
+ HTTP_STATUS_SEE_OTHER,
23
+ HTTP_STATUS_TEMPORARY_REDIRECT
24
+ } = _nodeHttp.default.constants;
25
+ const redirects = (res, options) => {
26
+ const {
27
+ credentials,
28
+ follow,
29
+ redirect,
30
+ url
31
+ } = options;
32
+ if (follow && /3\d{2}/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
33
+ if (!_constants.requestRedirectCodes.includes(res.statusCode)) {
34
+ return res.emit('error', new RangeError(`Invalid status code: ${res.statusCode}`));
35
+ }
36
+ if (redirect === _constants.requestRedirect.error) {
37
+ return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
38
+ }
39
+ if (redirect === _constants.requestRedirect.follow) {
40
+ const location = new URL(res.headers[HTTP2_HEADER_LOCATION], url);
41
+ if (!/^https?:/i.test(location.protocol)) {
42
+ return res.emit('error', new _errors.RequestError('URL scheme must be "http" or "https".'));
43
+ }
44
+ if (!(0, _utils.sameOrigin)(location, url)) {
45
+ if (credentials !== _constants.requestCredentials.include) {
46
+ options.credentials = _constants.requestCredentials.omit;
47
+ }
48
+ options.h2 = false;
49
+ }
50
+ if ([HTTP_STATUS_PERMANENT_REDIRECT, HTTP_STATUS_TEMPORARY_REDIRECT].includes(res.statusCode) && (0, _utils.isPipeStream)(options.body) && !(0, _nodeStream.isReadable)(options.body)) {
51
+ return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
52
+ }
53
+ if ([HTTP_STATUS_MOVED_PERMANENTLY, HTTP_STATUS_FOUND].includes(res.statusCode) && options.method === HTTP2_METHOD_POST || res.statusCode === HTTP_STATUS_SEE_OTHER && ![HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(options.method)) {
54
+ options.body = null;
55
+ options.method = HTTP2_METHOD_GET;
56
+ }
57
+ options.follow--;
58
+ options.redirected = true;
59
+ return (0, _index.default)(location, options);
60
+ }
61
+ }
62
+ };
63
+ exports.redirects = redirects;