rekwest 4.5.4 → 4.5.6

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/dist/preflight.js CHANGED
@@ -60,7 +60,7 @@ const preflight = options => {
60
60
  }
61
61
  if (credentials === _constants.requestCredentials.omit) {
62
62
  options.cookies = false;
63
- Object.keys(options.headers ?? {}).filter(it => new RegExp(`^${HTTP2_HEADER_AUTHORIZATION}`, 'i').test(it)).forEach(it => Reflect.deleteProperty(options.headers, it));
63
+ Object.keys(options.headers ?? {}).filter(it => new RegExp(`^(${HTTP2_HEADER_AUTHORIZATION}|${HTTP2_HEADER_COOKIE})$`, 'i').test(it)).forEach(it => Reflect.deleteProperty(options.headers, it));
64
64
  url.password = url.username = '';
65
65
  }
66
66
  options.headers = {
package/dist/transform.js CHANGED
@@ -31,7 +31,7 @@ const transform = async options => {
31
31
  [HTTP2_HEADER_CONTENT_LENGTH]: body.size,
32
32
  [HTTP2_HEADER_CONTENT_TYPE]: body.type || _mediatypes.APPLICATION_OCTET_STREAM
33
33
  };
34
- body = body.stream();
34
+ body = (0, _utils.tap)(body);
35
35
  } else if (_formdata.FormData.alike(body)) {
36
36
  body = _formdata.FormData.actuate(body);
37
37
  headers = {
package/package.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "url": "https://github.com/bricss/rekwest/issues"
9
9
  },
10
10
  "devDependencies": {
11
- "@babel/cli": "^7.21.5",
12
- "@babel/core": "^7.22.1",
13
- "@babel/eslint-parser": "^7.21.8",
14
- "@babel/preset-env": "^7.22.4",
15
- "c8": "^7.14.0",
16
- "eslint": "^8.42.0",
17
- "eslint-config-ultra-refined": "^2.15.0",
11
+ "@babel/cli": "^7.22.9",
12
+ "@babel/core": "^7.22.9",
13
+ "@babel/eslint-parser": "^7.22.9",
14
+ "@babel/preset-env": "^7.22.9",
15
+ "c8": "^8.0.0",
16
+ "eslint": "^8.45.0",
17
+ "eslint-config-ultra-refined": "^2.16.0",
18
18
  "mocha": "^10.2.0"
19
19
  },
20
20
  "description": "The robust request library that humanity deserves 🌐",
@@ -69,5 +69,5 @@
69
69
  "test:bail": "mocha --bail",
70
70
  "test:cover": "c8 --include=src --reporter=lcov --reporter=text npm test"
71
71
  },
72
- "version": "4.5.4"
72
+ "version": "4.5.6"
73
73
  }
