rekwest 4.0.0 → 4.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
@@ -85,7 +85,7 @@ const file = new File(['bits'], 'file.dab');
85
85
  const readable = Readable.from('bits');
86
86
 
87
87
  const fd = new FormData({
88
- aux: Date.now(), // either [[key, value]], or kv sequenceable
88
+ aux: Date.now(), // either [[key, value]] or kv sequenceable
89
89
  });
90
90
 
91
91
  fd.append('celestial', 'payload');
@@ -122,10 +122,11 @@ console.log(res.body);
122
122
  and [tls.ConnectionOptions](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
123
123
  for HTTP/2 attunes
124
124
  * `body` **{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File |
125
- FormData | Iterator | Object | Readable | ReadableStream | SharedArrayBuffer | URLSearchParams}** The body to send
126
- with the request
125
+ FormData | Iterator | Object | Readable | SharedArrayBuffer | URLSearchParams}** The body to send with the request
127
126
  * `cookies` **{boolean | Array<[k, v]> | Cookies | Object | URLSearchParams}** `Default: true` The cookies to add to
128
127
  the request
128
+ * `credentials` **{include | omit | same-origin}** `Default: same-origin` Controls credentials in case of cross-origin
129
+ redirects
129
130
  * `digest` **{boolean}** `Default: true` Controls whether to read the response stream or simply add a mixin
130
131
  * `follow` **{number}** `Default: 20` The number of redirects to follow
131
132
  * `h2` **{boolean}** `Default: false` Forces the use of HTTP/2 protocol
package/dist/ackn.js CHANGED
@@ -25,7 +25,7 @@ const ackn = options => new Promise((resolve, reject) => {
25
25
  createConnection() {
26
26
  return socket;
27
27
  },
28
- h2: /h2c?/.test(alpnProtocol),
28
+ h2: /h2c?/i.test(alpnProtocol),
29
29
  protocol: url.protocol
30
30
  });
31
31
  });
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.requestRedirectCodes = exports.requestRedirect = exports.requestCredentials = void 0;
5
+ var _nodeHttp = _interopRequireDefault(require("node:http2"));
6
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
7
+ const {
8
+ HTTP_STATUS_FOUND,
9
+ HTTP_STATUS_MOVED_PERMANENTLY,
10
+ HTTP_STATUS_PERMANENT_REDIRECT,
11
+ HTTP_STATUS_SEE_OTHER,
12
+ HTTP_STATUS_TEMPORARY_REDIRECT
13
+ } = _nodeHttp.default.constants;
14
+ const requestCredentials = {
15
+ include: 'include',
16
+ omit: 'omit',
17
+ sameOrigin: 'same-origin'
18
+ };
19
+ exports.requestCredentials = requestCredentials;
20
+ const requestRedirect = {
21
+ error: 'error',
22
+ follow: 'follow',
23
+ manual: 'manual'
24
+ };
25
+ exports.requestRedirect = requestRedirect;
26
+ const requestRedirectCodes = [HTTP_STATUS_MOVED_PERMANENTLY, HTTP_STATUS_FOUND, HTTP_STATUS_SEE_OTHER, HTTP_STATUS_TEMPORARY_REDIRECT, HTTP_STATUS_PERMANENT_REDIRECT];
27
+ exports.requestRedirectCodes = requestRedirectCodes;
package/dist/cookies.js CHANGED
@@ -15,7 +15,7 @@ class Cookies extends URLSearchParams {
15
15
  super(input);
16
16
  }
17
17
  toString() {
18
- (0, _utils.collate)(this, Cookies);
18
+ (0, _utils.brandCheck)(this, Cookies);
19
19
  return super.toString().split('&').join('; ').trim();
20
20
  }
21
21
  }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _nodeHttp = _interopRequireDefault(require("node:http2"));
