@e-mc/request 0.12.14 → 0.12.16
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 +5 -4
- package/http/adapter/index.js +12 -1
- package/index.js +61 -53
- package/package.json +4 -4
- package/util.d.ts +2 -2
- package/util.js +5 -3
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
* [View Source](https://www.unpkg.com/@e-mc/types@0.12.
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.12.16/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IModule, ModuleConstructor } from "./index";
|
|
@@ -45,6 +45,7 @@ interface IRequest extends IModule {
|
|
|
45
45
|
rclone(uri: string | URL, pathname: string | URL): Promise<string[]>;
|
|
46
46
|
rclone(uri: string | URL, options?: RcloneOptions): Promise<string[]>;
|
|
47
47
|
json(uri: string | URL, options?: OpenOptions): Promise<object | null>;
|
|
48
|
+
blob(uri: string | URL, options?: OpenOptions): Promise<Blob | null>;
|
|
48
49
|
pipe(uri: string | URL, to: Writable, options?: OpenOptions): Promise<null>;
|
|
49
50
|
opts(url: string | URL, options?: OpenOptions): HostConfig;
|
|
50
51
|
open(uri: string | URL, options: OpenOptions): HttpRequestClient;
|
|
@@ -255,9 +256,9 @@ instance.get("http://hostname/path/config.yml", options).then(data => {
|
|
|
255
256
|
|
|
256
257
|
## References
|
|
257
258
|
|
|
258
|
-
- https://www.unpkg.com/@e-mc/types@0.12.
|
|
259
|
-
- https://www.unpkg.com/@e-mc/types@0.12.
|
|
260
|
-
- https://www.unpkg.com/@e-mc/types@0.12.
|
|
259
|
+
- https://www.unpkg.com/@e-mc/types@0.12.16/lib/http.d.ts
|
|
260
|
+
- https://www.unpkg.com/@e-mc/types@0.12.16/lib/request.d.ts
|
|
261
|
+
- https://www.unpkg.com/@e-mc/types@0.12.16/lib/settings.d.ts
|
|
261
262
|
|
|
262
263
|
* https://www.npmjs.com/package/@types/node
|
|
263
264
|
|
package/http/adapter/index.js
CHANGED
|
@@ -243,6 +243,9 @@ class HttpAdapter {
|
|
|
243
243
|
if ('outFilename' in opts) {
|
|
244
244
|
opts.outFilename = (0, util_1.parseHeader)(headers, 'content-disposition');
|
|
245
245
|
}
|
|
246
|
+
if ('outContentType' in opts) {
|
|
247
|
+
opts.outContentType = headers['content-type'];
|
|
248
|
+
}
|
|
246
249
|
const pipeline = this.pipeTo ? !(0, types_1.isString)(this.pipeTo) : false;
|
|
247
250
|
const enabled = opts.connected?.call(this.client, headers) !== false && !pipeline;
|
|
248
251
|
const maxBufferSize = opts.maxBufferSize ? (0, types_1.alignSize)(opts.maxBufferSize) : 0;
|
|
@@ -349,7 +352,12 @@ class HttpAdapter {
|
|
|
349
352
|
result = new (require(packageName = 'fast-xml-parser').XMLParser)(parser).parse(buffer);
|
|
350
353
|
break;
|
|
351
354
|
case 'toml':
|
|
352
|
-
|
|
355
|
+
try {
|
|
356
|
+
result = require('smol-toml').parse(buffer, parser);
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
result = require(packageName = 'toml').parse(buffer);
|
|
360
|
+
}
|
|
353
361
|
break;
|
|
354
362
|
default:
|
|
355
363
|
result = JSON.parse(buffer);
|
|
@@ -367,6 +375,9 @@ class HttpAdapter {
|
|
|
367
375
|
}
|
|
368
376
|
}
|
|
369
377
|
}
|
|
378
|
+
else if (opts.outFormat) {
|
|
379
|
+
opts.outFormat = undefined;
|
|
380
|
+
}
|
|
370
381
|
if (result === undefined) {
|
|
371
382
|
result = buffer;
|
|
372
383
|
}
|
package/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const adapter_1 = require("@e-mc/request/http/adapter");
|
|
|
23
23
|
const kRequest = Symbol.for('request:constructor');
|
|
24
24
|
const SUPPORTED_NODE20 = (0, types_1.supported)(20);
|
|
25
25
|
const SUPPORTED_ZSTD = (0, types_1.supported)(23, 8) || (0, types_1.supported)(22, 15, 0, true);
|
|
26
|
+
const SUPPORTED_FILE = (0, types_1.supported)(19, 2) || (0, types_1.supported)(18, 13, true);
|
|
26
27
|
const REGEXP_PEMCERT = /^-{3,}[ \t]*BEGIN[ \t].+\n-{3,}[ \t]*END[ \t][^-]+-{3,}$/s;
|
|
27
28
|
const REGEXP_GLOBWITHIN = /\\\?|(?:(?<!\\)(?:\*|\[!?[^!\]]+\]|\{(?:[^,]+,)+[^}]+\}|[!?+*@]\((?:[^|]+\|)*[^)]+\)|\?.*\?|\?$))/;
|
|
28
29
|
const REGEXP_RCLONE = /^rclone:\?/i;
|
|
@@ -33,8 +34,8 @@ const HTTP = {
|
|
|
33
34
|
PROXY: null
|
|
34
35
|
};
|
|
35
36
|
const TLS = {
|
|
36
|
-
TEXT:
|
|
37
|
-
FILE:
|
|
37
|
+
TEXT: Object.create(null),
|
|
38
|
+
FILE: Object.create(null)
|
|
38
39
|
};
|
|
39
40
|
const DNS = {
|
|
40
41
|
CACHE: Object.create(null),
|
|
@@ -61,7 +62,7 @@ const ARIA2 = {
|
|
|
61
62
|
LOWEST_SPEED_LIMIT: null,
|
|
62
63
|
ALWAYS_RESUME: false,
|
|
63
64
|
FILE_ALLOCATION: 'none',
|
|
64
|
-
PROXY:
|
|
65
|
+
PROXY: Object.create(null),
|
|
65
66
|
NO_PROXY: '',
|
|
66
67
|
CONF_PATH: ''
|
|
67
68
|
};
|
|
@@ -116,21 +117,6 @@ try {
|
|
|
116
117
|
}
|
|
117
118
|
catch {
|
|
118
119
|
}
|
|
119
|
-
function getBaseHeaders(uri, headers) {
|
|
120
|
-
let result;
|
|
121
|
-
uri = (0, util_1.trimPath)(uri);
|
|
122
|
-
for (const pathname in headers) {
|
|
123
|
-
if (pathname === uri || uri.startsWith(pathname + '/')) {
|
|
124
|
-
(result ||= []).push([pathname, headers[pathname]]);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (result) {
|
|
128
|
-
if (result.length > 1) {
|
|
129
|
-
result.sort((a, b) => b[0].length - a[0].length);
|
|
130
|
-
}
|
|
131
|
-
return result[0][1];
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
120
|
function setDnsCache(hostname, value, expires) {
|
|
135
121
|
expires ??= DNS.EXPIRES;
|
|
136
122
|
if (expires > 0 && !DNS.CACHE[hostname]) {
|
|
@@ -175,11 +161,9 @@ function getProxySettings(request, agentTimeout) {
|
|
|
175
161
|
return null;
|
|
176
162
|
}
|
|
177
163
|
function closeTorrent(pid) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
ARIA2.PID_QUEUE.splice(index, 1);
|
|
182
|
-
}
|
|
164
|
+
const index = ARIA2.PID_QUEUE.findIndex(value => value[0] === pid);
|
|
165
|
+
if (index !== -1) {
|
|
166
|
+
ARIA2.PID_QUEUE.splice(index, 1);
|
|
183
167
|
}
|
|
184
168
|
}
|
|
185
169
|
function clearDnsLookup() {
|
|
@@ -201,7 +185,7 @@ function resetHttpHost(version) {
|
|
|
201
185
|
const host = HTTP.HOST[origin];
|
|
202
186
|
if (host.secure && host.version === 1) {
|
|
203
187
|
const failed = host.failed(2, true);
|
|
204
|
-
if (failed === 0 && host.
|
|
188
|
+
if (failed === 0 && host.error(2, true) < 10 || failed < 3 && host.success(2, true) > 0) {
|
|
205
189
|
host.version = version;
|
|
206
190
|
}
|
|
207
191
|
}
|
|
@@ -362,8 +346,10 @@ function decompressEncoding(value, chunkSize) {
|
|
|
362
346
|
}
|
|
363
347
|
}
|
|
364
348
|
function resetAria2() {
|
|
365
|
-
|
|
366
|
-
|
|
349
|
+
if (ARIA2.PID_TIMER) {
|
|
350
|
+
clearInterval(ARIA2.PID_TIMER);
|
|
351
|
+
ARIA2.PID_TIMER = null;
|
|
352
|
+
}
|
|
367
353
|
}
|
|
368
354
|
function escapeShellQuote(value) {
|
|
369
355
|
value = value.replace(/(?<!\\)"/g, '\\"');
|
|
@@ -846,9 +832,9 @@ class Request extends module_1 {
|
|
|
846
832
|
};
|
|
847
833
|
#singleton = false;
|
|
848
834
|
#httpVersion = null;
|
|
835
|
+
#headers = null;
|
|
849
836
|
#ipVersion;
|
|
850
837
|
#agentTimeout;
|
|
851
|
-
#headers = null;
|
|
852
838
|
#baseUrl = null;
|
|
853
839
|
#connectDns = Object.create(null);
|
|
854
840
|
#pendingDns = Object.create(null);
|
|
@@ -858,7 +844,7 @@ class Request extends module_1 {
|
|
|
858
844
|
#adapter = HTTP_ADAPTER;
|
|
859
845
|
#certs = null;
|
|
860
846
|
#downloading = new Set();
|
|
861
|
-
#hostInfo =
|
|
847
|
+
#hostInfo = Object.create(null);
|
|
862
848
|
#session = [Object.create(null)];
|
|
863
849
|
constructor(data) {
|
|
864
850
|
super();
|
|
@@ -884,9 +870,7 @@ class Request extends module_1 {
|
|
|
884
870
|
if (proxy) {
|
|
885
871
|
this.proxy = proxy;
|
|
886
872
|
}
|
|
887
|
-
|
|
888
|
-
setOutgoingHeaders(this.#headers = {}, headers);
|
|
889
|
-
}
|
|
873
|
+
this.parseHeaders(headers);
|
|
890
874
|
if ((0, types_1.isObject)(certs)) {
|
|
891
875
|
this.#certs = validateCerts(certs);
|
|
892
876
|
}
|
|
@@ -994,9 +978,7 @@ class Request extends module_1 {
|
|
|
994
978
|
init(config) {
|
|
995
979
|
if (config) {
|
|
996
980
|
const { headers, httpVersion, ipVersion, readTimeout } = config;
|
|
997
|
-
|
|
998
|
-
setOutgoingHeaders(this.#headers ||= {}, headers);
|
|
999
|
-
}
|
|
981
|
+
this.parseHeaders(headers);
|
|
1000
982
|
if (httpVersion !== undefined) {
|
|
1001
983
|
this.httpVersion = httpVersion;
|
|
1002
984
|
}
|
|
@@ -1220,8 +1202,7 @@ class Request extends module_1 {
|
|
|
1220
1202
|
}
|
|
1221
1203
|
}
|
|
1222
1204
|
headersOf(uri) {
|
|
1223
|
-
|
|
1224
|
-
return headers && getBaseHeaders(uri, headers) || (this.host ? getBaseHeaders(uri, HTTP.HEADERS) : undefined);
|
|
1205
|
+
return this.findHeadersByUri(uri) || (this.host ? this.findHeadersByUri(uri, HTTP.HEADERS) : undefined);
|
|
1225
1206
|
}
|
|
1226
1207
|
async aria2c(uri, options = {}) {
|
|
1227
1208
|
if (!ARIA2.BIN) {
|
|
@@ -1238,15 +1219,10 @@ class Request extends module_1 {
|
|
|
1238
1219
|
({ signal, silent } = options);
|
|
1239
1220
|
({ pathname, headers, binOpts } = this.parseBinOpts(options, ['--daemon'], ['--input-file'], options.shellExpansion));
|
|
1240
1221
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
uri = new URL(uri);
|
|
1244
|
-
}
|
|
1245
|
-
pathname = checkBinTarget(this, "aria2", uri, pathname, 'aria2', binOpts);
|
|
1246
|
-
}
|
|
1247
|
-
catch (err) {
|
|
1248
|
-
return Promise.reject(err);
|
|
1222
|
+
if ((0, types_1.isString)(uri) && module_1.isURL(uri)) {
|
|
1223
|
+
uri = new URL(uri);
|
|
1249
1224
|
}
|
|
1225
|
+
pathname = checkBinTarget(this, "aria2", uri, pathname, 'aria2', binOpts);
|
|
1250
1226
|
silent ??= this.#singleton;
|
|
1251
1227
|
return new Promise((resolve, reject) => {
|
|
1252
1228
|
let protocol, origin, username, password;
|
|
@@ -1511,12 +1487,7 @@ class Request extends module_1 {
|
|
|
1511
1487
|
default:
|
|
1512
1488
|
return Promise.reject((0, types_1.errorMessage)("rclone", "Invalid command", command || uri));
|
|
1513
1489
|
}
|
|
1514
|
-
|
|
1515
|
-
pathname = checkBinTarget(this, "rclone", uri, pathname, command, binOpts);
|
|
1516
|
-
}
|
|
1517
|
-
catch (err) {
|
|
1518
|
-
return Promise.reject(err);
|
|
1519
|
-
}
|
|
1490
|
+
pathname = checkBinTarget(this, "rclone", uri, pathname, command, binOpts);
|
|
1520
1491
|
silent ??= this.#singleton;
|
|
1521
1492
|
return new Promise((resolve, reject) => {
|
|
1522
1493
|
const init = [
|
|
@@ -1710,6 +1681,21 @@ class Request extends module_1 {
|
|
|
1710
1681
|
options.format = 'json';
|
|
1711
1682
|
return this.get(uri, options);
|
|
1712
1683
|
}
|
|
1684
|
+
async blob(uri, options = {}) {
|
|
1685
|
+
options.outContentType = undefined;
|
|
1686
|
+
options.outFilename = undefined;
|
|
1687
|
+
options.outBlob = true;
|
|
1688
|
+
const data = await this.get(uri, options);
|
|
1689
|
+
if (!data) {
|
|
1690
|
+
return null;
|
|
1691
|
+
}
|
|
1692
|
+
const format = options.outFormat?.out;
|
|
1693
|
+
const type = { type: format ? 'application/' + format : options.outContentType || (typeof data === 'string' ? 'text/plain' : undefined) };
|
|
1694
|
+
if (SUPPORTED_FILE && options.outFilename) {
|
|
1695
|
+
return new File([Buffer.from(data)], path.basename(options.outFilename), type);
|
|
1696
|
+
}
|
|
1697
|
+
return new Blob([Buffer.from(data)], type);
|
|
1698
|
+
}
|
|
1713
1699
|
async pipe(uri, to, options = {}) {
|
|
1714
1700
|
options.pipeTo = to;
|
|
1715
1701
|
return this.get(uri, options);
|
|
@@ -1777,7 +1763,9 @@ class Request extends module_1 {
|
|
|
1777
1763
|
}
|
|
1778
1764
|
headers.accept += ', text/plain';
|
|
1779
1765
|
options.encoding = (0, types_1.getEncoding)(encoding);
|
|
1780
|
-
options.
|
|
1766
|
+
if (!options.outBlob) {
|
|
1767
|
+
options.outFormat = { out: format, parser };
|
|
1768
|
+
}
|
|
1781
1769
|
}
|
|
1782
1770
|
if (typeof uri !== 'string') {
|
|
1783
1771
|
url = uri;
|
|
@@ -1942,7 +1930,7 @@ class Request extends module_1 {
|
|
|
1942
1930
|
try {
|
|
1943
1931
|
keepAlive ??= proxy.keepAlive;
|
|
1944
1932
|
agentTimeout ??= proxy.agentTimeout;
|
|
1945
|
-
const proxyHeaders = this
|
|
1933
|
+
const proxyHeaders = this.findHeadersByUri(proxy.host.href) || this.findHeadersByUri(proxy.host.href, HTTP.HEADERS);
|
|
1946
1934
|
agent = require(pkg)(proxy.host, (typeof keepAlive === 'boolean' || agentTimeout > 0) && agentTimeout !== 0 ? { keepAlive: keepAlive ?? true, timeout: agentTimeout, headers: proxyHeaders } : { headers: proxyHeaders });
|
|
1947
1935
|
}
|
|
1948
1936
|
catch (err) {
|
|
@@ -2391,7 +2379,7 @@ class Request extends module_1 {
|
|
|
2391
2379
|
}
|
|
2392
2380
|
if ((0, types_1.isArray)(options.binOpts)) {
|
|
2393
2381
|
let next = false;
|
|
2394
|
-
binOpts = options.binOpts.filter((opt) => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt
|
|
2382
|
+
binOpts = options.binOpts.filter((opt) => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt))).map((opt) => {
|
|
2395
2383
|
if (next) {
|
|
2396
2384
|
if (!module_1.asString(opt).startsWith('--')) {
|
|
2397
2385
|
return [];
|
|
@@ -2441,6 +2429,26 @@ class Request extends module_1 {
|
|
|
2441
2429
|
}
|
|
2442
2430
|
return { pathname, headers: (0, util_1.parseOutgoingHeaders)(options.headers), binOpts };
|
|
2443
2431
|
}
|
|
2432
|
+
parseHeaders(outgoing) {
|
|
2433
|
+
if ((0, types_1.isObject)(outgoing)) {
|
|
2434
|
+
setOutgoingHeaders(this.#headers ||= {}, outgoing);
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
findHeadersByUri(uri, outgoing = this.#headers) {
|
|
2438
|
+
if (outgoing) {
|
|
2439
|
+
const result = [];
|
|
2440
|
+
uri = (0, util_1.trimPath)(uri);
|
|
2441
|
+
for (const pathname in outgoing) {
|
|
2442
|
+
if (pathname === uri || uri.startsWith(pathname + '/')) {
|
|
2443
|
+
result.push([pathname, outgoing[pathname]]);
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
if (result.length > 0) {
|
|
2447
|
+
result.sort((a, b) => b[0].length - a[0].length);
|
|
2448
|
+
return result[0][1];
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2444
2452
|
set adapter(value) {
|
|
2445
2453
|
if (isConstructor(value) && value.prototype instanceof adapter_1) {
|
|
2446
2454
|
this.#adapter = value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/request",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.16",
|
|
4
4
|
"description": "Request constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"license": "BSD-3-Clause",
|
|
20
20
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@e-mc/module": "0.12.
|
|
23
|
-
"@e-mc/types": "0.12.
|
|
22
|
+
"@e-mc/module": "0.12.16",
|
|
23
|
+
"@e-mc/types": "0.12.16",
|
|
24
24
|
"combined-stream": "^1.0.8",
|
|
25
25
|
"js-yaml": "^4.1.1",
|
|
26
|
-
"picomatch": "^4.0.
|
|
26
|
+
"picomatch": "^4.0.4",
|
|
27
27
|
"which": "^4.0.0"
|
|
28
28
|
}
|
|
29
29
|
}
|
package/util.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ declare namespace util {
|
|
|
13
13
|
function hasBasicAuth(value: string): boolean;
|
|
14
14
|
function checkRetryable(err: unknown): boolean;
|
|
15
15
|
function isRetryable(value: number, timeout?: boolean): boolean;
|
|
16
|
-
function parseHttpProxy(value?: string): HttpProxySettings | undefined;
|
|
17
|
-
function trimPath(value: string): string;
|
|
16
|
+
function parseHttpProxy(value?: string, ignoreEnv?: boolean): HttpProxySettings | undefined;
|
|
17
|
+
function trimPath(value: string, char?: string): string;
|
|
18
18
|
function asInt(value: unknown): number;
|
|
19
19
|
function asFloat(value: unknown): number;
|
|
20
20
|
function fromSeconds(value: unknown): number;
|
package/util.js
CHANGED
|
@@ -182,9 +182,11 @@ function parseHttpProxy(value, ignoreEnv) {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
function trimPath(value) {
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
function trimPath(value, char = '/') {
|
|
186
|
+
while (value.at(-1) === char) {
|
|
187
|
+
value = value.slice(0, -1);
|
|
188
|
+
}
|
|
189
|
+
return value;
|
|
188
190
|
}
|
|
189
191
|
function asInt(value) {
|
|
190
192
|
switch (typeof value) {
|