@e-mc/request 0.12.8 → 0.13.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
@@ -1,6 +1,6 @@
1
1
  # @e-mc/request
2
2
 
3
- * NodeJS 18
3
+ * NodeJS 18.20.5 LTS
4
4
  * ES2022
5
5
 
6
6
  ## General Usage
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## Interface
11
11
 
12
- * [View Source](https://www.unpkg.com/@e-mc/types@0.12.7/lib/index.d.ts)
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.13.0/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { IModule, ModuleConstructor } from "./index";
@@ -40,9 +40,9 @@ interface IRequest extends IModule {
40
40
  headersOn(name: string | string[], callback: HeadersOnCallback): void;
41
41
  headersOn(name: string | string[], globUrl: string, callback: HeadersOnCallback): void;
42
42
  headersOf(uri: string): OutgoingHttpHeaders | undefined;
43
- aria2c(uri: string | URL, pathname: string): Promise<string[]>;
43
+ aria2c(uri: string | URL, pathname: string | URL): Promise<string[]>;
44
44
  aria2c(uri: string | URL, options?: Aria2Options): Promise<string[]>;
45
- rclone(uri: string | URL, pathname: string): Promise<string[]>;
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
48
  pipe(uri: string | URL, to: Writable, options?: OpenOptions): Promise<null>;
@@ -55,6 +55,7 @@ interface IRequest extends IModule {
55
55
  post(uri: string | URL, form: Record<string, unknown>, parts: FormDataPart[]): Promise<Buffer | string | null>;
56
56
  post(uri: string | URL, data: unknown, options: PostOptions): Promise<Buffer | string | null>;
57
57
  post(uri: string | URL, data: unknown, contentType?: string, options?: PostOptions): Promise<Buffer | string | null>;
58
+ get(uri: string | URL, format: "json" | "yaml" | "json5" | "xml" | "toml"): Promise<object | null>;
58
59
  get(uri: string | URL, options?: OpenOptions): Promise<Buffer | object | string | null>;
59
60
  detach(singleton?: boolean): void;
60
61
  reset(adapter?: IHttpAdapter): void;
@@ -74,10 +75,6 @@ interface RequestConstructor extends ModuleConstructor {
74
75
  readTLSKey(value: string, cache?: boolean): string;
75
76
  readTLSCert(value: string, cache?: boolean): string;
76
77
  isCert(value: string): boolean;
77
- /** @deprecated @e-mc/request/util */
78
- fromURL(url: URL, value: string): string;
79
- /** @deprecated @e-mc/request/util */
80
- fromStatusCode(value: number | string): string;
81
78
  defineHttpAgent(options: HttpAgentSettings): void;
82
79
  defineDnsLookup(options: DnsLookupSettings, clear?: boolean): void;
83
80
  defineHttpAdapter(module: unknown): void;
@@ -255,9 +252,9 @@ instance.get("http://hostname/path/config.yml", options).then(data => {
255
252
 
256
253
  ## References
257
254
 
258
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/http.d.ts
259
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/request.d.ts
260
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/settings.d.ts
255
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/http.d.ts
256
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/request.d.ts
257
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/settings.d.ts
261
258
 
262
259
  * https://www.npmjs.com/package/@types/node
263
260
 
@@ -5,22 +5,28 @@ const yaml = require("js-yaml");
5
5
  const types_1 = require("@e-mc/types");
6
6
  const module_1 = require("@e-mc/module");
7
7
  const util_1 = require("@e-mc/request/util");
8
+ const kHttpAdapter = Symbol.for('request:http:adapter:constructor');
8
9
  let LOG_TIMEFORMAT = 'readable';
10
+ const isConstructor = (value) => typeof value === 'function' && !!value.prototype?.constructor.name;
9
11
  class HttpAdapter {
10
12
  instance;
11
13
  state;
12
14
  uri;
15
+ static [kHttpAdapter] = true;
16
+ static constructorOf(value) {
17
+ return isConstructor(value) && value[kHttpAdapter] === true;
18
+ }
13
19
  static isUnsupported(value) {
14
20
  return value === 421 || value === 505;
15
21
  }
16
22
  static isDowngrade(err) {
17
- return module_1.isErrorCode(err, 'ERR_HTTP2_ERROR') || err instanceof Error && this.isUnsupported(Math.abs(err.errno));
23
+ return (0, types_1.isErrorCode)(err, 'ERR_HTTP2_ERROR') || err instanceof Error && this.isUnsupported(Math.abs(err.errno));
18
24
  }
19
25
  static wasAborted(err) {
20
26
  return err instanceof Error && err.message.startsWith("Aborted");
21
27
  }
22
28
  static isConnectionError(err) {
23
- return module_1.isErrorCode(err, 'ETIMEDOUT', 'ECONNRESET');
29
+ return (0, types_1.isErrorCode)(err, 'ETIMEDOUT', 'ECONNRESET');
24
30
  }
25
31
  static defineHostConfig({ settings }) {
26
32
  const time_format = settings?.time_format;
package/index.js CHANGED
@@ -14,6 +14,7 @@ const qs = require("node:querystring");
14
14
  const combined = require("combined-stream");
15
15
  const pm = require("picomatch");
16
16
  const which = require("which");
17
+ const node_url_1 = require("node:url");
17
18
  const types_1 = require("@e-mc/types");
18
19
  const module_1 = require("@e-mc/module");
19
20
  const util_1 = require("@e-mc/request/util");
@@ -21,8 +22,8 @@ const host_1 = require("@e-mc/request/http/host");
21
22
  const adapter_1 = require("@e-mc/request/http/adapter");
22
23
  const kRequest = Symbol.for('request:constructor');
23
24
  const SUPPORTED_NODE20 = (0, types_1.supported)(20);
24
- const SUPPORTED_ZSTD = (0, types_1.supported)(23, 8) || (0, types_1.supported)(22, 15, 0, true);
25
- const REGEXP_PEMCERT = /^-{3,}[ \t]*BEGIN[ \t].+\n-{3,}[ \t]*END[ \t][^-]+-{3,}$/s;
25
+ const SUPPORTED_ZSTD = (0, types_1.supported)(23, 8) || (0, types_1.supported)(22, 15, true);
26
+ const SUPPORTED_PROXY = (0, types_1.supported)(24, 5);
26
27
  const REGEXP_GLOBWITHIN = /\\\?|(?:(?<!\\)(?:\*|\[!?[^!\]]+\]|\{(?:[^,]+,)+[^}]+\}|[!?+*@]\((?:[^|]+\|)*[^)]+\)|\?.*\?|\?$))/;
27
28
  const REGEXP_RCLONE = /^rclone:\?/i;
28
29
  const HTTP = {
@@ -70,7 +71,12 @@ const RCLONE = {
70
71
  EXEC_GID: undefined,
71
72
  CHECK_FIRST: false,
72
73
  CHECKSUM: false,
74
+ COMBINED: '',
75
+ CSV: false,
73
76
  CUTOFF_MODE: '',
77
+ DIFFER: '',
78
+ ERROR: '',
79
+ HASH: '',
74
80
  IGNORE_CASE_SYNC: false,
75
81
  IGNORE_CHECKSUM: false,
76
82
  IGNORE_EXISTING: false,
@@ -90,8 +96,10 @@ const RCLONE = {
90
96
  NO_CHECK_DEST: false,
91
97
  NO_TRAVERSE: false,
92
98
  NO_UPDATE_DIR_MODTIME: false,
99
+ NO_UPDATE_MODTIME: false,
93
100
  REFRESH_TIMES: false,
94
101
  SIZE_ONLY: false,
102
+ STREAMING_UPLOAD_CUTOFF: '',
95
103
  UPDATE: false,
96
104
  FAST_LIST: false,
97
105
  BIND: '',
@@ -107,14 +115,6 @@ let READ_TIMEOUT = 0;
107
115
  let AGENT_TIMEOUT = 0;
108
116
  let LOG_HTTP = false;
109
117
  let LOG_TIMEPROCESS = true;
110
- let LIB_ZSTD = null;
111
- try {
112
- require('zstd-codec/lib/zstd-stream').run(codec => {
113
- LIB_ZSTD = codec;
114
- });
115
- }
116
- catch {
117
- }
118
118
  function getBaseHeaders(uri, headers) {
119
119
  let result;
120
120
  uri = (0, util_1.trimPath)(uri);
@@ -338,6 +338,16 @@ function checkEncoding(request, response, statusCode, outStream, contentEncoding
338
338
  return pipeTo;
339
339
  }
340
340
  }
341
+ function sendBody(request, options) {
342
+ const postData = options.postData;
343
+ if ((0, types_1.isString)(postData) || Buffer.isBuffer(postData)) {
344
+ request.write(postData);
345
+ }
346
+ else if (postData instanceof stream.Stream) {
347
+ postData.pipe(request);
348
+ }
349
+ request.end();
350
+ }
341
351
  function decompressEncoding(value, chunkSize) {
342
352
  switch (value) {
343
353
  case 'gzip':
@@ -349,9 +359,6 @@ function decompressEncoding(value, chunkSize) {
349
359
  case 'deflate-raw':
350
360
  return zlib.createInflateRaw({ chunkSize });
351
361
  case 'zstd':
352
- if (LIB_ZSTD) {
353
- return new LIB_ZSTD.ZstdDecompressTransform({ writableHighWaterMark: chunkSize });
354
- }
355
362
  if (SUPPORTED_ZSTD) {
356
363
  return zlib.createZstdDecompress({ chunkSize });
357
364
  }
@@ -391,68 +398,8 @@ function setBinExec(settings, target) {
391
398
  target.EXEC_GID = (gid = (0, util_1.asInt)(gid)) >= 0 ? gid : undefined;
392
399
  }
393
400
  }
394
- function parseBinOpts(instance, options, ignore, skip, doubleQuote) {
395
- let pathname = options.pathname, binOpts;
396
- if (!(0, types_1.isString)(pathname)) {
397
- if (!instance.host) {
398
- return [];
399
- }
400
- pathname = process.cwd();
401
- }
402
- if ((0, types_1.isArray)(options.binOpts)) {
403
- let next = false;
404
- binOpts = options.binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt.trim()))).map((opt) => {
405
- if (next) {
406
- if (!module_1.asString(opt).startsWith('--')) {
407
- return [];
408
- }
409
- next = false;
410
- }
411
- switch (typeof opt) {
412
- case 'string': {
413
- const value = opt.trim();
414
- if (value.startsWith('--')) {
415
- const match = /^(--[a-z]+[a-z0-9-]*)(=)?\s*(.*)$/s.exec(value);
416
- if (match) {
417
- if (ignore.includes(match[1])) {
418
- return [];
419
- }
420
- if (skip.includes(match[1])) {
421
- if (!match[2]) {
422
- next = true;
423
- }
424
- return [];
425
- }
426
- switch (match[1]) {
427
- case '--version':
428
- case '--help':
429
- return [];
430
- default:
431
- return match[3] ? [match[1] + '=' + (0, types_1.sanitizeArgs)(match[3], doubleQuote)] : [match[1]];
432
- }
433
- }
434
- }
435
- else if (value) {
436
- return [(0, types_1.sanitizeArgs)(value, doubleQuote)];
437
- }
438
- break;
439
- }
440
- case 'number':
441
- case 'boolean':
442
- return [opt.toString()];
443
- default:
444
- if ((0, types_1.isArray)(opt)) {
445
- return opt.filter(item => (0, types_1.isString)(item)).map(item => (0, types_1.sanitizeArgs)(item, doubleQuote));
446
- }
447
- break;
448
- }
449
- return [];
450
- }).flat();
451
- }
452
- return [pathname, (0, util_1.parseOutgoingHeaders)(options.headers), binOpts];
453
- }
454
401
  function checkBinTarget(instance, name, uri, pathname, command, binOpts) {
455
- if (!(0, types_1.isString)(pathname)) {
402
+ if (!pathname) {
456
403
  throw (0, types_1.errorMessage)(name, "Invalid parameters", 'pathname');
457
404
  }
458
405
  pathname = path.resolve(pathname);
@@ -549,7 +496,6 @@ function addAria2Proxy(args, protocol, host) {
549
496
  args.push(`--${protocol}-proxy-passwd="${escapeShellQuote(decodeURIComponent(password))}"`);
550
497
  }
551
498
  }
552
- const isConstructor = (value) => typeof value === 'function';
553
499
  const isDirEnd = (value) => value.endsWith('/') || value.endsWith(path.sep);
554
500
  const trimCharEnd = (value) => value.substring(0, value.length - 1);
555
501
  const configureDns = (family, options) => family === 0 ? options : { family, hints: family === 6 ? dns.V4MAPPED : 0 };
@@ -578,7 +524,8 @@ class Request extends module_1 {
578
524
  }
579
525
  const { request, download } = settings;
580
526
  if (download?.aria2) {
581
- let { update_status, max_concurrent_downloads, max_connection_per_server, check_integrity, bt_stop_timeout, bt_tracker_connect_timeout, bt_tracker_timeout, min_split_size, disk_cache, lowest_speed_limit, always_resume, file_allocation, proxy, no_proxy, conf_path } = download.aria2;
527
+ const aria2 = download.aria2;
528
+ let { update_status, check_integrity, bt_stop_timeout, min_split_size, disk_cache, lowest_speed_limit, always_resume, file_allocation, proxy, no_proxy, conf_path } = aria2;
582
529
  setBinExec(download.aria2, ARIA2);
583
530
  if ((0, types_1.isPlainObject)(update_status)) {
584
531
  const { interval, broadcast_only } = update_status;
@@ -593,21 +540,9 @@ class Request extends module_1 {
593
540
  if (typeof check_integrity === 'boolean') {
594
541
  ARIA2.CHECK_INTEGRITY = check_integrity;
595
542
  }
596
- if ((max_concurrent_downloads = (0, util_1.asInt)(max_concurrent_downloads)) > 0) {
597
- ARIA2.MAX_CONCURRENT_DOWNLOADS = max_concurrent_downloads;
598
- }
599
- if ((max_connection_per_server = (0, util_1.asInt)(max_connection_per_server)) > 0) {
600
- ARIA2.MAX_CONNECTION_PER_SERVER = max_connection_per_server;
601
- }
602
543
  if ((bt_stop_timeout = (0, util_1.asInt)(bt_stop_timeout)) >= 0) {
603
544
  ARIA2.BT_STOP_TIMEOUT = bt_stop_timeout;
604
545
  }
605
- if ((bt_tracker_connect_timeout = (0, util_1.asInt)(bt_tracker_connect_timeout)) > 0) {
606
- ARIA2.BT_TRACKER_CONNECT_TIMEOUT = bt_tracker_connect_timeout;
607
- }
608
- if ((bt_tracker_timeout = (0, util_1.asInt)(bt_tracker_timeout)) > 0) {
609
- ARIA2.BT_TRACKER_TIMEOUT = bt_tracker_timeout;
610
- }
611
546
  if (min_split_size = parseSize(min_split_size, false)) {
612
547
  ARIA2.MIN_SPLIT_SIZE = min_split_size;
613
548
  }
@@ -644,22 +579,23 @@ class Request extends module_1 {
644
579
  else if (proxy === false) {
645
580
  ARIA2.PROXY = {};
646
581
  }
647
- if (no_proxy === '' || (0, types_1.isString)(no_proxy)) {
582
+ if (typeof no_proxy === 'string') {
648
583
  ARIA2.NO_PROXY = no_proxy;
649
584
  }
650
585
  if (conf_path === '' || (0, types_1.isString)(conf_path) && this.isPath(conf_path = path.resolve(conf_path))) {
651
586
  ARIA2.CONF_PATH = conf_path;
652
587
  }
588
+ for (const name of ['max_concurrent_downloads', 'max_connection_per_server', 'bt_tracker_connect_timeout', 'bt_tracker_timeout']) {
589
+ let value = aria2[name];
590
+ if ((value = (0, util_1.asInt)(value)) > 0) {
591
+ ARIA2[name.toUpperCase()] = value;
592
+ }
593
+ }
653
594
  }
654
595
  if (download?.rclone) {
655
- let { check_first, checksum, cutoff_mode, ignore_case_sync, ignore_checksum, ignore_existing, ignore_size, ignore_times, immutable, inplace, max_backlog, max_duration, max_transfer, metadata, modify_window, multi_thread_chunk_size, multi_thread_cutoff, multi_thread_streams, multi_thread_write_buffer_size, no_check_dest, no_traverse, no_update_dir_modtime, refresh_times, size_only, update, fast_list, bind, contimeout, disable_http2, timeout, config } = download.rclone;
596
+ const rclone = download.rclone;
597
+ let { cutoff_mode, hash, max_backlog, max_duration, max_transfer, modify_window, multi_thread_chunk_size, multi_thread_cutoff, multi_thread_streams, multi_thread_write_buffer_size, streaming_upload_cutoff, bind, contimeout, timeout } = rclone;
656
598
  setBinExec(download.rclone, RCLONE);
657
- if (typeof check_first === 'boolean') {
658
- RCLONE.CHECK_FIRST = check_first;
659
- }
660
- if (typeof checksum === 'boolean') {
661
- RCLONE.CHECKSUM = checksum;
662
- }
663
599
  if ((0, types_1.isString)(cutoff_mode)) {
664
600
  const value = cutoff_mode.toUpperCase();
665
601
  switch (value) {
@@ -670,26 +606,18 @@ class Request extends module_1 {
670
606
  break;
671
607
  }
672
608
  }
673
- if (typeof ignore_case_sync === 'boolean') {
674
- RCLONE.IGNORE_CASE_SYNC = ignore_case_sync;
675
- }
676
- if (typeof ignore_checksum === 'boolean') {
677
- RCLONE.IGNORE_CHECKSUM = ignore_checksum;
678
- }
679
- if (typeof ignore_existing === 'boolean') {
680
- RCLONE.IGNORE_EXISTING = ignore_existing;
681
- }
682
- if (typeof ignore_size === 'boolean') {
683
- RCLONE.IGNORE_SIZE = ignore_size;
684
- }
685
- if (typeof ignore_times === 'boolean') {
686
- RCLONE.IGNORE_TIMES = ignore_times;
687
- }
688
- if (typeof immutable === 'boolean') {
689
- RCLONE.IMMUTABLE = immutable;
690
- }
691
- if (typeof inplace === 'boolean') {
692
- RCLONE.INPLACE = inplace;
609
+ if ((0, types_1.isString)(hash)) {
610
+ switch (hash.toLowerCase()) {
611
+ case 'md5':
612
+ RCLONE.HASH = 'md5';
613
+ break;
614
+ case 'sha-1':
615
+ RCLONE.HASH = 'SHA-1';
616
+ break;
617
+ case 'dropboxhash':
618
+ RCLONE.HASH = 'DropboxHash';
619
+ break;
620
+ }
693
621
  }
694
622
  if ((max_backlog = (0, util_1.asInt)(max_backlog)) > 0) {
695
623
  RCLONE.MAX_BACKLOG = max_backlog;
@@ -700,9 +628,6 @@ class Request extends module_1 {
700
628
  if (max_transfer = rcloneSize(max_transfer)) {
701
629
  RCLONE.MAX_TRANSFER = max_transfer;
702
630
  }
703
- if (typeof metadata === 'boolean') {
704
- RCLONE.METADATA = metadata;
705
- }
706
631
  if (modify_window = rcloneDuration(modify_window)) {
707
632
  RCLONE.MODIFY_WINDOW = modify_window;
708
633
  }
@@ -718,26 +643,8 @@ class Request extends module_1 {
718
643
  if (multi_thread_write_buffer_size = rcloneSize(multi_thread_write_buffer_size)) {
719
644
  RCLONE.MULTI_THREAD_WRITE_BUFFER_SIZE = multi_thread_write_buffer_size;
720
645
  }
721
- if (typeof no_check_dest === 'boolean') {
722
- RCLONE.NO_CHECK_DEST = no_check_dest;
723
- }
724
- if (typeof no_traverse === 'boolean') {
725
- RCLONE.NO_TRAVERSE = no_traverse;
726
- }
727
- if (typeof no_update_dir_modtime === 'boolean') {
728
- RCLONE.NO_UPDATE_DIR_MODTIME = no_update_dir_modtime;
729
- }
730
- if (typeof refresh_times === 'boolean') {
731
- RCLONE.REFRESH_TIMES = refresh_times;
732
- }
733
- if (typeof size_only === 'boolean') {
734
- RCLONE.SIZE_ONLY = size_only;
735
- }
736
- if (typeof update === 'boolean') {
737
- RCLONE.UPDATE = update;
738
- }
739
- if (typeof fast_list === 'boolean') {
740
- RCLONE.FAST_LIST = fast_list;
646
+ if (streaming_upload_cutoff = rcloneSize(streaming_upload_cutoff)) {
647
+ RCLONE.STREAMING_UPLOAD_CUTOFF = streaming_upload_cutoff;
741
648
  }
742
649
  if (contimeout = rcloneDuration(contimeout)) {
743
650
  RCLONE.CONTIMEOUT = contimeout;
@@ -745,14 +652,20 @@ class Request extends module_1 {
745
652
  if (typeof bind === 'string') {
746
653
  RCLONE.BIND = bind;
747
654
  }
748
- if (typeof disable_http2 === 'boolean') {
749
- RCLONE.DISABLE_HTTP2 = disable_http2;
750
- }
751
655
  if (timeout = rcloneDuration(timeout)) {
752
656
  RCLONE.TIMEOUT = timeout;
753
657
  }
754
- if (config === '' || (0, types_1.isString)(config) && this.isPath(config = path.resolve(config), true)) {
755
- RCLONE.CONFIG = config;
658
+ for (const name of ['check_first', 'checksum', 'csv', 'ignore_case_sync', 'ignore_checksum', 'ignore_existing', 'ignore_size', 'ignore_times', 'immutable', 'inplace', 'metadata', 'no_check_dest', 'no_traverse', 'no_update_dir_modtime', 'no_update_modtime', 'refresh_times', 'size_only', 'update', 'fast_list', 'disable_http2']) {
659
+ const value = rclone[name];
660
+ if (typeof value === 'boolean') {
661
+ RCLONE[name.toUpperCase()] = value;
662
+ }
663
+ }
664
+ for (const name of ['combined', 'differ', 'error', 'config']) {
665
+ let value = rclone[name];
666
+ if (value === '' || (0, types_1.isString)(value) && this.isPath(value = path.resolve(value), true)) {
667
+ RCLONE[name.toUpperCase()] = value;
668
+ }
756
669
  }
757
670
  }
758
671
  if (request) {
@@ -814,13 +727,7 @@ class Request extends module_1 {
814
727
  return this.readCACert(value, cache);
815
728
  }
816
729
  static isCert(value) {
817
- return typeof value === 'string' && (value = value.trim()).length > 0 && REGEXP_PEMCERT.test(value);
818
- }
819
- static fromURL(url, value) {
820
- return (0, util_1.fromURL)(url, value);
821
- }
822
- static fromStatusCode(value) {
823
- return (0, util_1.fromStatusCode)(value);
730
+ return typeof value === 'string' && (value = value.trim()).length > 0 && /^-{3,}[ \t]*BEGIN[ \t].+\n-{3,}[ \t]*END[ \t][^-]+-{3,}$/s.test(value);
824
731
  }
825
732
  static defineHttpAgent(options) {
826
733
  const { keepAlive, timeout = 0 } = options;
@@ -847,15 +754,25 @@ class Request extends module_1 {
847
754
  if (reset) {
848
755
  clearDnsLookup();
849
756
  }
850
- switch (family = (0, util_1.asInt)(family)) {
851
- case 0:
852
- case 4:
853
- case 6:
854
- DNS.FAMILY = family;
757
+ switch (family) {
758
+ case 'IPv4':
759
+ DNS.FAMILY = 4;
760
+ break;
761
+ case 'IPv6':
762
+ DNS.FAMILY = 6;
763
+ break;
764
+ default:
765
+ switch (family = (0, util_1.asInt)(family)) {
766
+ case 0:
767
+ case 4:
768
+ case 6:
769
+ DNS.FAMILY = family;
770
+ break;
771
+ }
855
772
  break;
856
773
  }
857
774
  if (expires !== undefined) {
858
- if (typeof expires === 'string') {
775
+ if ((0, types_1.isString)(expires)) {
859
776
  expires = (0, types_1.parseExpires)(expires);
860
777
  }
861
778
  if (expires >= 0) {
@@ -863,14 +780,14 @@ class Request extends module_1 {
863
780
  }
864
781
  }
865
782
  for (const hostname in resolve) {
866
- let { address, family: ipv } = resolve[hostname];
867
- if (address && (ipv = ipv && ((ipv = +ipv) === 4 || ipv === 6) ? ipv : net.isIPv6(address) ? 6 : net.isIPv4(address) ? 4 : 0)) {
868
- DNS.CACHE[hostname] = [{ address, family: ipv }];
783
+ const { address, family: ipv } = resolve[hostname];
784
+ if (address && (family = (0, util_1.asInt)(ipv) && (family === 4 || family === 6) ? family : net.isIPv6(address) ? 6 : net.isIPv4(address) ? 4 : 0)) {
785
+ DNS.CACHE[hostname] = [{ address, family }];
869
786
  }
870
787
  }
871
788
  }
872
789
  static defineHttpAdapter(module) {
873
- if (isConstructor(module) && module.prototype instanceof adapter_1) {
790
+ if (adapter_1.constructorOf(module)) {
874
791
  HTTP_ADAPTER = module;
875
792
  }
876
793
  }
@@ -1104,8 +1021,12 @@ class Request extends module_1 {
1104
1021
  }
1105
1022
  break;
1106
1023
  case 'readExpect':
1107
- if ((0, types_1.isString)(value)) {
1108
- this[name] = value;
1024
+ switch (value) {
1025
+ case 'string':
1026
+ case 'always':
1027
+ case 'none':
1028
+ this[name] = value;
1029
+ break;
1109
1030
  }
1110
1031
  break;
1111
1032
  }
@@ -1280,12 +1201,15 @@ class Request extends module_1 {
1280
1201
  return Promise.reject((0, types_1.errorMessage)("aria2", "Binary not found"));
1281
1202
  }
1282
1203
  let pathname, headers, binOpts, signal, silent;
1283
- if ((0, types_1.isString)(options)) {
1204
+ if (typeof options === 'string') {
1284
1205
  pathname = options;
1285
1206
  }
1207
+ else if (options instanceof URL) {
1208
+ pathname = (0, node_url_1.fileURLToPath)(options);
1209
+ }
1286
1210
  else {
1287
1211
  ({ signal, silent } = options);
1288
- [pathname, headers, binOpts] = parseBinOpts(this, options, ['--daemon'], ['--input-file'], options.shellExpansion);
1212
+ ({ pathname, headers, binOpts } = this.parseBinOpts(options, ['--daemon'], ['--input-file']));
1289
1213
  }
1290
1214
  try {
1291
1215
  if (typeof uri === 'string' && module_1.isURL(uri)) {
@@ -1537,13 +1461,17 @@ class Request extends module_1 {
1537
1461
  }
1538
1462
  uri = uri.toString();
1539
1463
  let pathname, headers, binOpts, silent;
1540
- if ((0, types_1.isString)(options)) {
1464
+ if (typeof options === 'string') {
1541
1465
  pathname = options;
1542
1466
  options = {};
1543
1467
  }
1468
+ else if (options instanceof URL) {
1469
+ pathname = (0, node_url_1.fileURLToPath)(options);
1470
+ options = {};
1471
+ }
1544
1472
  else {
1545
1473
  silent = options.silent;
1546
- [pathname, headers, binOpts] = parseBinOpts(this, options, ['--interactive', '--dry-run'], ['--partial-suffix', '--verbose'], options.shellExpansion);
1474
+ ({ pathname, headers, binOpts } = this.parseBinOpts(options, ['--interactive', '--dry-run'], ['–name-transform', '--partial-suffix', '--verbose']));
1547
1475
  }
1548
1476
  const command = options.command || 'copy';
1549
1477
  let source;
@@ -1593,6 +1521,12 @@ class Request extends module_1 {
1593
1521
  if (RCLONE.CUTOFF_MODE) {
1594
1522
  opts.push('--cutoff-mode=' + RCLONE.CUTOFF_MODE);
1595
1523
  }
1524
+ if (RCLONE.CSV) {
1525
+ opts.push('--csv');
1526
+ }
1527
+ if (RCLONE.HASH) {
1528
+ opts.push('--hash=' + RCLONE.HASH);
1529
+ }
1596
1530
  if (RCLONE.IGNORE_CASE_SYNC) {
1597
1531
  opts.push('--ignore-case-sync');
1598
1532
  }
@@ -1650,12 +1584,18 @@ class Request extends module_1 {
1650
1584
  if (RCLONE.NO_UPDATE_DIR_MODTIME) {
1651
1585
  opts.push('--no-update-dir-modtime');
1652
1586
  }
1587
+ if (RCLONE.NO_UPDATE_MODTIME) {
1588
+ opts.push('--no-update-modtime');
1589
+ }
1653
1590
  if (RCLONE.REFRESH_TIMES) {
1654
1591
  opts.push('--refresh-times');
1655
1592
  }
1656
1593
  if (RCLONE.SIZE_ONLY) {
1657
1594
  opts.push('--size-only');
1658
1595
  }
1596
+ if (RCLONE.STREAMING_UPLOAD_CUTOFF) {
1597
+ opts.push('--streaming-upload-cutoff');
1598
+ }
1659
1599
  if (RCLONE.FAST_LIST) {
1660
1600
  opts.push('--fast-list');
1661
1601
  }
@@ -1677,6 +1617,15 @@ class Request extends module_1 {
1677
1617
  else if (this._config.timeout > 0) {
1678
1618
  opts.push(`--timeout=${this._config.timeout}ms`);
1679
1619
  }
1620
+ if (RCLONE.COMBINED) {
1621
+ opts.push(`--combined="${escapeShellQuote(RCLONE.COMBINED)}"`);
1622
+ }
1623
+ if (RCLONE.DIFFER) {
1624
+ opts.push(`--differ="${escapeShellQuote(RCLONE.DIFFER)}"`);
1625
+ }
1626
+ if (RCLONE.ERROR) {
1627
+ opts.push(`--error="${escapeShellQuote(RCLONE.ERROR)}"`);
1628
+ }
1680
1629
  if (RCLONE.CONFIG) {
1681
1630
  opts.push(`--config="${escapeShellQuote(RCLONE.CONFIG)}"`);
1682
1631
  }
@@ -1868,7 +1817,7 @@ class Request extends module_1 {
1868
1817
  const baseHeaders = this.headersOf(uri);
1869
1818
  let request, ca, cert, key, ciphers, minVersion;
1870
1819
  if (getting && this.acceptEncoding && !host.localhost && !baseHeaders?.['accept-encoding']) {
1871
- (headers ||= {})['accept-encoding'] ||= 'gzip, deflate, br' + (LIB_ZSTD || SUPPORTED_ZSTD ? ', zstd' : '');
1820
+ (headers ||= {})['accept-encoding'] ||= 'gzip, deflate, br' + (SUPPORTED_ZSTD ? ', zstd' : '');
1872
1821
  }
1873
1822
  if (posting && options.postData) {
1874
1823
  if (expectContinue) {
@@ -1904,7 +1853,7 @@ class Request extends module_1 {
1904
1853
  request.on('response', response => {
1905
1854
  const statusCode = response[':status'];
1906
1855
  if (expectContinue) {
1907
- this.abortHeaders(url.href, request, options, statusCode, "Did not receive continue acknowledgment");
1856
+ this.abortHeaders(request, options, { href: url.href, statusCode, message: "Did not receive continue acknowledgment" });
1908
1857
  return;
1909
1858
  }
1910
1859
  connected = true;
@@ -1983,27 +1932,34 @@ class Request extends module_1 {
1983
1932
  if (!socketPath) {
1984
1933
  let { keepAlive, agentTimeout } = options;
1985
1934
  if (proxy) {
1935
+ keepAlive ??= proxy.keepAlive;
1936
+ agentTimeout ??= proxy.agentTimeout;
1937
+ const proxyHeaders = this.#headers && getBaseHeaders(proxy.host.href, this.#headers) || getBaseHeaders(proxy.host.href, HTTP.HEADERS);
1986
1938
  const pkg = secure ? 'https-proxy-agent' : 'http-proxy-agent';
1987
1939
  try {
1988
- keepAlive ??= proxy.keepAlive;
1989
- agentTimeout ??= proxy.agentTimeout;
1990
- const proxyHeaders = this.#headers && getBaseHeaders(proxy.host.href, this.#headers) || getBaseHeaders(proxy.host.href, HTTP.HEADERS);
1991
1940
  agent = require(pkg)(proxy.host, (typeof keepAlive === 'boolean' || agentTimeout > 0) && agentTimeout !== 0 ? { keepAlive: keepAlive ?? true, timeout: agentTimeout, headers: proxyHeaders } : { headers: proxyHeaders });
1992
1941
  }
1993
1942
  catch (err) {
1994
- this.checkPackage(err, pkg, "Unknown");
1943
+ if (!SUPPORTED_PROXY || proxyHeaders) {
1944
+ this.checkPackage(err, pkg, proxyHeaders ? "Unable to process headers" : '');
1945
+ }
1995
1946
  }
1996
1947
  }
1997
- else if (keepAlive === false) {
1998
- agent = new (secure ? https.Agent : http.Agent)({ keepAlive: false });
1999
- }
2000
- else if (keepAlive === true || agentTimeout > 0) {
2001
- agent = new (secure ? https.Agent : http.Agent)({ keepAlive: true, timeout: agentTimeout });
2002
- }
2003
- else if (agentTimeout !== 0) {
2004
- agentTimeout ??= this.agentTimeout;
2005
- if (this.keepAlive !== null || agentTimeout > 0) {
2006
- agent = new (secure ? https.Agent : http.Agent)({ keepAlive: this.keepAlive ?? true, timeout: agentTimeout });
1948
+ if (!agent) {
1949
+ let proxyEnv;
1950
+ if (proxy && SUPPORTED_PROXY) {
1951
+ const http_proxy = proxy.host.toString();
1952
+ proxyEnv = { http_proxy, https_proxy: http_proxy };
1953
+ }
1954
+ if (keepAlive === false) {
1955
+ agent = new (secure ? https.Agent : http.Agent)({ keepAlive: false, proxyEnv });
1956
+ }
1957
+ else if (keepAlive === true || agentTimeout > 0) {
1958
+ agent = new (secure ? https.Agent : http.Agent)({ keepAlive: true, timeout: agentTimeout, proxyEnv });
1959
+ }
1960
+ else if (agentTimeout !== 0 || proxyEnv) {
1961
+ agentTimeout ??= this.agentTimeout;
1962
+ agent = new (secure ? https.Agent : http.Agent)({ keepAlive: this.keepAlive ?? true, timeout: agentTimeout || undefined, proxyEnv });
2007
1963
  }
2008
1964
  }
2009
1965
  }
@@ -2099,7 +2055,7 @@ class Request extends module_1 {
2099
2055
  request.emit('end');
2100
2056
  });
2101
2057
  if (expectContinue) {
2102
- this.abortHeaders(url.href, request, options, statusCode, "Did not receive continue acknowledgment");
2058
+ this.abortHeaders(request, options, { href: url.href, statusCode, message: "Did not receive continue acknowledgment" });
2103
2059
  return;
2104
2060
  }
2105
2061
  }
@@ -2126,17 +2082,6 @@ class Request extends module_1 {
2126
2082
  ac.abort(new Error("Aborted by process"));
2127
2083
  }, { once: true });
2128
2084
  }
2129
- const sendBody = () => {
2130
- if (posting) {
2131
- const postData = options.postData;
2132
- if ((0, types_1.isString)(postData) || Buffer.isBuffer(postData)) {
2133
- request.write(postData);
2134
- }
2135
- else if (postData instanceof stream.Stream) {
2136
- postData.pipe(request);
2137
- }
2138
- }
2139
- };
2140
2085
  if (expectContinue) {
2141
2086
  const pending = setTimeout(() => {
2142
2087
  request.end();
@@ -2144,12 +2089,18 @@ class Request extends module_1 {
2144
2089
  request.on('continue', () => {
2145
2090
  clearTimeout(pending);
2146
2091
  expectContinue = false;
2147
- sendBody();
2148
- request.end();
2092
+ if (posting) {
2093
+ sendBody(request, options);
2094
+ }
2095
+ else {
2096
+ request.end();
2097
+ }
2149
2098
  });
2150
2099
  }
2100
+ else if (posting) {
2101
+ sendBody(request, options);
2102
+ }
2151
2103
  else {
2152
- sendBody();
2153
2104
  request.end();
2154
2105
  }
2155
2106
  return request;
@@ -2246,7 +2197,7 @@ class Request extends module_1 {
2246
2197
  type ||= module_1.lookupMime(filename);
2247
2198
  target = fs.readFileSync(target);
2248
2199
  }
2249
- else if (target instanceof stream.Readable) {
2200
+ else if (stream.Readable.isReadable(target)) {
2250
2201
  const chunks = [];
2251
2202
  for await (const chunk of target) {
2252
2203
  chunks.push(chunk);
@@ -2371,7 +2322,7 @@ class Request extends module_1 {
2371
2322
  for (const callback of called) {
2372
2323
  try {
2373
2324
  if (callback(code, headers, url) === true) {
2374
- this.abortHeaders(href, request, options, code);
2325
+ this.abortHeaders(request, options, { href, statusCode: code });
2375
2326
  return false;
2376
2327
  }
2377
2328
  }
@@ -2403,7 +2354,7 @@ class Request extends module_1 {
2403
2354
  for (const [callback, data] of called) {
2404
2355
  try {
2405
2356
  if (callback(data, url) === true) {
2406
- this.abortHeaders(href, request, options);
2357
+ this.abortHeaders(request, options, { href });
2407
2358
  return false;
2408
2359
  }
2409
2360
  }
@@ -2414,7 +2365,7 @@ class Request extends module_1 {
2414
2365
  }
2415
2366
  return true;
2416
2367
  }
2417
- abortHeaders(href, request, options, statusCode = '', message = "Aborted by client") {
2368
+ abortHeaders(request, options, { href, statusCode = '', message = "Aborted by client" } = {}) {
2418
2369
  const reason = (0, types_1.errorMessage)(statusCode, message, href);
2419
2370
  const outAbort = options.outAbort;
2420
2371
  if (outAbort) {
@@ -2423,8 +2374,71 @@ class Request extends module_1 {
2423
2374
  }
2424
2375
  request.destroy(reason);
2425
2376
  }
2377
+ parseBinOpts(options, ignore, skip, doubleQuote = options.shellExpansion) {
2378
+ let pathname = options.pathname, binOpts;
2379
+ if (pathname instanceof URL) {
2380
+ pathname = (0, node_url_1.fileURLToPath)(pathname);
2381
+ }
2382
+ else if (!(0, types_1.isString)(pathname)) {
2383
+ if (!this.host) {
2384
+ return {};
2385
+ }
2386
+ pathname = process.cwd();
2387
+ }
2388
+ if ((0, types_1.isArray)(options.binOpts)) {
2389
+ let next = false;
2390
+ binOpts = options.binOpts.filter((opt) => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt.trim()))).map((opt) => {
2391
+ if (next) {
2392
+ if (!module_1.asString(opt).startsWith('--')) {
2393
+ return [];
2394
+ }
2395
+ next = false;
2396
+ }
2397
+ switch (typeof opt) {
2398
+ case 'string': {
2399
+ const value = opt.trim();
2400
+ if (value.startsWith('--')) {
2401
+ const match = /^(--[a-z]+[a-z0-9-]*)(=)?\s*(.*)$/s.exec(value);
2402
+ if (match) {
2403
+ if (ignore.includes(match[1])) {
2404
+ return [];
2405
+ }
2406
+ if (skip.includes(match[1])) {
2407
+ if (!match[2]) {
2408
+ next = true;
2409
+ }
2410
+ return [];
2411
+ }
2412
+ switch (match[1]) {
2413
+ case '--version':
2414
+ case '--help':
2415
+ return [];
2416
+ default:
2417
+ return match[3] ? [match[1] + '=' + (0, types_1.sanitizeArgs)(match[3], doubleQuote)] : [match[1]];
2418
+ }
2419
+ }
2420
+ }
2421
+ else if (value) {
2422
+ return [(0, types_1.sanitizeArgs)(value, doubleQuote)];
2423
+ }
2424
+ break;
2425
+ }
2426
+ case 'number':
2427
+ case 'boolean':
2428
+ return [opt.toString()];
2429
+ default:
2430
+ if ((0, types_1.isArray)(opt)) {
2431
+ return opt.filter(item => (0, types_1.isString)(item)).map(item => (0, types_1.sanitizeArgs)(item, doubleQuote));
2432
+ }
2433
+ break;
2434
+ }
2435
+ return [];
2436
+ }).flat();
2437
+ }
2438
+ return { pathname, headers: (0, util_1.parseOutgoingHeaders)(options.headers), binOpts };
2439
+ }
2426
2440
  set adapter(value) {
2427
- if (isConstructor(value) && value.prototype instanceof adapter_1) {
2441
+ if (adapter_1.constructorOf(value)) {
2428
2442
  this.#adapter = value;
2429
2443
  }
2430
2444
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/request",
3
- "version": "0.12.8",
3
+ "version": "0.13.0",
4
4
  "description": "Request constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -19,8 +19,8 @@
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.8",
23
- "@e-mc/types": "0.12.8",
22
+ "@e-mc/module": "0.13.0",
23
+ "@e-mc/types": "0.13.0",
24
24
  "combined-stream": "^1.0.8",
25
25
  "js-yaml": "^4.1.0",
26
26
  "picomatch": "^4.0.3",
package/util.js CHANGED
@@ -142,7 +142,7 @@ function isRetryable(value, timeout) {
142
142
  }
143
143
  function parseHttpProxy(value, ignoreEnv) {
144
144
  if (!ignoreEnv) {
145
- value ||= process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
145
+ value ||= process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.ALL_PROXY;
146
146
  }
147
147
  if (value) {
148
148
  try {
@@ -426,7 +426,7 @@ function cleanupStream(stream, uri) {
426
426
  }
427
427
  }
428
428
  catch (err) {
429
- if (!module_1.isErrorCode(err, 'ENOENT')) {
429
+ if (!(0, types_1.isErrorCode)(err, 'ENOENT')) {
430
430
  module_1.writeFail(["Unable to delete file", path.basename(uri)], err, 32);
431
431
  }
432
432
  }