6
+ var _constants = require("./constants");
7
+ var _utils = require("./utils");
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ const {
10
+ HTTP2_METHOD_GET,
11
+ HTTP_STATUS_SERVICE_UNAVAILABLE,
12
+ HTTP_STATUS_TOO_MANY_REQUESTS
13
+ } = _nodeHttp.default.constants;
14
+ const stash = {
15
+ credentials: _constants.requestCredentials.sameOrigin,
16
+ digest: true,
17
+ follow: 20,
18
+ get maxRetryAfter() {
19
+ return this[_utils.maxRetryAfter] ?? this.timeout;
20
+ },
21
+ set maxRetryAfter(value) {
22
+ this[_utils.maxRetryAfter] = value;
23
+ },
24
+ method: HTTP2_METHOD_GET,
25
+ parse: true,
26
+ redirect: _constants.requestRedirect.follow,
27
+ redirected: false,
28
+ retry: {
29
+ attempts: 0,
30
+ backoffStrategy: 'interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)',
31
+ interval: 1e3,
32
+ retryAfter: true,
33
+ statusCodes: [HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_SERVICE_UNAVAILABLE]
34
+ },
35
+ thenable: false,
36
+ timeout: 3e5
37
+ };
38
+ var _default = {
39
+ stash
40
+ };
41
+ exports.default = _default;
package/dist/formdata.js CHANGED
@@ -31,7 +31,7 @@ class FormData {
31
31
  } else {
32
32
  yield encoder.encode(`${prefix}; name="${escape(normalize(name))}"${value.name ? `; filename="${escape(value.name)}"` : ''}${CRLF}${HTTP2_HEADER_CONTENT_TYPE}: ${value.type || _mediatypes.APPLICATION_OCTET_STREAM}${CRLF.repeat(2)}`);
33
33
  yield* (0, _utils.tap)(value);
34
- yield encoder.encode(CRLF);
34
+ yield new Uint8Array([13, 10]);
35
35
  }
36
36
  }
37
37
  yield encoder.encode(`--${boundary}--`);
@@ -98,18 +98,18 @@ class FormData {
98
98
  }
99
99
  }
100
100
  append(...args) {
101
- (0, _utils.collate)(this, FormData);
101
+ (0, _utils.brandCheck)(this, FormData);
102
102
  this.#ensureArgs(args, 2, 'append');
103
103
  this.#entries.push(this.constructor.#enfoldEntry(...args));
104
104
  }
105
105
  delete(...args) {
106
- (0, _utils.collate)(this, FormData);
106
+ (0, _utils.brandCheck)(this, FormData);
107
107
  this.#ensureArgs(args, 1, 'delete');
108
108
  const name = (0, _nodeUtil.toUSVString)(args[0]);
109
109
  this.#entries = this.#entries.filter(it => it.name !== name);
110
110
  }