package/src/mixin.mjs CHANGED
@@ -1,109 +1,109 @@
1
- import { Blob } from 'node:buffer';
2
- import http2 from 'node:http2';
3
- import {
4
- brandCheck,
5
- decompress,
6
- } from './utils.mjs';
7
-
8
- const {
9
- HTTP2_HEADER_CONTENT_ENCODING,
10
- HTTP2_HEADER_CONTENT_TYPE,
11
- } = http2.constants;
12
-
13
- export const mixin = (res, { digest = false, parse = false } = {}) => {
14
- if (!digest) {
15
- Object.defineProperties(res, {
16
- arrayBuffer: {
17
- enumerable: true,
18
- value: async function () {
19
- brandCheck(this, res?.constructor);
20
- parse &&= false;
21
- const { buffer, byteLength, byteOffset } = await this.body();
22
-
23
- return buffer.slice(byteOffset, byteOffset + byteLength);
24
- },
25
- },
26
- blob: {
27
- enumerable: true,
28
- value: async function () {
29
- brandCheck(this, res?.constructor);
30
- const val = await this.arrayBuffer();
31
-
32
- return new Blob([val]);
33
- },
34
- },
35
- json: {
36
- enumerable: true,
37
- value: async function () {
38
- brandCheck(this, res?.constructor);
39
- const val = await this.text();
40
-
41
- return JSON.parse(val);
42
- },
43
- },
44
- text: {
45
- enumerable: true,
46
- value: async function () {
47
- brandCheck(this, res?.constructor);
48
- const blob = await this.blob();
49
-
50
- return blob.text();
51
- },
52
- },
53
- });
54
- }
55
-
56
- return Object.defineProperties(res, {
57
- body: {
58
- enumerable: true,
59
- value: async function () {
60
- brandCheck(this, res?.constructor);
61
-
62
- if (this.bodyUsed) {
63
- throw new TypeError('Response stream already read');
64
- }
65
-
66
- let body = [];
67
-
68
- for await (const chunk of decompress(this, this.headers[HTTP2_HEADER_CONTENT_ENCODING])) {
69
- body.push(chunk);
70
- }
71
-
72
- body = Buffer.concat(body);
73
-
74
- if (!body.length && parse) {
75
- return null;
76
- }
77
-
78
- if (body.length && parse) {
79
- const contentType = this.headers[HTTP2_HEADER_CONTENT_TYPE] ?? '';
80
- const charset = contentType.split(';')
81
- .find((it) => /charset=/i.test(it))
82
- ?.toLowerCase()
83
- .replace('charset=', '')
84
- .replace('iso-8859-1', 'latin1')
85
- .trim() || 'utf-8';
86
-
87
- if (/\bjson\b/i.test(contentType)) {
88
- body = JSON.parse(body.toString(charset));
89
- } else if (/\b(?:text|xml)\b/i.test(contentType)) {
90
- if (/\b(?:latin1|ucs-2|utf-(?:8|16le))\b/i.test(charset)) {
91
- body = body.toString(charset);
92
- } else {
93
- body = new TextDecoder(charset).decode(body);
94
- }
95
- }
96
- }
97
-
98
- return body;
99
- },
100
- writable: true,
101
- },
102
- bodyUsed: {
103
- enumerable: true,
104
- get() {
105
- return this.readableEnded;
106
- },
107
- },
108
- });
109
- };
1
+ import { Blob } from 'node:buffer';
2
+ import http2 from 'node:http2';
3
+ import {
4
+ brandCheck,
5
+ decompress,
6
+ } from './utils.mjs';
7
+
8
+ const {
9
+ HTTP2_HEADER_CONTENT_ENCODING,
10
+ HTTP2_HEADER_CONTENT_TYPE,
11
+ } = http2.constants;
12
+
13
+ export const mixin = (res, { digest = false, parse = false } = {}) => {
14
+ if (!digest) {
15
+ Object.defineProperties(res, {
16
+ arrayBuffer: {
17
+ enumerable: true,
18
+ value: async function () {
19
+ brandCheck(this, res?.constructor);
20
+ parse &&= false;
21
+ const { buffer, byteLength, byteOffset } = await this.body();
22
+
23
+ return buffer.slice(byteOffset, byteOffset + byteLength);
24
+ },
25
+ },
26
+ blob: {
27
+ enumerable: true,
28
+ value: async function () {
29
+ brandCheck(this, res?.constructor);
30
+ const val = await this.arrayBuffer();
31
+
32
+ return new Blob([val]);
33
+ },
34
+ },
35
+ json: {
36
+ enumerable: true,
37
+ value: async function () {
38
+ brandCheck(this, res?.constructor);
39
+ const val = await this.text();
40
+
41
+ return JSON.parse(val);
42
+ },
43
+ },
44
+ text: {
45
+ enumerable: true,
46
+ value: async function () {
47
+ brandCheck(this, res?.constructor);
48
+ const blob = await this.blob();
49
+
50
+ return blob.text();
51
+ },
52
+ },
53
+ });
54
+ }
55
+
56
+ return Object.defineProperties(res, {
57
+ body: {
58
+ enumerable: true,
59
+ value: async function () {
60
+ brandCheck(this, res?.constructor);
61
+
62
+ if (this.bodyUsed) {
63
+ throw new TypeError('Response stream already read');
64
+ }
65
+
66
+ let body = [];
67
+
68
+ for await (const chunk of decompress(this, this.headers[HTTP2_HEADER_CONTENT_ENCODING])) {
69
+ body.push(chunk);
70
+ }
71
+
72
+ body = Buffer.concat(body);
73
+
74
+ if (!body.length && parse) {
75
+ return null;
76
+ }
77
+
78
+ if (body.length && parse) {
79
+ const contentType = this.headers[HTTP2_HEADER_CONTENT_TYPE] ?? '';
80
+ const charset = contentType.split(';')
81
+ .find((it) => /charset=/i.test(it))
82
+ ?.toLowerCase()
83
+ .replace('charset=', '')
84
+ .replace('iso-8859-1', 'latin1')
85
+ .trim() || 'utf-8';
86
+
87
+ if (/\bjson\b/i.test(contentType)) {
88
+ body = JSON.parse(body.toString(charset));
89
+ } else if (/\b(?:text|xml)\b/i.test(contentType)) {
90
+ if (/\b(?:latin1|ucs-2|utf-(?:8|16le))\b/i.test(charset)) {
91
+ body = body.toString(charset);
92
+ } else {
93
+ body = new TextDecoder(charset).decode(body);
94
+ }
95
+ }
96
+ }
97
+
98
+ return body;
99
+ },
100
+ writable: true,
101
+ },
102
+ bodyUsed: {
103
+ enumerable: true,
104
+ get() {
105
+ return this.readableEnded;
106
+ },
107
+ },
108
+ });
109
+ };
package/src/preflight.mjs CHANGED
@@ -63,7 +63,9 @@ export const preflight = (options) => {
63
63
  if (credentials === requestCredentials.omit) {
64
64
  options.cookies = false;
65
65
  Object.keys(options.headers ?? {})
66
- .filter((it) => new RegExp(`^${ HTTP2_HEADER_AUTHORIZATION }`, 'i').test(it))
66
+ .filter((it) => new RegExp(`^(${
67
+ HTTP2_HEADER_AUTHORIZATION }|${ HTTP2_HEADER_COOKIE
68
+ })$`, 'i').test(it))
67
69
  .forEach((it) => Reflect.deleteProperty(options.headers, it));
68
70
  url.password = url.username = '';
69
71
  }
package/src/transform.mjs CHANGED
@@ -9,7 +9,10 @@ import {
9
9
  APPLICATION_JSON,
10
10
  APPLICATION_OCTET_STREAM,
11
11
  } from './mediatypes.mjs';
12
- import { compress } from './utils.mjs';
12
+ import {
13
+ compress,
14
+ tap,
15
+ } from './utils.mjs';
13
16
 
14
17
  const {
15
18
  HTTP2_HEADER_CONTENT_ENCODING,
@@ -29,7 +32,7 @@ export const transform = async (options) => {
29
32
  [HTTP2_HEADER_CONTENT_LENGTH]: body.size,
30
33
  [HTTP2_HEADER_CONTENT_TYPE]: body.type || APPLICATION_OCTET_STREAM,
31
34
  };
32
- body = body.stream();
35
+ body = tap(body);
33
36
  } else if (FormData.alike(body)) {
34
37
  body = FormData.actuate(body);
35
38
  headers = { [HTTP2_HEADER_CONTENT_TYPE]: body.contentType };
package/src/utils.mjs CHANGED
@@ -1,188 +1,188 @@
1
- import http2 from 'node:http2';
2
- import { pipeline } from 'node:stream';
3
- import zlib from 'node:zlib';
4
- import defaults from './defaults.mjs';
5
- import {
6
- RequestError,
7
- TimeoutError,
8
- } from './errors.mjs';
9
-
10
- const {
11
- HTTP2_HEADER_RETRY_AFTER,
12
- HTTP2_HEADER_STATUS,
13
- } = http2.constants;
14
-
15
- export const admix = (res, headers, options) => {
16
- const { h2 } = options;
17
-
18
- if (h2) {
19
- Reflect.defineProperty(res, 'headers', {
20
- enumerable: true,
21
- value: headers,
22
- });
23
-
24
- Reflect.defineProperty(res, 'httpVersion', {
25
- enumerable: true,
26
- value: `${ h2 + 1 }.0`,
27
- });
28
-
29
- Reflect.defineProperty(res, 'statusCode', {
30
- enumerable: true,
31
- value: headers[HTTP2_HEADER_STATUS],
32
- });
33
- }
34
-
35
- Reflect.defineProperty(res, 'ok', {
36
- enumerable: true,
37
- value: /^2\d{2}$/.test(res.statusCode),
38
- });
39
-
40
- Reflect.defineProperty(res, 'redirected', {
41
- enumerable: true,
42
- value: !!options.redirected,
43
- });
44
- };
45
-
46
- export const affix = (client, req, options) => {
47
- req.once('end', () => client?.close());
48
- req.once('timeout', () => req.destroy(new TimeoutError(`Timed out after ${ options.timeout } ms.`)));
49
- req.once('trailers', (trailers) => {
50
- Reflect.defineProperty(req, 'trailers', {
51
- enumerable: true,
52
- value: trailers,
53
- });
54
- });
55
- };
56
-
57
- export const brandCheck = (value, ctor) => {
58
- if (!(value instanceof ctor)) {
59
- throw new TypeError('Illegal invocation');
60
- }
61
- };
62
-
63
- export const compress = (readable, encodings = '') => {
64
- const encoders = [];
65
-
66
- encodings = unwind(encodings);
67
-
68
- for (const encoding of encodings) {
69
- if (/\bbr\b/i.test(encoding)) {
70
- encoders.push(zlib.createBrotliCompress());
71
- } else if (/\bdeflate(?!-(?:\w+)?)\b/i.test(encoding)) {
72
- encoders.push(zlib.createDeflate());
73
- } else if (/\bdeflate-raw\b/i.test(encoding)) {
74
- encoders.push(zlib.createDeflateRaw());
75
- } else if (/\bgzip\b/i.test(encoding)) {
76
- encoders.push(zlib.createGzip());
77
- } else {
78
- return readable;
79
- }
80
- }
81
-
82
- return pipeline(readable, ...encoders, () => void 0);
83
- };
84
-
85
- export const decompress = (readable, encodings = '') => {
86
- const decoders = [];
87
-
88
- encodings = unwind(encodings);
89
-
90
- for (const encoding of encodings) {
91
- if (/\bbr\b/i.test(encoding)) {
92
- decoders.push(zlib.createBrotliDecompress());
93
- } else if (/\bdeflate(?!-(?:\w+)?)\b/i.test(encoding)) {
94
- decoders.push(zlib.createInflate());
95
- } else if (/\bdeflate-raw\b/i.test(encoding)) {
96
- decoders.push(zlib.createInflateRaw());
97
- } else if (/\bgzip\b/i.test(encoding)) {
98
- decoders.push(zlib.createGunzip());
99
- } else {
100
- return readable;
101
- }
102
- }
103
-
104
- return pipeline(readable, ...decoders, () => void 0);
105
- };
106
-
107
- export const dispatch = ({ body }, req) => {
108
- if (body?.pipe?.constructor === Function) {
109
- body.pipe(req);
110
- } else {
111
- req.end(body);
112
- }
113
- };
114
-
115
- export const maxRetryAfter = Symbol('maxRetryAfter');
116
-
117
- export const maxRetryAfterError = (
118
- interval,
119
- options,
120
- ) => new RequestError(`Maximum '${ HTTP2_HEADER_RETRY_AFTER }' limit exceeded: ${ interval } ms.`, options);
121
-
122
- export const merge = (target = {}, ...rest) => {
123
- target = JSON.parse(JSON.stringify(target));
124
- if (!rest.length) {
125
- return target;
126
- }
127
-
128
- rest.filter((it) => it === Object(it)).forEach((it) => {
129
- Object.entries(it).reduce((acc, [key, val]) => {
130
- if ([
131
- acc[key]?.constructor,
132
- val?.constructor,
133
- ].every((it) => [
134
- Array,
135
- Object,
136
- ].includes(it))) {
137
- if (acc[key]?.constructor === val.constructor) {
138
- acc[key] = merge(acc[key], val);
139
- } else {
140
- acc[key] = val;
141
- }
142
- } else {
143
- acc[key] = val;
144
- }
145
-
146
- return acc;
147
- }, target);
148
- });
149
-
150
- return target;
151
- };
152
-
153
- export const normalize = (url, options = {}) => {
154
- if (!options.redirected) {
155
- options = merge(defaults.stash, options);
156
- }
157
-
158
- if (options.trimTrailingSlashes) {
159
- url = `${ url }`.replace(/(?<!:)\/+/g, '/');
160
- }
161
-
162
- if (options.stripTrailingSlash) {
163
- url = `${ url }`.replace(/\/$|\/(?=#)|\/(?=\?)/g, '');
164
- }
165
-
166
- url = new URL(url, options.baseURL);
167
-
168
- return Object.assign(options, { url });
169
- };
170
-
171
- export const sameOrigin = (a, b) => a.protocol === b.protocol && a.hostname === b.hostname && a.port === b.port;
172
-
173
- export async function* tap(value) {
174
- if (Reflect.has(value, Symbol.asyncIterator)) {
175
- yield* value;
176
- } else if (value.stream) {
177
- yield* value.stream();
178
- } else {
179
- yield await value.arrayBuffer();
180
- }
181
- }
182
-
183
- export const toCamelCase = (str) => str?.toLowerCase().replace(
184
- /\p{Punctuation}.|\p{White_Space}./gu,
185
- (val) => val.replace(/\p{Punctuation}+|\p{White_Space}+/gu, '').toUpperCase(),
186
- );
187
-
188
- export const unwind = (encodings) => encodings.split(',').map((it) => it.trim());
1
+ import http2 from 'node:http2';
2
+ import { pipeline } from 'node:stream';
3
+ import zlib from 'node:zlib';
4
+ import defaults from './defaults.mjs';
5
+ import {
6
+ RequestError,
7
+ TimeoutError,
8
+ } from './errors.mjs';
9
+
10
+ const {
11
+ HTTP2_HEADER_RETRY_AFTER,
12
+ HTTP2_HEADER_STATUS,
13
+ } = http2.constants;
14
+
15
+ export const admix = (res, headers, options) => {
16
+ const { h2 } = options;
17
+
18
+ if (h2) {
19
+ Reflect.defineProperty(res, 'headers', {
20
+ enumerable: true,
21
+ value: headers,
22
+ });
23
+
24
+ Reflect.defineProperty(res, 'httpVersion', {
25
+ enumerable: true,
26
+ value: `${ h2 + 1 }.0`,
27
+ });
28
+
29
+ Reflect.defineProperty(res, 'statusCode', {
30
+ enumerable: true,
31
+ value: headers[HTTP2_HEADER_STATUS],
32
+ });
33
+ }
34
+
35
+ Reflect.defineProperty(res, 'ok', {
36
+ enumerable: true,
37
+ value: /^2\d{2}$/.test(res.statusCode),
38
+ });
39
+
40
+ Reflect.defineProperty(res, 'redirected', {
41
+ enumerable: true,
42
+ value: !!options.redirected,
43
+ });
44
+ };
45
+
46
+ export const affix = (client, req, options) => {
47
+ req.once('end', () => client?.close());
48
+ req.once('timeout', () => req.destroy(new TimeoutError(`Timed out after ${ options.timeout } ms.`)));
49
+ req.once('trailers', (trailers) => {
50
+ Reflect.defineProperty(req, 'trailers', {
51
+ enumerable: true,
52
+ value: trailers,
53
+ });
54
+ });
55
+ };
56
+
57
+ export const brandCheck = (value, ctor) => {
58
+ if (!(value instanceof ctor)) {
59
+ throw new TypeError('Illegal invocation');
60
+ }
61
+ };
62
+
63
+ export const compress = (readable, encodings = '') => {
64
+ const encoders = [];
65
+
66
+ encodings = unwind(encodings);
67
+
68
+ for (const encoding of encodings) {
69
+ if (/\bbr\b/i.test(encoding)) {
70
+ encoders.push(zlib.createBrotliCompress());
71
+ } else if (/\bdeflate(?!-(?:\w+)?)\b/i.test(encoding)) {
72
+ encoders.push(zlib.createDeflate());
73
+ } else if (/\bdeflate-raw\b/i.test(encoding)) {
74
+ encoders.push(zlib.createDeflateRaw());
75
+ } else if (/\bgzip\b/i.test(encoding)) {
76
+ encoders.push(zlib.createGzip());
77
+ } else {
78
+ return readable;
79
+ }
80
+ }
81
+
82
+ return pipeline(readable, ...encoders, () => void 0);
83
+ };
84
+
85
+ export const decompress = (readable, encodings = '') => {
86
+ const decoders = [];
87
+
88
+ encodings = unwind(encodings);
89
+
90
+ for (const encoding of encodings) {
91
+ if (/\bbr\b/i.test(encoding)) {
92
+ decoders.push(zlib.createBrotliDecompress());
93
+ } else if (/\bdeflate(?!-(?:\w+)?)\b/i.test(encoding)) {
94
+ decoders.push(zlib.createInflate());
95
+ } else if (/\bdeflate-raw\b/i.test(encoding)) {
96
+ decoders.push(zlib.createInflateRaw());
97
+ } else if (/\bgzip\b/i.test(encoding)) {
98
+ decoders.push(zlib.createGunzip());
99
+ } else {
100
+ return readable;
101
+ }
102
+ }
103
+
104
+ return pipeline(readable, ...decoders, () => void 0);
105
+ };
106
+
107
+ export const dispatch = ({ body }, req) => {
108
+ if (body?.pipe?.constructor === Function) {
109
+ body.pipe(req);
110
+ } else {
111
+ req.end(body);
112
+ }
113
+ };
114
+
115
+ export const maxRetryAfter = Symbol('maxRetryAfter');
116
+
117
+ export const maxRetryAfterError = (
118
+ interval,
119
+ options,
120
+ ) => new RequestError(`Maximum '${ HTTP2_HEADER_RETRY_AFTER }' limit exceeded: ${ interval } ms.`, options);
121
+
122
+ export const merge = (target = {}, ...rest) => {
123
+ target = JSON.parse(JSON.stringify(target));
124
+ if (!rest.length) {
125
+ return target;
126
+ }
127
+
128
+ rest.filter((it) => it === Object(it)).forEach((it) => {
129
+ Object.entries(it).reduce((acc, [key, val]) => {
130
+ if ([
131
+ acc[key]?.constructor,
132
+ val?.constructor,
133
+ ].every((it) => [
134
+ Array,
135
+ Object,
136
+ ].includes(it))) {
137
+ if (acc[key]?.constructor === val.constructor) {
138
+ acc[key] = merge(acc[key], val);
139
+ } else {
140
+ acc[key] = val;
141
+ }
142
+ } else {
143
+ acc[key] = val;
144
+ }
145
+
146
+ return acc;
147
+ }, target);
148
+ });
149
+
150
+ return target;
151
+ };
152
+
153
+ export const normalize = (url, options = {}) => {
154
+ if (!options.redirected) {
155
+ options = merge(defaults.stash, options);
156
+ }
157
+
158
+ if (options.trimTrailingSlashes) {
159
+ url = `${ url }`.replace(/(?<!:)\/+/g, '/');
160
+ }
161
+
162
+ if (options.stripTrailingSlash) {
163
+ url = `${ url }`.replace(/\/$|\/(?=#)|\/(?=\?)/g, '');
164
+ }
165
+
166
+ url = new URL(url, options.baseURL);
167
+
168
+ return Object.assign(options, { url });
169
+ };
170
+
171
+ export const sameOrigin = (a, b) => a.protocol === b.protocol && a.hostname === b.hostname && a.port === b.port;
172
+
173
+ export async function* tap(value) {
174
+ if (Reflect.has(value, Symbol.asyncIterator)) {
175
+ yield* value;
176
+ } else if (value.stream) {
177
+ yield* value.stream();
178
+ } else {
179
+ yield await value.arrayBuffer();
180
+ }
181
+ }
182
+
183
+ export const toCamelCase = (str) => str?.toLowerCase().replace(
184
+ /\p{Punctuation}.|\p{White_Space}./gu,
185
+ (val) => val.replace(/\p{Punctuation}+|\p{White_Space}+/gu, '').toUpperCase(),
186
+ );
187
+
188
+ export const unwind = (encodings) => encodings.split(',').map((it) => it.trim());