@e-mc/request 0.8.10 → 0.9.1

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/LICENSE CHANGED
@@ -1,7 +1,11 @@
1
1
  Copyright 2024 An Pham
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
4
 
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
6
 
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @e-mc/request
2
2
 
3
- * NodeJS 14
4
- * ES2019
3
+ * NodeJS 16
4
+ * ES2020
5
5
 
6
6
  ## General Usage
7
7
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## Interface
11
11
 
12
- - https://www.unpkg.com/@e-mc/types@0.8.10/lib/index.d.ts
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.9.1/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { IModule, ModuleConstructor } from "./index";
@@ -32,13 +32,13 @@ interface IRequest extends IModule {
32
32
  init(config?: RequestInit): this;
33
33
  apply(options: ApplyOptions): this;
34
34
  addDns(hostname: string, address: string, timeout: number): void;
35
- addDns(hostname: string, address: string, family?: number | string, timeout?: number): void;
35
+ addDns(hostname: string, address: string, family?: string, timeout?: number): void;
36
36
  lookupDns(hostname: string): LookupFunction;
37
37
  proxyOf(uri: string, localhost?: boolean): ProxySettings | undefined;
38
38
  statusOn(name: number | number[], callback: StatusOnCallback): void;
39
- statusOn(name: number | number[], patternUrl: string, callback: StatusOnCallback): void;
39
+ statusOn(name: number | number[], globUrl: string, callback: StatusOnCallback): void;
40
40
  headersOn(name: string | string[], callback: HeadersOnCallback): void;
41
- headersOn(name: string | string[], patternUrl: string, callback: HeadersOnCallback): void;
41
+ headersOn(name: string | string[], globUrl: string, callback: HeadersOnCallback): void;
42
42
  headersOf(uri: string): OutgoingHttpHeaders | undefined;
43
43
  aria2c(uri: string | URL, pathname: string): Promise<string[]>;
44
44
  aria2c(uri: string | URL, options?: Aria2Options): Promise<string[]>;
@@ -80,12 +80,133 @@ interface RequestConstructor extends ModuleConstructor {
80
80
  }
81
81
  ```
82
82
 
83
+ ## Settings
84
+
85
+ ```typescript
86
+ import type { PermittedDirectories } from "./core";
87
+ import type { SecureConfig } from "./http";
88
+ import type { PurgeComponent } from "./settings";
89
+
90
+ import type { LookupAddress } from "dns";
91
+ import type { OutgoingHttpHeaders } from "http";
92
+
93
+ interface RequestModule {
94
+ handler: "@e-mc/request";
95
+ timeout?: number | string;
96
+ read_timeout?: number | string;
97
+ agent?: {
98
+ keep_alive?: boolean;
99
+ timeout?: number | string;
100
+ };
101
+ connect?: {
102
+ timeout?: number | string;
103
+ retry_wait?: number | string;
104
+ retry_after?: number | string;
105
+ retry_limit?: number;
106
+ redirect_limit?: number;
107
+ };
108
+ dns?: {
109
+ family?: number;
110
+ expires?: number | string;
111
+ resolve?: Record<string, Partial<LookupAddress>>;
112
+ };
113
+ use?: {
114
+ http_version?: 1 | 2;
115
+ accept_encoding?: boolean;
116
+ };
117
+ proxy?: {
118
+ address?: string;
119
+ port?: number;
120
+ username?: string;
121
+ password?: string;
122
+ include?: string[];
123
+ exclude?: string[];
124
+ keep_alive?: boolean;
125
+ };
126
+ headers: Record<string, OutgoingHttpHeaders>;
127
+ certs?: Record<string, SecureConfig<string | string[]>>;
128
+ localhost?: string[];
129
+ protocol?: {
130
+ "http/1.1"?: string[];
131
+ h2c?: string[];
132
+ h2?: string[];
133
+ };
134
+ post_limit?: number | string;
135
+ settings?: {
136
+ broadcast_id?: string | string[];
137
+ time_format?: "readable" | "relative" | "none";
138
+ purge?: PurgeComponent;
139
+ }
140
+ }
141
+
142
+ interface DownloadModule {
143
+ expires?: number | string;
144
+ aria2?: {
145
+ bin?: string | false;
146
+ exec?: {
147
+ uid?: number;
148
+ gid?: number;
149
+ };
150
+ update_status?: number | { interval?: number; broadcast_only?: boolean };
151
+ max_concurrent_downloads?: number;
152
+ max_connection_per_server?: number;
153
+ bt_stop_timeout?: number;
154
+ bt_tracker_connect_timeout?: number;
155
+ bt_tracker_timeout?: number;
156
+ min_split_size?: string;
157
+ disk_cache?: number | string;
158
+ lowest_speed_limit?: number | string;
159
+ always_resume?: boolean;
160
+ file_allocation?: "none" | "prealloc" | "trunc" | "falloc";
161
+ conf_path?: string;
162
+ };
163
+ }
164
+ ```
165
+
166
+ ### Example usage
167
+
168
+ ```javascript
169
+ const Request = require("@e-mc/request");
170
+
171
+ const instance = new Request({
172
+ read_timeout: 30,
173
+ connect: {
174
+ timeout: 20, // Seconds
175
+ retry_wait: 1,
176
+ retry_after: 30,
177
+ retry_limit: 3, // Max attempts
178
+ redirect_limit: 10
179
+ },
180
+ use: {
181
+ http_version: 2,
182
+ accept_encoding: true
183
+ },
184
+ dns: {
185
+ family: 4 // ipVersion
186
+ },
187
+ agent: { keep_alive: true }
188
+ });
189
+ request.init({ ipVersion: 6 });
190
+
191
+ const options = {
192
+ format: "yaml",
193
+ httpVersion: 1,
194
+ silent: true,
195
+ headers: { "x-goog-user-project": "project-1" }
196
+ };
197
+ instance.get("http://hostname/path/config.yml", options).then(data => {
198
+ console.log(data.property);
199
+ });
200
+ ```
201
+
83
202
  ## References
84
203
 
85
- - https://www.unpkg.com/@e-mc/types@0.8.10/lib/http.d.ts
86
- - https://www.unpkg.com/@e-mc/types@0.8.10/lib/request.d.ts
87
- - https://www.unpkg.com/@e-mc/types@0.8.10/lib/settings.d.ts
204
+ - https://www.unpkg.com/@e-mc/types@0.9.1/lib/http.d.ts
205
+ - https://www.unpkg.com/@e-mc/types@0.9.1/lib/request.d.ts
206
+ - https://www.unpkg.com/@e-mc/types@0.9.1/lib/settings.d.ts
207
+
208
+ * https://www.npmjs.com/package/@types/node
88
209
 
89
210
  ## LICENSE
90
211
 
91
- MIT
212
+ BSD 3-Clause
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  var _a, _b, _c, _d;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
3
  const tls = require("tls");
5
- const types_1 = require("@e-mc/types");
6
4
  const kProtocol = Symbol('protocol');
7
5
  const kSecure = Symbol('secure');
8
6
  const kHostname = Symbol('hostname');
@@ -27,7 +25,7 @@ const HOST_ALPN_H2 = [];
27
25
  })();
28
26
  class HttpHost {
29
27
  static normalizeOrigin(value) {
30
- return value.replace(/\/+$/, '') + (!/:\d+$/.test(value) ? ':' + (value.startsWith('https') ? '443' : '80') : '');
28
+ return (value = value.trim()).replace(/\/+$/, '') + (!/:\d+$/.test(value) ? ':' + (value.startsWith('https') ? '443' : '80') : '');
31
29
  }
32
30
  static formatBasicAuth(url) {
33
31
  return url.username ? decodeURIComponent(url.username) + (url.password ? ':' + decodeURIComponent(url.password) : '') : '';
@@ -40,19 +38,19 @@ class HttpHost {
40
38
  }
41
39
  static defineLocalHost(value) {
42
40
  HOST_LOCAL.clear();
43
- value.forEach(address => (0, types_1.isString)(address) && HOST_LOCAL.add(address.trim()));
41
+ value.forEach(address => HOST_LOCAL.add(address));
44
42
  }
45
43
  static defineProtocolNegotiation(value) {
46
44
  const { h2c, h2 } = value;
47
45
  const http11 = value['http/1.1'];
48
46
  if (Array.isArray(http11)) {
49
- HOST_HTTP_1_1.push(...http11.map(address => this.normalizeOrigin(address.trim())));
47
+ HOST_HTTP_1_1.push(...http11.map(address => this.normalizeOrigin(address)));
50
48
  }
51
49
  if (Array.isArray(h2c)) {
52
- HOST_ALPN_H2C.push(...h2c.map(address => this.normalizeOrigin(address.trim())));
50
+ HOST_ALPN_H2C.push(...h2c.map(address => this.normalizeOrigin(address)));
53
51
  }
54
52
  if (Array.isArray(h2)) {
55
- HOST_ALPN_H2.push(...h2.map(address => this.normalizeOrigin(address.trim())));
53
+ HOST_ALPN_H2.push(...h2.map(address => this.normalizeOrigin(address)));
56
54
  }
57
55
  }
58
56
  constructor(url, httpVersion = 1) {
@@ -154,7 +152,6 @@ class HttpHost {
154
152
  return ++data[2];
155
153
  }
156
154
  upgrade(version, altSvc) {
157
- var _e;
158
155
  if (altSvc && this.secure) {
159
156
  if (altSvc === 'clear') {
160
157
  this.clearAltSvc();
@@ -174,13 +171,11 @@ class HttpHost {
174
171
  }
175
172
  return false;
176
173
  };
177
- const pattern = new RegExp(`h${i + 1}(?:-\\d+)?="([^:]*):(\\d+)"([^,]*)`, 'g');
178
174
  const addresses = [];
179
175
  const time = Date.now();
180
176
  const hostname = this[kHostname];
181
177
  const excluded = this[kAltSvcError];
182
- let match;
183
- while (match = pattern.exec(altSvc)) {
178
+ for (const match of altSvc.matchAll(new RegExp(`h${i + 1}(?:-\\d+)?="([^:]*):(\\d+)"([^,]*)`, 'g'))) {
184
179
  const port = match[2];
185
180
  if (!match[1] && port === this.port) {
186
181
  increment(2);
@@ -188,7 +183,7 @@ class HttpHost {
188
183
  break;
189
184
  }
190
185
  const address = match[1] || hostname;
191
- const ma = +(((_e = /ma=(\d+)/.exec(match[3])) === null || _e === void 0 ? void 0 : _e[1]) || 86400);
186
+ const ma = +(/ma=(\d+)/.exec(match[3])?.[1] || 86400);
192
187
  if (!excluded.includes(`h${i + 1}:${address}:${port}`)) {
193
188
  addresses.push([
194
189
  address,
@@ -328,9 +323,5 @@ class HttpHost {
328
323
  }
329
324
  }
330
325
  _a = kVersionData, _b = kAltSvc, _c = kAltSvcQueue, _d = kAltSvcError;
331
- exports.default = HttpHost;
332
326
 
333
- if (exports.default) {
334
- module.exports = exports.default;
335
- module.exports.default = exports.default;
336
- }
327
+ module.exports = HttpHost;
package/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
3
  const path = require("path");
5
4
  const fs = require("fs");
6
5
  const child_process = require("child_process");
@@ -16,7 +15,6 @@ const combined = require("combined-stream");
16
15
  const pm = require("picomatch");
17
16
  const yaml = require("js-yaml");
18
17
  const which = require("which");
19
- const lib_v4_1 = require("@e-mc/module/lib-v4");
20
18
  const types_1 = require("@e-mc/types");
21
19
  const module_1 = require("@e-mc/module");
22
20
  const host_1 = require("@e-mc/request/http/host");
@@ -36,8 +34,7 @@ const kConnectHttp = Symbol('connectHttp');
36
34
  const kStatusOn = Symbol('statusOn');
37
35
  const kHeadersOn = Symbol('headersOn');
38
36
  const PLATFORM_WIN32 = process.platform === 'win32';
39
- const SUPPORT_NODEJS20 = module_1.default.supported(20);
40
- const SUPPORT_ABORTSIGNAL = module_1.default.supported(15, 4);
37
+ const SUPPORT_NODEJS20 = module_1.supported(20);
41
38
  const HTTP = {
42
39
  HOST: {},
43
40
  HEADERS: {},
@@ -106,7 +103,7 @@ function getBaseHeaders(uri, headers) {
106
103
  }
107
104
  }
108
105
  function setDnsCache(hostname, value, expires) {
109
- expires !== null && expires !== void 0 ? expires : (expires = DNS.EXPIRES);
106
+ expires ?? (expires = DNS.EXPIRES);
110
107
  if (expires > 0 && !DNS.CACHE[hostname]) {
111
108
  DNS.CACHE[hostname] = value;
112
109
  if (expires !== Infinity) {
@@ -137,12 +134,12 @@ function setOutgoingHeaders(output, headers) {
137
134
  }
138
135
  function getProxySettings(request, agentTimeout) {
139
136
  const proxy = request.proxy;
140
- if ((proxy === null || proxy === void 0 ? void 0 : proxy.address) && proxy.port) {
137
+ if (proxy?.address && proxy.port) {
141
138
  const port = (0, util_1.asInt)(proxy.port);
142
- const address = (!module_1.default.isURL(proxy.address) ? port === 80 ? 'http://' : 'https://' : '') + proxy.address;
139
+ const address = (!module_1.isURL(proxy.address) ? port === 80 ? 'http://' : 'https://' : '') + proxy.address;
143
140
  try {
144
141
  let host = new URL(address + ':' + port), include, exclude;
145
- if ((0, types_1.isString)(proxy.username)) {
142
+ if (proxy.username) {
146
143
  host = new URL(host.protocol + '//' + (0, util_1.getBasicAuth)(proxy.username, proxy.password) + host.host);
147
144
  }
148
145
  if ((0, types_1.isArray)(proxy.include)) {
@@ -199,7 +196,7 @@ function validateCerts(certs) {
199
196
  const file = {};
200
197
  const checkFile = (values) => {
201
198
  for (let pathname of values) {
202
- if (module_1.default.isPath(pathname = path.resolve(pathname))) {
199
+ if (module_1.isPath(pathname = path.resolve(pathname))) {
203
200
  return pathname;
204
201
  }
205
202
  }
@@ -270,7 +267,7 @@ function abortHeaders(href, request, options) {
270
267
  }
271
268
  request.destroy(reason);
272
269
  }
273
- class Request extends module_1.default {
270
+ class Request extends module_1 {
274
271
  static async purgeMemory(percent = 1, limit = 0, parent) {
275
272
  if (percent >= 1) {
276
273
  resetHttpHost();
@@ -285,7 +282,6 @@ class Request extends module_1.default {
285
282
  return parent ? super.purgeMemory(percent, limit) : 0;
286
283
  }
287
284
  static loadSettings(settings, password) {
288
- var _o;
289
285
  if (this.enabled("process.password") && !super.loadSettings({ process: settings.process }, password)) {
290
286
  return false;
291
287
  }
@@ -404,7 +400,7 @@ class Request extends module_1.default {
404
400
  [TLS.TEXT, TLS.FILE] = validateCerts(certs);
405
401
  }
406
402
  HTTP.PROXY = getProxySettings(request, agent_timeout);
407
- const time_format = (_o = request.settings) === null || _o === void 0 ? void 0 : _o.time_format;
403
+ const time_format = request.settings?.time_format;
408
404
  switch (time_format) {
409
405
  case 'readable':
410
406
  case 'relative':
@@ -415,7 +411,7 @@ class Request extends module_1.default {
415
411
  }
416
412
  LOG_HTTP = this.hasLogType(1024);
417
413
  LOG_TIMEPROCESS = this.hasLogType(256);
418
- LOG_STDOUT = module_1.default.hasLogType(32768);
414
+ LOG_STDOUT = module_1.hasLogType(32768);
419
415
  return true;
420
416
  }
421
417
  static readCACert(value, cache) {
@@ -434,7 +430,7 @@ class Request extends module_1.default {
434
430
  if (this.isURL(value)) {
435
431
  return value;
436
432
  }
437
- const auth = host_1.default.formatBasicAuth(url);
433
+ const auth = host_1.formatBasicAuth(url);
438
434
  return url.protocol + '//' + (auth && (auth + '@')) + url.hostname + (url.port ? ':' + url.port : '') + (value.startsWith('/') ? '' : '/') + value;
439
435
  }
440
436
  static fromStatusCode(value) {
@@ -629,7 +625,6 @@ class Request extends module_1.default {
629
625
  return ARIA2.BIN;
630
626
  }
631
627
  constructor(data) {
632
- var _o;
633
628
  super();
634
629
  this.startTime = Date.now();
635
630
  this.readExpect = 'none';
@@ -661,13 +656,13 @@ class Request extends module_1.default {
661
656
  const timeout = (0, util_1.fromSeconds)(data.timeout);
662
657
  let value;
663
658
  this.readTimeout = (value = (0, util_1.fromSeconds)(read_timeout)) >= 0 ? value : READ_TIMEOUT;
664
- this.keepAlive = typeof (value = agent === null || agent === void 0 ? void 0 : agent.keep_alive) === 'boolean' ? value : KEEP_ALIVE;
665
- this.acceptEncoding = typeof (value = use === null || use === void 0 ? void 0 : use.accept_encoding) === 'boolean' ? value : ACCEPT_ENCODING;
666
- if ((value = (0, util_1.asInt)(use === null || use === void 0 ? void 0 : use.http_version)) === 1 || value === 2) {
659
+ this.keepAlive = typeof (value = agent?.keep_alive) === 'boolean' ? value : KEEP_ALIVE;
660
+ this.acceptEncoding = typeof (value = use?.accept_encoding) === 'boolean' ? value : ACCEPT_ENCODING;
661
+ if ((value = (0, util_1.asInt)(use?.http_version)) === 1 || value === 2) {
667
662
  this[kHttpVersion] = value;
668
663
  }
669
- this[kIpVersion] = (value = (0, util_1.asInt)((_o = data.dns) === null || _o === void 0 ? void 0 : _o.family)) && (value === 4 || value === 6) ? value : 0;
670
- if ((value = (0, util_1.fromSeconds)(agent === null || agent === void 0 ? void 0 : agent.timeout)) >= 0) {
664
+ this[kIpVersion] = (value = (0, util_1.asInt)(data.dns?.family)) && (value === 4 || value === 6) ? value : 0;
665
+ if ((value = (0, util_1.fromSeconds)(agent?.timeout)) >= 0) {
671
666
  this[kAgentTimeout] = value;
672
667
  }
673
668
  else {
@@ -709,13 +704,12 @@ class Request extends module_1.default {
709
704
  this.module = data;
710
705
  }
711
706
  flushLog() {
712
- var _o;
713
707
  const log = this._logQueued;
714
708
  if (this[kSingleton]) {
715
709
  log.length = 0;
716
710
  }
717
711
  else {
718
- if (log.length && !((_o = this.host) === null || _o === void 0 ? void 0 : _o.aborted)) {
712
+ if (log.length && !this.host?.aborted) {
719
713
  const output = [];
720
714
  let count = 0;
721
715
  this[kConnectHttp].forEach((protocol, index) => {
@@ -748,19 +742,19 @@ class Request extends module_1.default {
748
742
  const width = count.toString().length;
749
743
  output.forEach(item => {
750
744
  const [title, origin, downloads, messages] = item;
751
- const options = { ...title === 'HTTP1' ? module_1.default.LOG_STYLE_NOTICE : module_1.default.LOG_STYLE_INFO };
745
+ const options = { ...title === 'HTTP1' ? module_1.LOG_STYLE_NOTICE : module_1.LOG_STYLE_INFO };
752
746
  if (messages.length === 1) {
753
747
  const message = messages[0];
754
748
  message[1] = title;
755
749
  message[2] = [origin + message[2][0], message[2][1]];
756
750
  message[4] = Object.assign(message[4], options);
757
- module_1.default.formatMessage(...message);
751
+ module_1.formatMessage(...message);
758
752
  }
759
753
  else {
760
754
  this.formatMessage(1024, title, [origin, 'downloads: ' + downloads.toString().padStart(width)], '', options);
761
755
  messages.forEach(args => {
762
756
  args[4].titleIndent = true;
763
- module_1.default.formatMessage(...args);
757
+ module_1.formatMessage(...args);
764
758
  });
765
759
  }
766
760
  });
@@ -787,7 +781,7 @@ class Request extends module_1.default {
787
781
  }
788
782
  init(config) {
789
783
  if (config) {
790
- const { headers, httpVersion, ipVersion, requestTimeout, readTimeout = requestTimeout } = config;
784
+ const { headers, httpVersion, ipVersion, readTimeout } = config;
791
785
  if ((0, types_1.isObject)(headers)) {
792
786
  setOutgoingHeaders(this[kHeaders] || (this[kHeaders] = {}), headers);
793
787
  }
@@ -822,7 +816,7 @@ class Request extends module_1.default {
822
816
  this._config.retryWait = Math.min(retryWait, 600 * 1000);
823
817
  }
824
818
  if (retryAfter >= 0) {
825
- this._config.retryAfter = Math.min(retryAfter, module_1.default.MAX_TIMEOUT);
819
+ this._config.retryAfter = Math.min(retryAfter, module_1.MAX_TIMEOUT);
826
820
  }
827
821
  if (retryLimit >= 0) {
828
822
  this._config.retryLimit = retryLimit;
@@ -998,7 +992,7 @@ class Request extends module_1.default {
998
992
  if (!ARIA2.BIN) {
999
993
  return Promise.reject((0, types_1.errorMessage)("aria2", "Binary not found"));
1000
994
  }
1001
- if (typeof uri === 'string' && module_1.default.isURL(uri)) {
995
+ if (typeof uri === 'string' && module_1.isURL(uri)) {
1002
996
  try {
1003
997
  uri = new URL(uri);
1004
998
  }
@@ -1017,7 +1011,7 @@ class Request extends module_1.default {
1017
1011
  let next = false;
1018
1012
  binOpts = binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z][\S\s]*$/i.test(opt.trim()))).map((opt) => {
1019
1013
  if (next) {
1020
- if (!module_1.default.asString(opt).startsWith('--')) {
1014
+ if (!module_1.asString(opt).startsWith('--')) {
1021
1015
  return [];
1022
1016
  }
1023
1017
  next = false;
@@ -1039,12 +1033,12 @@ class Request extends module_1.default {
1039
1033
  }
1040
1034
  break;
1041
1035
  default:
1042
- return match[3] ? [match[1], module_1.default.sanitizeArgs(match[3])] : [match[1]];
1036
+ return match[3] ? [match[1], module_1.sanitizeArgs(match[3])] : [match[1]];
1043
1037
  }
1044
1038
  }
1045
1039
  }
1046
1040
  else if (value) {
1047
- return [module_1.default.sanitizeArgs(value)];
1041
+ return [module_1.sanitizeArgs(value)];
1048
1042
  }
1049
1043
  break;
1050
1044
  }
@@ -1053,7 +1047,7 @@ class Request extends module_1.default {
1053
1047
  return [opt.toString()];
1054
1048
  default:
1055
1049
  if ((0, types_1.isArray)(opt)) {
1056
- return opt.filter(item => (0, types_1.isString)(item)).map((item) => module_1.default.sanitizeArgs(item));
1050
+ return opt.filter(item => (0, types_1.isString)(item)).map((item) => module_1.sanitizeArgs(item));
1057
1051
  }
1058
1052
  break;
1059
1053
  }
@@ -1062,7 +1056,7 @@ class Request extends module_1.default {
1062
1056
  }
1063
1057
  }
1064
1058
  }
1065
- if (!(0, types_1.isString)(pathname)) {
1059
+ if (!pathname) {
1066
1060
  if (this.host) {
1067
1061
  return Promise.reject((0, types_1.errorMessage)("aria2", "Invalid parameters", 'pathname'));
1068
1062
  }
@@ -1071,12 +1065,11 @@ class Request extends module_1.default {
1071
1065
  if ((this.host || this.hasOwnPermission()) && !this.canWrite(pathname = path.resolve(pathname.trim()))) {
1072
1066
  return Promise.reject((0, types_1.errorMessage)("aria2", "Unsupported access", pathname));
1073
1067
  }
1074
- if (!module_1.default.createDir(pathname)) {
1068
+ if (!module_1.createDir(pathname)) {
1075
1069
  return Promise.reject((0, types_1.errorMessage)("aria2", "Path is not a directory", pathname));
1076
1070
  }
1077
- silent !== null && silent !== void 0 ? silent : (silent = this[kSingleton]);
1071
+ silent ?? (silent = this[kSingleton]);
1078
1072
  return new Promise((resolve, reject) => {
1079
- var _o;
1080
1073
  let protocol, origin, username, password;
1081
1074
  if (uri instanceof URL) {
1082
1075
  ({ protocol, origin, username, password, href: uri } = uri);
@@ -1134,7 +1127,7 @@ class Request extends module_1.default {
1134
1127
  '--file-allocation=' + ARIA2.FILE_ALLOCATION,
1135
1128
  '--max-tries=' + (retryLimit + 1)
1136
1129
  ];
1137
- const ignoreOpt = (...values) => !(binOpts === null || binOpts === void 0 ? void 0 : binOpts.some(item => values.includes(item)));
1130
+ const ignoreOpt = (...values) => !binOpts?.some(item => values.includes(item));
1138
1131
  if (ARIA2.MAX_CONCURRENT_DOWNLOADS) {
1139
1132
  opts.push('--max-concurrent-downloads=' + ARIA2.MAX_CONCURRENT_DOWNLOADS);
1140
1133
  }
@@ -1183,7 +1176,7 @@ class Request extends module_1.default {
1183
1176
  }
1184
1177
  }
1185
1178
  if (origin) {
1186
- const secure = ((_o = this[kCerts]) === null || _o === void 0 ? void 0 : _o[1][origin]) || (this.host ? TLS.FILE[origin] : null);
1179
+ const secure = this[kCerts]?.[1][origin] || this.host && TLS.FILE[origin];
1187
1180
  if (secure) {
1188
1181
  if (secure.ca && ignoreOpt('--ca-certificate')) {
1189
1182
  args.push(`--ca-certificate="${escapeQuote(secure.ca)}"`);
@@ -1238,8 +1231,8 @@ class Request extends module_1.default {
1238
1231
  args = binOpts.concat(args);
1239
1232
  }
1240
1233
  if (args.length) {
1241
- if (module_1.default.hasLogType(32768)) {
1242
- this.formatMessage(32768, 'ARIA2', ARIA2.BIN, args.join(' '), { ...module_1.default.LOG_STYLE_WARN });
1234
+ if (module_1.hasLogType(32768)) {
1235
+ this.formatMessage(32768, 'ARIA2', ARIA2.BIN, args.join(' '), { ...module_1.LOG_STYLE_WARN });
1243
1236
  }
1244
1237
  else {
1245
1238
  this.addLog(types_1.STATUS_TYPE.INFO, path.basename(ARIA2.BIN) + ' ' + args.join(' '), "aria2");
@@ -1254,7 +1247,7 @@ class Request extends module_1.default {
1254
1247
  closeTorrent(pid);
1255
1248
  reject(err);
1256
1249
  };
1257
- const { pid, stdout, stderr } = child_process.spawn(module_1.default.sanitizeCmd(ARIA2.BIN), args, { cwd: pathname, shell: true, signal: this.signal, uid: ARIA2.EXEC_UID, gid: ARIA2.EXEC_GID })
1250
+ const { pid, stdout, stderr } = child_process.spawn(module_1.sanitizeCmd(ARIA2.BIN), args, { cwd: pathname, shell: true, signal: this.signal, uid: ARIA2.EXEC_UID, gid: ARIA2.EXEC_GID })
1258
1251
  .on('exit', code => {
1259
1252
  closeTorrent(pid);
1260
1253
  if (aborted) {
@@ -1264,15 +1257,15 @@ class Request extends module_1.default {
1264
1257
  errorResponse(pid, (0, types_1.createAbortError)());
1265
1258
  return;
1266
1259
  }
1267
- if (!code) {
1268
- const currentTime = Date.now();
1269
- const pattern = /\|(OK|ERR|INPR)\s*\|\s*([^|]+)\|\s*(\d+)\|([^\n]+)/g;
1270
- const result = [];
1271
- let messageUnit, match;
1272
- while (match = pattern.exec(out)) {
1273
- if (match[4].startsWith('[MEMORY]')) {
1274
- continue;
1275
- }
1260
+ if (code) {
1261
+ reject((0, types_1.errorValue)(message || "Unknown", 'Exit status: ' + code));
1262
+ return;
1263
+ }
1264
+ const currentTime = Date.now();
1265
+ const result = [];
1266
+ let messageUnit;
1267
+ for (const match of out.matchAll(/\|(OK|ERR|INPR)\s*\|\s*([^|]+)\|\s*(\d+)\|([^\n]+)/g)) {
1268
+ if (!match[4].startsWith('[MEMORY]')) {
1276
1269
  const file = path.normalize(match[4].trim());
1277
1270
  switch (match[1]) {
1278
1271
  case 'OK':
@@ -1290,20 +1283,17 @@ class Request extends module_1.default {
1290
1283
  break;
1291
1284
  }
1292
1285
  }
1293
- if (result.length && !silent && LOG_HTTP && LOG_TIMEPROCESS) {
1294
- this.writeTimeProcess("aria2", uri, startTime, { type: 1024, queue: true, messageUnit, messageUnitMinWidth: 9, bypassLog: true });
1295
- }
1296
- this.addLog(result.length ? types_1.STATUS_TYPE.INFO : types_1.STATUS_TYPE.ERROR, out, currentTime, currentTime - startTime, "aria2", uri);
1297
- resolve(result);
1298
1286
  }
1299
- else {
1300
- reject((0, types_1.errorValue)(message || "Unknown", 'Exit status: ' + code));
1287
+ if (result.length && !silent && LOG_HTTP && LOG_TIMEPROCESS) {
1288
+ this.writeTimeProcess("aria2", uri, startTime, { type: 1024, queue: true, messageUnit, messageUnitMinWidth: 9, bypassLog: true });
1301
1289
  }
1290
+ this.addLog(result.length ? types_1.STATUS_TYPE.INFO : types_1.STATUS_TYPE.ERROR, out, currentTime, currentTime - startTime, "aria2", uri);
1291
+ resolve(result);
1302
1292
  })
1303
1293
  .on('error', err => errorResponse(pid, err));
1304
1294
  stdout.setEncoding('utf-8').on('data', (value) => out += value);
1305
1295
  stderr.setEncoding('utf-8').on('data', (value) => message += value);
1306
- if (pid !== undefined && module_1.default.isFile(uri, 'torrent')) {
1296
+ if (pid !== undefined && module_1.isFile(uri, 'torrent')) {
1307
1297
  if (!ARIA2.PID_TIMER) {
1308
1298
  const clearTimer = () => {
1309
1299
  clearInterval(ARIA2.PID_TIMER);
@@ -1324,24 +1314,22 @@ class Request extends module_1.default {
1324
1314
  }
1325
1315
  if (ARIA2.UPDATE_STATUS && !silent) {
1326
1316
  const item = ARIA2.PID_QUEUE.shift();
1327
- if (item) {
1328
- const broadcastId = item[2];
1329
- if (!ARIA2.UPDATE_BROADCAST_ONLY || broadcastId) {
1330
- let progressBar;
1331
- if (item[2]) {
1332
- progressBar = true;
1333
- }
1334
- else {
1335
- const current = (0, types_1.getLogCurrent)();
1336
- progressBar = (current === null || current === void 0 ? void 0 : current.type) === 128 && current.title === "aria2";
1337
- }
1338
- this.formatMessage(128, "aria2", ['Downloading...', (0, types_1.formatTime)(startTime, true)], (PLATFORM_WIN32 ? 'taskkill /f /pid' : 'kill') + ` ${item[0]} -> ` + item[1], { ...module_1.default.LOG_STYLE_INFO, progressBar, broadcastId });
1339
- }
1340
- ARIA2.PID_QUEUE.push(item);
1341
- }
1342
- else {
1317
+ if (!item) {
1343
1318
  clearTimer();
1319
+ return;
1344
1320
  }
1321
+ if ((!ARIA2.UPDATE_BROADCAST_ONLY || item[2]) && this.host?.logState !== 0) {
1322
+ let progressBar;
1323
+ if (item[2]) {
1324
+ progressBar = true;
1325
+ }
1326
+ else {
1327
+ const current = (0, types_1.getLogCurrent)();
1328
+ progressBar = current?.type === 128 && current.title === "aria2";
1329
+ }
1330
+ this.formatMessage(128, "aria2", ['Downloading...', (0, types_1.formatTime)(startTime, true)], (PLATFORM_WIN32 ? 'taskkill /f /pid' : 'kill') + ` ${item[0]} -> ` + item[1], { ...module_1.LOG_STYLE_INFO, progressBar, broadcastId: item[2] });
1331
+ }
1332
+ ARIA2.PID_QUEUE.push(item);
1345
1333
  }
1346
1334
  }, (ARIA2.UPDATE_STATUS || 30) * 1000);
1347
1335
  }
@@ -1364,17 +1352,16 @@ class Request extends module_1.default {
1364
1352
  }
1365
1353
  let host;
1366
1354
  if (this.host) {
1367
- host = (_o = HTTP.HOST)[_p = url.origin] || (_o[_p] = new host_1.default(url, HTTP.VERSION));
1355
+ host = (_o = HTTP.HOST)[_p = url.origin] || (_o[_p] = new host_1(url, HTTP.VERSION));
1368
1356
  }
1369
1357
  else {
1370
- host = (_q = this[kHostInfo])[_r = url.origin] || (_q[_r] = new host_1.default(url, this.httpVersion || 1));
1358
+ host = (_q = this[kHostInfo])[_r = url.origin] || (_q[_r] = new host_1(url, this.httpVersion || 1));
1371
1359
  }
1372
1360
  return { ...options, host, url };
1373
1361
  }
1374
1362
  open(uri, options) {
1375
- var _o;
1376
- var _p, _q;
1377
- let { host, url, httpVersion, method = 'GET', encoding, format, headers, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options;
1363
+ var _o, _p;
1364
+ let { host, url, httpVersion, method = 'GET', search, encoding, format, headers, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options;
1378
1365
  const getting = method === 'GET';
1379
1366
  const posting = method === 'POST';
1380
1367
  if (format) {
@@ -1421,6 +1408,12 @@ class Request extends module_1.default {
1421
1408
  url = new URL(uri);
1422
1409
  options.url = url;
1423
1410
  }
1411
+ if (search) {
1412
+ for (const param in search) {
1413
+ url.searchParams.append(param, search[param]);
1414
+ }
1415
+ uri = url.href;
1416
+ }
1424
1417
  const checkEncoding = (response, statusCode, contentEncoding = '') => {
1425
1418
  switch (statusCode) {
1426
1419
  case 206:
@@ -1428,7 +1421,7 @@ class Request extends module_1.default {
1428
1421
  case 204:
1429
1422
  return;
1430
1423
  }
1431
- const chunkSize = outStream === null || outStream === void 0 ? void 0 : outStream.writableHighWaterMark;
1424
+ const chunkSize = outStream?.writableHighWaterMark;
1432
1425
  let pipeTo;
1433
1426
  switch (contentEncoding.trim().toLowerCase()) {
1434
1427
  case 'gzip':
@@ -1464,17 +1457,17 @@ class Request extends module_1.default {
1464
1457
  const proxy = this.proxyOf(uri, localhost);
1465
1458
  const version = this.httpVersion;
1466
1459
  let request, ca, cert, key, minVersion, baseHeaders = this.headersOf(uri);
1467
- if (getting && this.acceptEncoding && !localhost && !(baseHeaders === null || baseHeaders === void 0 ? void 0 : baseHeaders['accept-encoding'])) {
1468
- (_p = (headers || (headers = {})))['accept-encoding'] || (_p['accept-encoding'] = 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : ''));
1460
+ if (getting && this.acceptEncoding && !localhost && !baseHeaders?.['accept-encoding']) {
1461
+ (_o = (headers || (headers = {})))['accept-encoding'] || (_o['accept-encoding'] = 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : ''));
1469
1462
  }
1470
1463
  if (secure) {
1471
- const certs = ((_o = this[kCerts]) === null || _o === void 0 ? void 0 : _o[0][origin]) || (this.host ? TLS.TEXT[origin] : null);
1464
+ const certs = this[kCerts]?.[0][origin] || this.host && TLS.TEXT[origin];
1472
1465
  if (certs) {
1473
1466
  ({ ca, cert, key, version: minVersion } = certs);
1474
1467
  }
1475
1468
  }
1476
1469
  if (!proxy && httpVersion !== 1 && ((httpVersion || host.version) === 2 && version !== 1 || secure && version === 2 && host.failed(2, true) === 0)) {
1477
- request = ((_q = this[kSession][0])[origin] || (_q[origin] = http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, minVersion, settings: localhost ? { maxFrameSize: 16777215, enablePush: false } : { enablePush: false } }))).request({ ...baseHeaders, ...host_1.default.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
1470
+ request = ((_p = this[kSession][0])[origin] || (_p[origin] = http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, minVersion, settings: localhost ? { maxFrameSize: 16777215, enablePush: false } : { enablePush: false } }))).request({ ...baseHeaders, ...host_1.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
1478
1471
  if (getting) {
1479
1472
  const listenerMap = {};
1480
1473
  const onEvent = request.on.bind(request);
@@ -1558,8 +1551,8 @@ class Request extends module_1.default {
1558
1551
  const pkg = secure ? 'https-proxy-agent' : 'http-proxy-agent';
1559
1552
  try {
1560
1553
  const { protocol, hostname: proxyname, port, username, password, href } = proxy.host;
1561
- keepAlive !== null && keepAlive !== void 0 ? keepAlive : (keepAlive = proxy.keepAlive || false);
1562
- agentTimeout !== null && agentTimeout !== void 0 ? agentTimeout : (agentTimeout = proxy.agentTimeout);
1554
+ keepAlive ?? (keepAlive = proxy.keepAlive || false);
1555
+ agentTimeout ?? (agentTimeout = proxy.agentTimeout);
1563
1556
  agent = require(pkg)(keepAlive || agentTimeout > 0 ? { protocol, hostname: proxyname, port, username, password, keepAlive, timeout: agentTimeout } : href);
1564
1557
  const proxyHeaders = this[kHeaders] && getBaseHeaders(href, this[kHeaders]) || getBaseHeaders(href, HTTP.HEADERS);
1565
1558
  if (proxyHeaders) {
@@ -1578,13 +1571,13 @@ class Request extends module_1.default {
1578
1571
  }
1579
1572
  else if (agentTimeout !== 0) {
1580
1573
  keepAlive = this.keepAlive || false;
1581
- agentTimeout !== null && agentTimeout !== void 0 ? agentTimeout : (agentTimeout = this.agentTimeout);
1574
+ agentTimeout ?? (agentTimeout = this.agentTimeout);
1582
1575
  if (keepAlive || agentTimeout > 0) {
1583
1576
  agent = new (secure ? https.Agent : http.Agent)({ keepAlive, timeout: agentTimeout });
1584
1577
  }
1585
1578
  }
1586
1579
  }
1587
- const basicAuth = host_1.default.getBasicAuth(url);
1580
+ const basicAuth = host_1.getBasicAuth(url);
1588
1581
  if (baseHeaders || basicAuth) {
1589
1582
  headers = { ...baseHeaders, ...basicAuth, ...headers };
1590
1583
  }
@@ -1602,7 +1595,6 @@ class Request extends module_1.default {
1602
1595
  lookup: this.lookupDns(hostname),
1603
1596
  agent
1604
1597
  }, response => {
1605
- var _o;
1606
1598
  const statusCode = response.statusCode;
1607
1599
  const incoming = response.headers;
1608
1600
  if (this.matchStatus(statusCode, url, incoming, request, options) && (getting || posting) && statusCode >= 200 && statusCode < 300) {
@@ -1638,7 +1630,7 @@ class Request extends module_1.default {
1638
1630
  source.on('error', err => request.emit('error', err));
1639
1631
  }
1640
1632
  if (!posting) {
1641
- if (version === 2 && ((_o = incoming.upgrade) === null || _o === void 0 ? void 0 : _o.includes('h2'))) {
1633
+ if (version === 2 && incoming.upgrade?.includes('h2')) {
1642
1634
  host.version = 2;
1643
1635
  }
1644
1636
  else if (!host.didAltSvc(1)) {
@@ -1665,7 +1657,7 @@ class Request extends module_1.default {
1665
1657
  if (timeout > 0) {
1666
1658
  request.setTimeout(timeout);
1667
1659
  }
1668
- if ((getting || posting) && SUPPORT_ABORTSIGNAL) {
1660
+ if (getting || posting) {
1669
1661
  const ac = new AbortController();
1670
1662
  this[kDownloading].add(options.outAbort = ac);
1671
1663
  stream.addAbortSignal(ac.signal, request);
@@ -1741,7 +1733,7 @@ class Request extends module_1.default {
1741
1733
  };
1742
1734
  const addValue = (name, value) => {
1743
1735
  if (value !== undefined) {
1744
- const disposition = createPart(name) + module_1.default.asString(value) + "\r\n";
1736
+ const disposition = createPart(name) + module_1.asString(value) + "\r\n";
1745
1737
  write.append(disposition);
1746
1738
  contentLength += Buffer.byteLength(disposition);
1747
1739
  }
@@ -1760,7 +1752,7 @@ class Request extends module_1.default {
1760
1752
  try {
1761
1753
  if (typeof target === 'string') {
1762
1754
  filename || (filename = path.basename(target));
1763
- type || (type = module_1.default.lookupMime(filename));
1755
+ type || (type = module_1.lookupMime(filename));
1764
1756
  target = fs.readFileSync(target);
1765
1757
  }
1766
1758
  else if (target instanceof stream.Readable) {
@@ -1774,14 +1766,14 @@ class Request extends module_1.default {
1774
1766
  throw (0, types_1.errorMessage)('File', "Unknown", "multipart/form-data");
1775
1767
  }
1776
1768
  if (!type || !filename) {
1777
- const result = await module_1.default.resolveMime(target);
1769
+ const result = await module_1.resolveMime(target);
1778
1770
  let ext;
1779
1771
  if (result) {
1780
1772
  type || (type = result.mime);
1781
1773
  ext = result.ext;
1782
1774
  }
1783
1775
  else if (type) {
1784
- ext = module_1.default.lookupMime(type, true);
1776
+ ext = module_1.lookupMime(type, true);
1785
1777
  }
1786
1778
  if (ext && !filename) {
1787
1779
  filename = (0, types_1.generateUUID)() + '.' + ext;
@@ -1809,7 +1801,7 @@ class Request extends module_1.default {
1809
1801
  }
1810
1802
  }
1811
1803
  if (!valid) {
1812
- return Promise.reject((0, types_1.errorValue)('No files were detected', "multipart/form-data"));
1804
+ return Promise.reject((0, types_1.errorValue)("No files were attached", "multipart/form-data"));
1813
1805
  }
1814
1806
  }
1815
1807
  else {
@@ -1817,7 +1809,7 @@ class Request extends module_1.default {
1817
1809
  contentType = 'application/' + contentType.trim();
1818
1810
  }
1819
1811
  if (!(0, types_1.isPlainObject)(data)) {
1820
- data = module_1.default.asString(data);
1812
+ data = module_1.asString(data);
1821
1813
  }
1822
1814
  else if (contentType === "application/x-www-form-urlencoded") {
1823
1815
  data = qs.stringify(data);
@@ -1848,7 +1840,7 @@ class Request extends module_1.default {
1848
1840
  if (!closed) {
1849
1841
  closed = true;
1850
1842
  if (outStream && (0, types_1.isString)(pipeTo)) {
1851
- (0, lib_v4_1.cleanupStream)(outStream, pipeTo);
1843
+ (0, util_1.cleanupStream)(outStream, pipeTo);
1852
1844
  }
1853
1845
  reject(typeof err === 'string' ? new Error(err) : err);
1854
1846
  }
@@ -1865,10 +1857,10 @@ class Request extends module_1.default {
1865
1857
  try {
1866
1858
  const request = this.opts(href, opts);
1867
1859
  if (outStream && (0, types_1.isString)(pipeTo)) {
1868
- (0, lib_v4_1.cleanupStream)(outStream, pipeTo);
1860
+ (0, util_1.cleanupStream)(outStream, pipeTo);
1869
1861
  }
1870
1862
  if (pipeTo) {
1871
- if ((0, types_1.isString)(pipeTo)) {
1863
+ if (typeof pipeTo === 'string') {
1872
1864
  outStream = fs.createWriteStream(pipeTo, { emitClose: false, highWaterMark: request.host.localhost ? 65536 : 4096 });
1873
1865
  request.outStream = outStream;
1874
1866
  }
@@ -1880,7 +1872,7 @@ class Request extends module_1.default {
1880
1872
  request.httpVersion = httpVersion;
1881
1873
  }
1882
1874
  const client = this.open(href, request);
1883
- const { host, url, encoding, outFormat } = request;
1875
+ const { host, url, encoding, progressId, outFormat } = request;
1884
1876
  let buffer, aborted;
1885
1877
  ({ httpVersion, outAbort } = request);
1886
1878
  const isAborted = () => client.destroyed || httpVersion === 2 && client.aborted;
@@ -1912,21 +1904,21 @@ class Request extends module_1.default {
1912
1904
  downloadUri.call(this, href);
1913
1905
  };
1914
1906
  const acceptResponse = (headers) => {
1915
- var _o;
1916
1907
  if ('outHeaders' in opts) {
1917
1908
  opts.outHeaders = headers;
1918
1909
  }
1919
1910
  if ('outFilename' in opts) {
1920
1911
  opts.outFilename = (0, util_1.parseHeader)(headers, 'content-disposition');
1921
1912
  }
1922
- const buffering = (_o = request.connected) === null || _o === void 0 ? void 0 : _o.call(client, headers);
1913
+ const buffering = request.connected?.call(client, headers);
1923
1914
  const pipeline = pipeTo ? !(0, types_1.isString)(pipeTo) : false;
1924
1915
  const enabled = buffering !== false && !pipeline;
1925
- const readTimeout = this.readTimeout;
1926
- let mibsTime, delayTime;
1927
- if (log || readTimeout > 0) {
1916
+ const maxBufferSize = request.maxBufferSize ? (0, types_1.alignSize)(request.maxBufferSize) : 0;
1917
+ const { host: parent, readTimeout } = this;
1918
+ const contentLength = parent && progressId !== undefined ? parseInt(headers['content-length'] || '0') : 0;
1919
+ let dataLength = 0, mibsTime, delayTime;
1920
+ if (log || readTimeout > 0 || contentLength > 0) {
1928
1921
  client.once('readable', () => {
1929
- var _o;
1930
1922
  if (readTimeout > 0) {
1931
1923
  timeout = setTimeout(() => {
1932
1924
  abortResponse();
@@ -1934,7 +1926,7 @@ class Request extends module_1.default {
1934
1926
  }, readTimeout);
1935
1927
  }
1936
1928
  if (log) {
1937
- switch (((_o = this.settings) === null || _o === void 0 ? void 0 : _o.time_format) || LOG_TIMEFORMAT) {
1929
+ switch (this.settings?.time_format || LOG_TIMEFORMAT) {
1938
1930
  case 'readable':
1939
1931
  delayTime = process.hrtime(startTime);
1940
1932
  break;
@@ -1942,7 +1934,10 @@ class Request extends module_1.default {
1942
1934
  delayTime = Date.now() - this.startTime;
1943
1935
  break;
1944
1936
  }
1945
- mibsTime = process.hrtime();
1937
+ }
1938
+ mibsTime = process.hrtime();
1939
+ if (contentLength > 0) {
1940
+ parent.updateProgress("request", progressId, 0, 0, mibsTime);
1946
1941
  }
1947
1942
  });
1948
1943
  }
@@ -1962,6 +1957,19 @@ class Request extends module_1.default {
1962
1957
  else {
1963
1958
  buffer = typeof chunk === 'string' ? chunk : [chunk];
1964
1959
  }
1960
+ if (contentLength > 0) {
1961
+ dataLength += Buffer.byteLength(chunk, encoding);
1962
+ parent.updateProgress("request", progressId, dataLength, contentLength);
1963
+ }
1964
+ if (maxBufferSize > 0) {
1965
+ if (contentLength === 0) {
1966
+ dataLength += Buffer.byteLength(chunk, encoding);
1967
+ }
1968
+ if (dataLength > maxBufferSize) {
1969
+ abortResponse();
1970
+ throwError((0, types_1.errorValue)("Size limit was exceeded", href.toString()));
1971
+ }
1972
+ }
1965
1973
  });
1966
1974
  }
1967
1975
  client.once('end', () => {
@@ -1984,20 +1992,15 @@ class Request extends module_1.default {
1984
1992
  buffer = buffer.toString(encoding);
1985
1993
  }
1986
1994
  }
1995
+ dataLength = Buffer.byteLength(buffer, encoding);
1987
1996
  if (mibsTime) {
1988
- const unit = (Buffer.byteLength(buffer, encoding) * 8) / ((0, types_1.convertTime)(process.hrtime(mibsTime)) * 1000);
1989
- if (unit < 1) {
1990
- messageUnit = Math.ceil(unit * 1000) + 'KiB/s';
1991
- }
1992
- else if (unit < 1000) {
1993
- messageUnit = unit.toPrecision(3) + 'MiB/s';
1994
- }
1995
- else {
1996
- messageUnit = (unit / 1000).toPrecision(3) + 'GiB/s';
1997
- }
1997
+ messageUnit = (0, util_1.getTransferRate)(dataLength, (0, types_1.convertTime)(process.hrtime(mibsTime), false) * 1000);
1998
+ }
1999
+ if (contentLength > 0) {
2000
+ parent.updateProgress("request", progressId, dataLength, dataLength);
1998
2001
  }
1999
2002
  if (typeof buffer === 'string') {
2000
- if (buffer.startsWith('\uFEFF') && encoding !== 'utf16le') {
2003
+ if (buffer.startsWith('\uFEFF') && encoding !== 'utf16le' && encoding !== 'utf-16le') {
2001
2004
  buffer = buffer.substring(1);
2002
2005
  }
2003
2006
  if (outFormat) {
@@ -2037,11 +2040,14 @@ class Request extends module_1.default {
2037
2040
  result = buffer;
2038
2041
  }
2039
2042
  }
2040
- else if (enabled && this.readExpect === 'always') {
2041
- throwError('No data received');
2042
- return;
2043
- }
2044
2043
  else {
2044
+ if (contentLength > 0) {
2045
+ parent.updateProgress("request", progressId, 0, contentLength);
2046
+ }
2047
+ if (enabled && this.readExpect === 'always') {
2048
+ throwError('No data received');
2049
+ return;
2050
+ }
2045
2051
  result = encoding && !pipeline ? '' : null;
2046
2052
  titleBgColor = 'bgBlue';
2047
2053
  }
@@ -2055,7 +2061,10 @@ class Request extends module_1.default {
2055
2061
  const redirectResponse = (statusCode, location) => {
2056
2062
  abortResponse();
2057
2063
  if (location) {
2058
- if (++redirects <= this._config.redirectLimit) {
2064
+ if (request.follow_redirect === false) {
2065
+ throwError(formatStatus(statusCode, 'Follow redirect was disabled'));
2066
+ }
2067
+ else if (++redirects <= this._config.redirectLimit) {
2059
2068
  downloadUri.call(this, Request.fromURL(url, location));
2060
2069
  }
2061
2070
  else {
@@ -2264,8 +2273,7 @@ class Request extends module_1.default {
2264
2273
  this[kDownloading].clear();
2265
2274
  }
2266
2275
  matchStatus(code, url, headers, request, options) {
2267
- var _o;
2268
- const status = (_o = this[kStatusOn]) === null || _o === void 0 ? void 0 : _o.get(code);
2276
+ const status = this[kStatusOn]?.get(code);
2269
2277
  if (status) {
2270
2278
  const href = url.href;
2271
2279
  const called = new Set();
@@ -2290,7 +2298,7 @@ class Request extends module_1.default {
2290
2298
  }
2291
2299
  matchHeaders(url, headers, request, options) {
2292
2300
  const on = this[kHeadersOn];
2293
- if (on === null || on === void 0 ? void 0 : on.size) {
2301
+ if (on?.size) {
2294
2302
  const href = url.href;
2295
2303
  const called = new Map();
2296
2304
  for (const [name, item] of on) {
@@ -2321,14 +2329,13 @@ class Request extends module_1.default {
2321
2329
  return true;
2322
2330
  }
2323
2331
  set agentTimeout(value) {
2324
- var _o, _p;
2325
2332
  if (value > 0) {
2326
2333
  this[kAgentTimeout] = value;
2327
- (_o = this.keepAlive) !== null && _o !== void 0 ? _o : (this.keepAlive = true);
2334
+ this.keepAlive ?? (this.keepAlive = true);
2328
2335
  }
2329
2336
  else {
2330
2337
  this[kAgentTimeout] = 0;
2331
- (_p = this.keepAlive) !== null && _p !== void 0 ? _p : (this.keepAlive = false);
2338
+ this.keepAlive ?? (this.keepAlive = false);
2332
2339
  }
2333
2340
  }
2334
2341
  get agentTimeout() {
@@ -2363,9 +2370,5 @@ class Request extends module_1.default {
2363
2370
  }
2364
2371
  }
2365
2372
  _a = kSingleton, _b = kHttpVersion, _c = kHeaders, _d = kCerts, _e = kConnectDns, _f = kPendingDns, _g = kConnectHttp, _h = kStatusOn, _j = kHeadersOn, _k = kDownloading, _l = kHostInfo, _m = kSession;
2366
- exports.default = Request;
2367
2373
 
2368
- if (exports.default) {
2369
- module.exports = exports.default;
2370
- module.exports.default = exports.default;
2371
- }
2374
+ module.exports = Request;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/request",
3
- "version": "0.8.10",
3
+ "version": "0.9.1",
4
4
  "description": "Request constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -17,14 +17,14 @@
17
17
  "squared-functions"
18
18
  ],
19
19
  "author": "An Pham <anpham6@gmail.com>",
20
- "license": "MIT",
20
+ "license": "BSD 3-Clause",
21
21
  "homepage": "https://github.com/anpham6/e-mc#readme",
22
22
  "dependencies": {
23
- "@e-mc/module": "0.8.10",
24
- "@e-mc/types": "0.8.10",
23
+ "@e-mc/module": "0.9.1",
24
+ "@e-mc/types": "0.9.1",
25
25
  "combined-stream": "^1.0.8",
26
26
  "js-yaml": "^4.1.0",
27
- "picomatch": "^3.0.1",
27
+ "picomatch": "^4.0.2",
28
28
  "which": "^2.0.2"
29
29
  }
30
30
  }
package/util.d.ts CHANGED
@@ -1,4 +1,7 @@
1
+ import type { AuthValue } from '../types/lib/http';
2
+
1
3
  import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http';
4
+ import type { Readable, Writable } from 'stream';
2
5
 
3
6
  declare namespace util {
4
7
  function parseHeader<T = unknown>(headers: IncomingHttpHeaders, name: string): T | undefined;
@@ -12,6 +15,12 @@ declare namespace util {
12
15
  function asInt(value: unknown): number;
13
16
  function asFloat(value: unknown): number;
14
17
  function fromSeconds(value: unknown): number;
18
+ function getTransferRate(length: number, timeMs: number, unitSeparator?: string): string;
19
+ function hasSameStat(src: string, dest: string, keepEmpty?: boolean): boolean;
20
+ function hasSize(value: string, keepEmpty?: boolean): boolean;
21
+ function getSize(value: string, diskUsed?: boolean): number;
22
+ function byteLength(value: Bufferable, encoding?: BufferEncoding): number;
23
+ function cleanupStream(target: Readable | Writable, pathname?: string): void;
15
24
  }
16
25
 
17
26
  export = util;
package/util.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fromSeconds = exports.asFloat = exports.asInt = exports.trimPath = exports.isRetryable = exports.checkRetryable = exports.hasBasicAuth = exports.getBasicAuth = exports.normalizeHeaders = exports.parseHeader = void 0;
2
+ exports.cleanupStream = exports.byteLength = exports.hasSameStat = exports.getSize = exports.hasSize = exports.getTransferRate = exports.fromSeconds = exports.asFloat = exports.asInt = exports.trimPath = exports.isRetryable = exports.checkRetryable = exports.hasBasicAuth = exports.getBasicAuth = exports.normalizeHeaders = exports.parseHeader = void 0;
3
+ const path = require("path");
4
+ const fs = require("fs");
4
5
  const module_1 = require("@e-mc/module");
5
6
  const types_1 = require("@e-mc/types");
6
7
  const safeInt = (value) => value >= 0 ? Math.min(value, Number.MAX_SAFE_INTEGER) : NaN;
@@ -9,9 +10,8 @@ function parseHeader(headers, name) {
9
10
  if (value) {
10
11
  switch (name.toLowerCase()) {
11
12
  case 'content-disposition': {
12
- const pattern = /\bfilename(?:\*\s*=\s*UTF-8''([^\s;]+)|\s*=\s*(?:"([^"]+)"|([^\s;]+)))/gi;
13
- let result, match;
14
- while (match = pattern.exec(value)) {
13
+ let result;
14
+ for (const match of value.matchAll(/\bfilename(?:\*\s*=\s*UTF-8''([^\s;]+)|\s*=\s*(?:"([^"]+)"|([^\s;]+)))/gi)) {
15
15
  if (match[1]) {
16
16
  return decodeURIComponent(match[1]).trim();
17
17
  }
@@ -36,7 +36,7 @@ function normalizeHeaders(headers) {
36
36
  break;
37
37
  default:
38
38
  if (Array.isArray(value)) {
39
- value = value.map(out => module_1.default.asString(out).trim());
39
+ value = value.map(out => module_1.asString(out).trim());
40
40
  break;
41
41
  }
42
42
  continue;
@@ -57,7 +57,7 @@ function getBasicAuth(username, password) {
57
57
  exports.getBasicAuth = getBasicAuth;
58
58
  function hasBasicAuth(value) {
59
59
  try {
60
- return (0, types_1.isString)(new URL(value).username);
60
+ return new URL(value).username.length > 0;
61
61
  }
62
62
  catch {
63
63
  }
@@ -146,3 +146,75 @@ function fromSeconds(value) {
146
146
  }
147
147
  }
148
148
  exports.fromSeconds = fromSeconds;
149
+ function getTransferRate(length, timeMs, unitSeparator = '') {
150
+ const unit = (length * 8) / timeMs;
151
+ if (unit < 1) {
152
+ return Math.ceil(unit * 1000) + unitSeparator + 'KiB/s';
153
+ }
154
+ if (unit < 1000) {
155
+ return unit.toPrecision(3) + unitSeparator + 'MiB/s';
156
+ }
157
+ return (unit / 1000).toPrecision(3) + unitSeparator + 'GiB/s';
158
+ }
159
+ exports.getTransferRate = getTransferRate;
160
+ function hasSize(value, keepEmpty) {
161
+ try {
162
+ const statSrc = fs.statSync(value);
163
+ if (statSrc.size > 0) {
164
+ return true;
165
+ }
166
+ if (!keepEmpty) {
167
+ fs.unlinkSync(value);
168
+ }
169
+ }
170
+ catch {
171
+ }
172
+ return false;
173
+ }
174
+ exports.hasSize = hasSize;
175
+ function getSize(value, diskUsed) {
176
+ try {
177
+ return (diskUsed ? fs.lstatSync(value) : fs.statSync(value)).size;
178
+ }
179
+ catch {
180
+ return 0;
181
+ }
182
+ }
183
+ exports.getSize = getSize;
184
+ function hasSameStat(src, dest, keepEmpty) {
185
+ try {
186
+ if (fs.existsSync(dest)) {
187
+ const { size, mtimeMs } = fs.statSync(src);
188
+ if (size > 0) {
189
+ const statDest = fs.statSync(dest);
190
+ return size === statDest.size && mtimeMs === statDest.mtimeMs;
191
+ }
192
+ if (!keepEmpty) {
193
+ fs.unlinkSync(src);
194
+ }
195
+ }
196
+ }
197
+ catch {
198
+ }
199
+ return false;
200
+ }
201
+ exports.hasSameStat = hasSameStat;
202
+ function byteLength(value, encoding) {
203
+ return typeof value === 'string' && (path.isAbsolute(value) || module_1.isPath(value)) ? getSize(value) : Buffer.byteLength(value, encoding && (0, types_1.getEncoding)(encoding));
204
+ }
205
+ exports.byteLength = byteLength;
206
+ function cleanupStream(stream, uri) {
207
+ try {
208
+ stream.removeAllListeners();
209
+ stream.destroy();
210
+ if (uri && fs.existsSync(uri)) {
211
+ fs.unlinkSync(uri);
212
+ }
213
+ }
214
+ catch (err) {
215
+ if (!module_1.isErrorCode(err, 'ENOENT')) {
216
+ module_1.writeFail(["Unable to delete file", path.basename(uri)], err, 32);
217
+ }
218
+ }
219
+ }
220
+ exports.cleanupStream = cleanupStream;