111
111
  forEach(...args) {
112
- (0, _utils.collate)(this, FormData);
112
+ (0, _utils.brandCheck)(this, FormData);
113
113
  this.#ensureArgs(args, 1, 'forEach');
114
114
  const [callback, thisArg] = args;
115
115
  for (const entry of this) {
@@ -117,25 +117,25 @@ class FormData {
117
117
  }
118
118
  }
119
119
  get(...args) {
120
- (0, _utils.collate)(this, FormData);
120
+ (0, _utils.brandCheck)(this, FormData);
121
121
  this.#ensureArgs(args, 1, 'get');
122
122
  const name = (0, _nodeUtil.toUSVString)(args[0]);
123
123
  return (this.#entries.find(it => it.name === name) ?? {}).value ?? null;
124
124
  }
125
125
  getAll(...args) {
126
- (0, _utils.collate)(this, FormData);
126
+ (0, _utils.brandCheck)(this, FormData);
127
127
  this.#ensureArgs(args, 1, 'getAll');
128
128
  const name = (0, _nodeUtil.toUSVString)(args[0]);
129
129
  return this.#entries.filter(it => it.name === name).map(it => it.value);
130
130
  }
131
131
  has(...args) {
132
- (0, _utils.collate)(this, FormData);
132
+ (0, _utils.brandCheck)(this, FormData);
133
133
  this.#ensureArgs(args, 1, 'has');
134
134
  const name = (0, _nodeUtil.toUSVString)(args[0]);
135
135
  return !!this.#entries.find(it => it.name === name);
136
136
  }
137
137
  set(...args) {
138
- (0, _utils.collate)(this, FormData);
138
+ (0, _utils.brandCheck)(this, FormData);
139
139
  this.#ensureArgs(args, 2, 'set');
140
140
  const entry = this.constructor.#enfoldEntry(...args);
141
141
  const idx = this.#entries.findIndex(it => it.name === entry.name);
@@ -146,7 +146,7 @@ class FormData {
146
146
  }
147
147
  }
148
148
  *entries() {
149
- (0, _utils.collate)(this, FormData);
149
+ (0, _utils.brandCheck)(this, FormData);
150
150
  for (const {
151
151
  name,
152
152
  value
@@ -155,19 +155,19 @@ class FormData {
155
155
  }
156
156
  }
157
157
  *keys() {
158
- (0, _utils.collate)(this, FormData);
158
+ (0, _utils.brandCheck)(this, FormData);
159
159
  for (const [name] of this) {
160
160
  yield name;
161
161
  }
162
162
  }
163
163
  *values() {
164
- (0, _utils.collate)(this, FormData);
164
+ (0, _utils.brandCheck)(this, FormData);
165
165
  for (const [, value] of this) {
166
166
  yield value;
167
167
  }
168
168
  }
169
169
  [Symbol.iterator]() {
170
- (0, _utils.collate)(this, FormData);
170
+ (0, _utils.brandCheck)(this, FormData);
171
171
  return this.entries();
172
172
  }
173
173
  }
package/dist/index.js CHANGED
@@ -12,7 +12,24 @@ var _nodeHttp = _interopRequireDefault(require("node:http"));
12
12
  var _nodeHttp2 = _interopRequireWildcard(require("node:http2"));
13
13
  exports.constants = _nodeHttp2.constants;
14
14
  var _nodeHttps = _interopRequireDefault(require("node:https"));
15
- var _promises = require("node:timers/promises");
15
+ var _constants = require("./constants");
16
+ Object.keys(_constants).forEach(function (key) {
17
+ if (key === "default" || key === "__esModule") return;
18
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
19
+ if (key in exports && exports[key] === _constants[key]) return;
20
+ exports[key] = _constants[key];
21
+ });
22
+ var _defaults = _interopRequireDefault(require("./defaults"));
23
+ var _mediatypes = _interopRequireWildcard(require("./mediatypes"));
24
+ exports.mediatypes = _mediatypes;
25
+ var _preflight = require("./preflight");
26
+ var _utils = require("./utils");
27
+ Object.keys(_utils).forEach(function (key) {
28
+ if (key === "default" || key === "__esModule") return;
29
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
30
+ if (key in exports && exports[key] === _utils[key]) return;
31
+ exports[key] = _utils[key];
32
+ });
16
33
  var _ackn = require("./ackn");
17
34
  Object.keys(_ackn).forEach(function (key) {
18
35
  if (key === "default" || key === "__esModule") return;
@@ -34,15 +51,6 @@ Object.keys(_errors).forEach(function (key) {
34
51
  if (key in exports && exports[key] === _errors[key]) return;
35
52
  exports[key] = _errors[key];
36
53
  });
37
- var _mediatypes = _interopRequireWildcard(require("./mediatypes"));
38
- exports.mediatypes = _mediatypes;
39
- var _utils = require("./utils");
40
- Object.keys(_utils).forEach(function (key) {
41
- if (key === "default" || key === "__esModule") return;
42
- if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
43
- if (key in exports && exports[key] === _utils[key]) return;
44
- exports[key] = _utils[key];
45
- });
46
54
  var _file = require("./file");
47
55
  Object.keys(_file).forEach(function (key) {
48
56
  if (key === "default" || key === "__esModule") return;
@@ -61,191 +69,25 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
61
69
  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; }
62
70
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
63
71
  const {
64
- HTTP2_HEADER_CONTENT_LENGTH,
65
- HTTP2_HEADER_CONTENT_TYPE,
66
- HTTP2_HEADER_LOCATION,
67
- HTTP2_HEADER_RETRY_AFTER,
68
- HTTP2_HEADER_SET_COOKIE,
69
- HTTP2_METHOD_GET,
70
- HTTP2_METHOD_HEAD,
71
- HTTP_STATUS_BAD_REQUEST,
72
- HTTP_STATUS_MOVED_PERMANENTLY,
73
- HTTP_STATUS_SEE_OTHER,
74
- HTTP_STATUS_SERVICE_UNAVAILABLE,
75
- HTTP_STATUS_TOO_MANY_REQUESTS
72
+ HTTP2_HEADER_CONTENT_TYPE
76
73
  } = _nodeHttp2.default.constants;
77
- const maxRetryAfter = Symbol('maxRetryAfter');
78
- const maxRetryAfterError = (interval, options) => new _errors.RequestError(`Maximum '${HTTP2_HEADER_RETRY_AFTER}' limit exceeded: ${interval} ms.`, options);
79
- let defaults = {
80
- follow: 20,
81
- get maxRetryAfter() {
82
- return this[maxRetryAfter] ?? this.timeout;
83
- },
84
- set maxRetryAfter(value) {
85
- this[maxRetryAfter] = value;
86
- },
87
- method: HTTP2_METHOD_GET,
88
- retry: {
89
- attempts: 0,
90
- backoffStrategy: 'interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)',
91
- interval: 1e3,
92
- retryAfter: true,
93
- statusCodes: [HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_SERVICE_UNAVAILABLE]
94
- },
95
- timeout: 3e5
96
- };
97
- async function rekwest(...args) {
74
+ function rekwest(...args) {
98
75
  let options = (0, _utils.sanitize)(...args);
99
- const {
100
- url
101
- } = options;
102
76
  if (!options.redirected) {
103
77
  options = (0, _utils.merge)(rekwest.defaults, options);
104
78
  }
105
- if (options.body && [HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(options.method)) {
106
- throw new TypeError(`Request with ${HTTP2_METHOD_GET}/${HTTP2_METHOD_HEAD} method cannot have body.`);
107
- }
108
- if (options.follow === 0) {
109
- throw new _errors.RequestError(`Maximum redirect reached at: ${url.href}`);
110
- }
111
- if (url.protocol === 'https:') {
112
- options = await (0, _ackn.ackn)(options);
113
- } else if (Reflect.has(options, 'alpnProtocol')) {
114
- ['alpnProtocol', 'createConnection', 'h2', 'protocol'].forEach(it => Reflect.deleteProperty(options, it));
115
- }
116
- options = await (0, _utils.transform)((0, _utils.preflight)(options));
117
- const {
118
- cookies,
119
- digest,
120
- follow,
121
- h2,
122
- redirect,
123
- redirected,
124
- thenable
125
- } = options;
126
- const {
127
- request
128
- } = url.protocol === 'http:' ? _nodeHttp.default : _nodeHttps.default;
129
- const promise = new Promise((resolve, reject) => {
130
- let client, req;
131
- if (h2) {
132
- client = _nodeHttp2.default.connect(url.origin, options);
133
- req = client.request(options.headers, options);
134
- } else {
135
- req = request(url, options);
136
- }
137
- (0, _utils.affix)(client, req, options);
138
- req.once('error', reject);
139
- req.once('frameError', reject);
140
- req.once('goaway', reject);
141
- req.once('response', res => {
142
- let headers;
143
- if (h2) {
144
- headers = res;
145
- res = req;
146
- } else {
147
- res.once('error', reject);
148
- }
149
- (0, _utils.admix)(res, headers, options);
150
- if (cookies !== false && res.headers[HTTP2_HEADER_SET_COOKIE]) {
151
- if (_cookies.Cookies.jar.has(url.origin)) {
152
- new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]).forEach(function (val, key) {
153
- this.set(key, val);
154
- }, _cookies.Cookies.jar.get(url.origin));
155
- } else {
156
- _cookies.Cookies.jar.set(url.origin, new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]));
157
- }
158
- }
159
- Reflect.defineProperty(res, 'cookies', {
160
- enumerable: true,
161
- value: cookies !== false && _cookies.Cookies.jar.has(url.origin) ? _cookies.Cookies.jar.get(url.origin) : void 0
162
- });
163
- if (follow && /^3\d{2}$/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
164
- if (redirect === _utils.redirects.error) {
165
- return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
166
- }
167
- if (redirect === _utils.redirects.follow) {
168
- options.url = new URL(res.headers[HTTP2_HEADER_LOCATION], url).href;
169
- if (res.statusCode !== HTTP_STATUS_SEE_OTHER && options?.body?.pipe?.constructor === Function) {
170
- return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
171
- }
172
- options.follow--;
173
- if (res.statusCode === HTTP_STATUS_SEE_OTHER) {
174
- Reflect.deleteProperty(options.headers, HTTP2_HEADER_CONTENT_LENGTH);
175
- options.method = HTTP2_METHOD_GET;
176
- options.body = null;
177
- }
178
- Reflect.set(options, 'redirected', true);
179
- if (res.statusCode === HTTP_STATUS_MOVED_PERMANENTLY && res.headers[HTTP2_HEADER_RETRY_AFTER]) {
180
- let interval = res.headers[HTTP2_HEADER_RETRY_AFTER];
181
- interval = Number(interval) * 1000 || new Date(interval) - Date.now();
182
- if (interval > options.maxRetryAfter) {
183
- return res.emit('error', maxRetryAfterError(interval, {
184
- cause: (0, _utils.mixin)(res, options)
185
- }));
186
- }
187
- return (0, _promises.setTimeout)(interval).then(() => rekwest(options.url, options).then(resolve, reject));
188
- }
189
- return rekwest(options.url, options).then(resolve, reject);
190
- }
191
- }
192
- if (res.statusCode >= HTTP_STATUS_BAD_REQUEST) {
193
- return reject((0, _utils.mixin)(res, options));
194
- }
195
- resolve((0, _utils.mixin)(res, options));
196
- });
197
- (0, _utils.dispatch)(options, req);
198
- });
199
- try {
200
- const res = await promise;
201
- if (digest && !redirected) {
202
- res.body = await res.body();
203
- }
204
- return res;
205
- } catch (ex) {
206
- const {
207
- maxRetryAfter,
208
- retry
209
- } = options;
210
- if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
211
- let {
212
- interval
213
- } = retry;
214
- if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
215
- interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
216
- interval = Number(interval) * 1000 || new Date(interval) - Date.now();
217
- if (interval > maxRetryAfter) {
218
- throw maxRetryAfterError(interval, {
219
- cause: ex
220
- });
221
- }
222
- } else {
223
- interval = new Function('interval', `return Math.ceil(${retry.backoffStrategy});`)(interval);
224
- }
225
- retry.attempts--;
226
- retry.interval = interval;
227
- return (0, _promises.setTimeout)(interval).then(() => rekwest(url, options));
228
- }
229
- if (digest && !redirected && ex.body) {
230
- ex.body = await ex.body();
231
- }
232
- if (!thenable) {
233
- throw ex;
234
- } else {
235
- return ex;
236
- }
237
- }
79
+ return (0, _utils.transfer)((0, _utils.validation)(options));
238
80
  }
239
81
  Reflect.defineProperty(rekwest, 'stream', {
240
82
  enumerable: true,
241
83
  value(...args) {
242
- const options = (0, _utils.preflight)({
243
- ...(0, _utils.merge)(rekwest.defaults, {
84
+ const options = (0, _preflight.preflight)({
85
+ ...(0, _utils.validation)((0, _utils.merge)(rekwest.defaults, {
244
86
  headers: {
245
87
  [HTTP2_HEADER_CONTENT_TYPE]: _mediatypes.APPLICATION_OCTET_STREAM
246
88
  }
247
- }, (0, _utils.sanitize)(...args)),
248
- redirect: _utils.redirects.manual
89
+ }, (0, _utils.sanitize)(...args))),
90
+ redirect: _constants.requestRedirect.manual
249
91
  });
250
92
  const {
251
93
  h2,
@@ -276,9 +118,9 @@ Reflect.defineProperty(rekwest, 'stream', {
276
118
  Reflect.defineProperty(rekwest, 'defaults', {
277
119
  enumerable: true,
278
120
  get() {
279
- return defaults;
121
+ return _defaults.default.stash;
280
122
  },
281
123
  set(value) {
282
- defaults = (0, _utils.merge)(defaults, value);
124
+ _defaults.default.stash = (0, _utils.merge)(_defaults.default.stash, value);
283
125
  }
284
126
  });
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.postflight = void 0;
5
+ var _nodeHttp = _interopRequireDefault(require("node:http2"));
6
+ var _promises = require("node:timers/promises");
7
+ var _constants = require("./constants");
8
+ var _cookies = require("./cookies");
9
+ var _errors = require("./errors");
10
+ var _index = _interopRequireDefault(require("./index"));
11
+ var _utils = require("./utils");
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ const {
14
+ HTTP2_HEADER_AUTHORIZATION,
15
+ HTTP2_HEADER_LOCATION,
16
+ HTTP2_HEADER_RETRY_AFTER,
17
+ HTTP2_HEADER_SET_COOKIE,
18
+ HTTP2_METHOD_GET,
19
+ HTTP2_METHOD_HEAD,
20
+ HTTP2_METHOD_POST,
21
+ HTTP_STATUS_BAD_REQUEST,
22
+ HTTP_STATUS_FOUND,
23
+ HTTP_STATUS_MOVED_PERMANENTLY,
24
+ HTTP_STATUS_SEE_OTHER
25
+ } = _nodeHttp.default.constants;
26
+ const postflight = (req, res, options, {
27
+ reject,
28
+ resolve
29
+ }) => {
30
+ const {
31
+ cookies,
32
+ credentials,
33
+ follow,
34
+ h2,
35
+ redirect,
36
+ url
37
+ } = options;
38
+ let headers;
39
+ if (h2) {
40
+ headers = res;
41
+ res = req;
42
+ } else {
43
+ res.once('error', reject);
44
+ }
45
+ (0, _utils.admix)(res, headers, options);
46
+ if (cookies !== false && res.headers[HTTP2_HEADER_SET_COOKIE]) {
47
+ if (_cookies.Cookies.jar.has(url.origin)) {
48
+ new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]).forEach(function (val, key) {
49
+ this.set(key, val);
50
+ }, _cookies.Cookies.jar.get(url.origin));
51
+ } else {
52
+ _cookies.Cookies.jar.set(url.origin, new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]));
53
+ }
54
+ }
55
+ Reflect.defineProperty(res, 'cookies', {
56
+ enumerable: true,
57
+ value: cookies !== false && _cookies.Cookies.jar.has(url.origin) ? _cookies.Cookies.jar.get(url.origin) : void 0
58
+ });
59
+ const {
60
+ statusCode
61
+ } = res;
62
+ if (follow && /3\d{2}/.test(statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
63
+ if (!_constants.requestRedirectCodes.includes(statusCode)) {
64
+ return res.emit('error', new RangeError(`Invalid status code: ${statusCode}`));
65
+ }
66
+ if (redirect === _constants.requestRedirect.error) {
67
+ return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
68
+ }
69
+ if (redirect === _constants.requestRedirect.follow) {
70
+ const location = new URL(res.headers[HTTP2_HEADER_LOCATION], url);
71
+ if (!/^https?:/i.test(location.protocol)) {
72
+ return res.emit('error', new _errors.RequestError('URL scheme must be "http" or "https".'));
73
+ }
74
+ if (!(0, _utils.sameOrigin)(location, url) && [_constants.requestCredentials.omit, _constants.requestCredentials.sameOrigin].includes(credentials)) {
75
+ Reflect.deleteProperty(options.headers, HTTP2_HEADER_AUTHORIZATION);
76
+ location.password = location.username = '';
77
+ if (credentials === _constants.requestCredentials.omit) {
78
+ options.cookies = false;
79
+ }
80
+ }
81
+ options.url = location;
82
+ if (statusCode !== HTTP_STATUS_SEE_OTHER && options.body?.pipe?.constructor === Function) {
83
+ return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
84
+ }
85
+ options.follow--;
86
+ if ([HTTP_STATUS_MOVED_PERMANENTLY, HTTP_STATUS_FOUND].includes(statusCode) && options.method === HTTP2_METHOD_POST || statusCode === HTTP_STATUS_SEE_OTHER && ![HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(options.method)) {
87
+ Object.keys(options.headers).filter(it => /^content-/i.test(it)).forEach(it => Reflect.deleteProperty(options.headers, it));
88
+ options.body = null;
89
+ options.method = HTTP2_METHOD_GET;
90
+ }
91
+ Reflect.set(options, 'redirected', true);
92
+ if (statusCode === HTTP_STATUS_MOVED_PERMANENTLY && res.headers[HTTP2_HEADER_RETRY_AFTER]) {
93
+ let interval = res.headers[HTTP2_HEADER_RETRY_AFTER];
94
+ interval = Number(interval) * 1000 || new Date(interval) - Date.now();
95
+ if (interval > options.maxRetryAfter) {
96
+ return res.emit('error', (0, _utils.maxRetryAfterError)(interval, {
97
+ cause: (0, _utils.mixin)(res, options)
98
+ }));
99
+ }
100
+ return (0, _promises.setTimeout)(interval).then(() => (0, _index.default)(options.url, options).then(resolve, reject));
101
+ }
102
+ return (0, _index.default)(options.url, options).then(resolve, reject);
103
+ }
104
+ }
105
+ if (statusCode >= HTTP_STATUS_BAD_REQUEST) {
106
+ return reject((0, _utils.mixin)(res, options));
107
+ }
108
+ resolve((0, _utils.mixin)(res, options));
109
+ };
110
+ exports.postflight = postflight;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.preflight = void 0;
5
+ var _nodeHttp = _interopRequireDefault(require("node:http2"));
6
+ var _constants = require("./constants");
7
+ var _cookies = require("./cookies");
8
+ var _mediatypes = require("./mediatypes");
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ const {
11
+ HTTP2_HEADER_ACCEPT,
12
+ HTTP2_HEADER_ACCEPT_ENCODING,
13
+ HTTP2_HEADER_AUTHORITY,
14
+ HTTP2_HEADER_COOKIE,
15
+ HTTP2_HEADER_METHOD,
16
+ HTTP2_HEADER_PATH,
17
+ HTTP2_HEADER_SCHEME,
18
+ HTTP2_METHOD_GET,
19
+ HTTP2_METHOD_HEAD
20
+ } = _nodeHttp.default.constants;
21
+ const preflight = options => {
22
+ const {
23
+ cookies,
24
+ credentials,
25
+ h2 = false,
26
+ headers,
27
+ method,
28
+ url
29
+ } = options;
30
+ if (h2) {
31
+ options.endStream = [HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(method);
32
+ }
33
+ if (cookies !== false) {
34
+ let cookie = _cookies.Cookies.jar.get(url.origin);
35
+ if (cookies === Object(cookies) && [_constants.requestCredentials.include, _constants.requestCredentials.sameOrigin].includes(credentials)) {
36
+ if (cookie) {
37
+ new _cookies.Cookies(cookies).forEach(function (val, key) {
38
+ this.set(key, val);
39
+ }, cookie);
40
+ } else {
41
+ cookie = new _cookies.Cookies(cookies);
42
+ _cookies.Cookies.jar.set(url.origin, cookie);
43
+ }
44
+ }
45
+ options.headers = {
46
+ ...(cookie && {
47
+ [HTTP2_HEADER_COOKIE]: cookie
48
+ }),
49
+ ...headers
50
+ };
51
+ }
52
+ options.h2 ??= h2;
53
+ options.headers = {
54
+ [HTTP2_HEADER_ACCEPT]: `${_mediatypes.APPLICATION_JSON}, ${_mediatypes.TEXT_PLAIN}, ${_mediatypes.WILDCARD}`,
55
+ [HTTP2_HEADER_ACCEPT_ENCODING]: 'br, deflate, deflate-raw, gzip, identity',
56
+ ...Object.entries(options.headers ?? {}).reduce((acc, [key, val]) => (acc[key.toLowerCase()] = val, acc), {}),
57
+ ...(h2 && {
58
+ [HTTP2_HEADER_AUTHORITY]: url.host,
59
+ [HTTP2_HEADER_METHOD]: method,
60
+ [HTTP2_HEADER_PATH]: `${url.pathname}${url.search}`,
61
+ [HTTP2_HEADER_SCHEME]: url.protocol.replace(/\p{Punctuation}/gu, '')
62
+ })
63
+ };
64
+ return options;
65
+ };
66
+ exports.preflight = preflight;