@e-mc/request 0.10.2 → 0.10.3

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
@@ -9,12 +9,12 @@
9
9
 
10
10
  ## Interface
11
11
 
12
- * [View Source](https://www.unpkg.com/@e-mc/types@0.10.2/lib/index.d.ts)
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.10.3/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { IModule, ModuleConstructor } from "./index";
16
16
  import type { HttpAgentSettings, HttpProtocolVersion, HttpRequestClient, InternetProtocolVersion } from "./http";
17
- import type { ApplyOptions, Aria2Options, FormDataPart, HeadersOnCallback, HostConfig, OpenOptions, PostOptions, ProxySettings, ReadExpectType, RequestInit, StatusOnCallback } from "./request";
17
+ import type { ApplyOptions, Aria2Options, FormDataPart, HeadersOnCallback, HostConfig, OpenOptions, PostOptions, ProxySettings, PutOptions, ReadExpectType, RequestInit, StatusOnCallback } from "./request";
18
18
  import type { DnsLookupSettings, RequestModule, RequestSettings } from "./settings";
19
19
 
20
20
  import type { ClientRequest, OutgoingHttpHeaders } from "http";
@@ -47,7 +47,8 @@ interface IRequest extends IModule {
47
47
  opts(url: string | URL, options?: OpenOptions): HostConfig;
48
48
  open(uri: string | URL, options: OpenOptions): HttpRequestClient;
49
49
  head(uri: string | URL, options?: OpenOptions): ClientRequest;
50
- post(uri: string | URL, data: unknown, contentType: string): Promise<Buffer | string | null>;
50
+ put(uri: string | URL, data: unknown, options: PutOptions): Promise<Buffer | string | null>;
51
+ put(uri: string | URL, data: unknown, contentType?: string, options?: PutOptions): Promise<Buffer | string | null>;
51
52
  post(uri: string | URL, parts: FormDataPart[]): Promise<Buffer | string | null>;
52
53
  post(uri: string | URL, form: Record<string, unknown>, parts: FormDataPart[]): Promise<Buffer | string | null>;
53
54
  post(uri: string | URL, data: unknown, options: PostOptions): Promise<Buffer | string | null>;
@@ -204,9 +205,9 @@ instance.get("http://hostname/path/config.yml", options).then(data => {
204
205
 
205
206
  ## References
206
207
 
207
- - https://www.unpkg.com/@e-mc/types@0.10.2/lib/http.d.ts
208
- - https://www.unpkg.com/@e-mc/types@0.10.2/lib/request.d.ts
209
- - https://www.unpkg.com/@e-mc/types@0.10.2/lib/settings.d.ts
208
+ - https://www.unpkg.com/@e-mc/types@0.10.3/lib/http.d.ts
209
+ - https://www.unpkg.com/@e-mc/types@0.10.3/lib/request.d.ts
210
+ - https://www.unpkg.com/@e-mc/types@0.10.3/lib/settings.d.ts
210
211
 
211
212
  * https://www.npmjs.com/package/@types/node
212
213
 
@@ -1,5 +1,5 @@
1
- import type { HttpHostConstructor } from '../../../types/lib/request';
2
-
3
- declare const HttpHost: HttpHostConstructor;
4
-
1
+ import type { HttpHostConstructor } from '@e-mc/types/lib/request';
2
+
3
+ declare const HttpHost: HttpHostConstructor;
4
+
5
5
  export = HttpHost;
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { RequestConstructor } from '../types/lib';
2
-
3
- declare const Request: RequestConstructor;
4
-
1
+ import type { RequestConstructor } from '@e-mc/types/lib';
2
+
3
+ declare const Request: RequestConstructor;
4
+
5
5
  export = Request;
package/index.js CHANGED
@@ -16,8 +16,8 @@ const combined = require("combined-stream");
16
16
  const pm = require("picomatch");
17
17
  const yaml = require("js-yaml");
18
18
  const which = require("which");
19
- const module_1 = require("@e-mc/module");
20
19
  const types_1 = require("@e-mc/types");
20
+ const module_1 = require("@e-mc/module");
21
21
  const util_1 = require("@e-mc/request/util");
22
22
  const host_1 = require("@e-mc/request/http/host");
23
23
  const kSession = Symbol('session');
@@ -331,8 +331,8 @@ function decompressEncoding(value, chunkSize) {
331
331
  break;
332
332
  }
333
333
  }
334
- function abortHeaders(href, request, options) {
335
- const reason = (0, types_1.errorValue)("Aborted by client", href);
334
+ function abortHeaders(href, request, options, statusCode = '') {
335
+ const reason = (0, types_1.errorMessage)(statusCode, "Aborted by client", href);
336
336
  const outAbort = options.outAbort;
337
337
  if (outAbort) {
338
338
  outAbort.abort(reason);
@@ -413,12 +413,13 @@ class Fetch {
413
413
  }
414
414
  async start() {
415
415
  return new Promise((resolve, reject) => {
416
- this.promise = [resolve, reject];
416
+ this.resolve = resolve;
417
+ this.reject = reject;
417
418
  this.init();
418
419
  });
419
420
  }
420
421
  init() {
421
- if (this.retries > 0) {
422
+ if (this.aborted || this.retries > 0) {
422
423
  this.cleanup();
423
424
  this.aborted = false;
424
425
  }
@@ -445,7 +446,7 @@ class Fetch {
445
446
  statusCode === 404 ||
446
447
  statusCode === 407 ||
447
448
  statusCode === 410) {
448
- this.rejectError(this.formatStatus(statusCode));
449
+ this.terminate(this.formatStatus(statusCode));
449
450
  }
450
451
  else if (this.isRetry(statusCode)) {
451
452
  this.retryResponse(statusCode, headers['retry-after']);
@@ -473,7 +474,7 @@ class Fetch {
473
474
  })
474
475
  .on('aborted', () => {
475
476
  this.aborted = true;
476
- this.rejectError((0, types_1.createAbortError)());
477
+ this.terminate((0, types_1.createAbortError)());
477
478
  })
478
479
  .on('error', async (err) => {
479
480
  if (this.aborted) {
@@ -514,13 +515,12 @@ class Fetch {
514
515
  this.retryResponse(statusCode, res.headers['retry-after']);
515
516
  }
516
517
  else {
517
- this.abortResponse();
518
- this.rejectError(this.formatStatus(statusCode));
518
+ this.terminate(this.formatStatus(statusCode));
519
519
  }
520
520
  })
521
521
  .on('abort', () => {
522
522
  this.aborted = true;
523
- this.rejectError((0, types_1.createAbortError)());
523
+ this.terminate((0, types_1.createAbortError)());
524
524
  })
525
525
  .on('error', err => {
526
526
  if (!this.aborted) {
@@ -532,12 +532,12 @@ class Fetch {
532
532
  if (this.aborted) {
533
533
  return;
534
534
  }
535
- this.abortResponse();
536
535
  if (++this.retries <= this.retryLimit) {
536
+ this.abortResponse();
537
537
  this.retryTimeout();
538
538
  }
539
539
  else {
540
- this.rejectError(this.formatStatus(408));
540
+ this.terminate(this.formatStatus(408));
541
541
  }
542
542
  });
543
543
  }
@@ -553,7 +553,7 @@ class Fetch {
553
553
  this.config.outStream = this.outStream;
554
554
  }
555
555
  catch (err) {
556
- this.rejectError(err);
556
+ this.terminate(err);
557
557
  }
558
558
  }
559
559
  else {
@@ -568,12 +568,6 @@ class Fetch {
568
568
  clearTimeout(this.timeout);
569
569
  }
570
570
  this.aborted = true;
571
- if (this.outAbort) {
572
- if (!this.client.aborted) {
573
- this.outAbort.abort();
574
- }
575
- this.downloading.delete(this.outAbort);
576
- }
577
571
  this.client.destroy();
578
572
  }
579
573
  retryDownload(downgrade, message) {
@@ -613,8 +607,7 @@ class Fetch {
613
607
  client.once('readable', () => {
614
608
  if (instance.readTimeout > 0) {
615
609
  this.timeout = setTimeout(() => {
616
- this.abortResponse();
617
- this.rejectError((0, types_1.errorValue)("Timeout was exceeded", this.uri.toString()));
610
+ this.terminate((0, types_1.errorValue)("Timeout was exceeded", this.uri.toString()));
618
611
  }, instance.readTimeout);
619
612
  }
620
613
  if (log) {
@@ -664,8 +657,7 @@ class Fetch {
664
657
  dataLength += Buffer.byteLength(chunk, encoding);
665
658
  }
666
659
  if (dataLength > maxBufferSize) {
667
- this.abortResponse();
668
- this.rejectError((0, types_1.errorValue)("Size limit was exceeded", this.uri.toString()));
660
+ this.terminate((0, types_1.errorValue)("Size limit was exceeded", this.uri.toString()));
669
661
  }
670
662
  }
671
663
  });
@@ -674,13 +666,7 @@ class Fetch {
674
666
  if (this.closed || this.aborted) {
675
667
  return;
676
668
  }
677
- if (this.timeout) {
678
- clearTimeout(this.timeout);
679
- }
680
- if (this.outAbort) {
681
- this.downloading.delete(this.outAbort);
682
- }
683
- this.closed = true;
669
+ this.close();
684
670
  const encoding = opts.encoding;
685
671
  let result, messageUnit, titleBgColor;
686
672
  if (buffer) {
@@ -743,7 +729,7 @@ class Fetch {
743
729
  parent.updateProgress("request", progressId, 0, contentLength);
744
730
  }
745
731
  if (enabled && instance.readExpect === 'always') {
746
- this.rejectError("No data received");
732
+ this.terminate("No data received");
747
733
  return;
748
734
  }
749
735
  result = encoding && !pipeline ? '' : null;
@@ -752,34 +738,34 @@ class Fetch {
752
738
  if (log) {
753
739
  instance.writeTimeProcess('HTTP' + config.httpVersion, config.statusMessage || this.uri.toString(), this.startTime, { type: 1024, queue: !!parent, titleBgColor, messageUnit, messageUnitMinWidth: 9, delayTime, bypassLog: LOG_STDOUT });
754
740
  }
755
- this.promise[0](result);
741
+ this.resolve(result);
756
742
  });
757
743
  config.host.success(this.httpVersion);
758
744
  }
759
745
  redirectResponse(statusCode, location) {
760
- this.abortResponse();
761
746
  if (location) {
762
747
  if (this.config.follow_redirect === false || this.config.followRedirect === false) {
763
- this.rejectError(this.formatStatus(statusCode, "Follow redirect was disabled"));
748
+ this.terminate(this.formatStatus(statusCode, "Follow redirect was disabled"));
764
749
  }
765
750
  else if (++this.redirects <= this.redirectLimit) {
751
+ this.abortResponse();
766
752
  this.setConfig(Request.fromURL(this.config.url, location));
767
753
  this.init();
768
754
  }
769
755
  else {
770
- this.rejectError(this.formatStatus(statusCode, "Exceeded redirect limit"));
756
+ this.terminate(this.formatStatus(statusCode, "Exceeded redirect limit"));
771
757
  }
772
758
  }
773
759
  else {
774
- this.rejectError(this.formatStatus(statusCode, "Missing redirect location"));
760
+ this.terminate(this.formatStatus(statusCode, "Missing redirect location"));
775
761
  }
776
762
  }
777
763
  errorResponse(err) {
778
- this.abortResponse();
779
764
  if (Fetch.wasAborted(err)) {
780
- this.rejectError(err);
765
+ this.terminate(err);
781
766
  }
782
767
  else if ((0, util_1.checkRetryable)(err) && ++this.retries <= this.retryLimit) {
768
+ this.abortResponse();
783
769
  if (Fetch.isConnectionTimeout(err)) {
784
770
  this.retryTimeout();
785
771
  }
@@ -791,7 +777,7 @@ class Fetch {
791
777
  }
792
778
  else {
793
779
  this.config.host.error(this.httpVersion);
794
- this.rejectError(err);
780
+ this.terminate(err);
795
781
  }
796
782
  }
797
783
  retryResponse(statusCode, retryAfter) {
@@ -812,7 +798,7 @@ class Fetch {
812
798
  }, offset);
813
799
  }
814
800
  else {
815
- this.rejectError(this.formatStatus(statusCode));
801
+ this.terminate(this.formatStatus(statusCode));
816
802
  }
817
803
  return;
818
804
  }
@@ -834,17 +820,14 @@ class Fetch {
834
820
  this.sendWarning(this.formatRetry("HTTP connection timeout"));
835
821
  this.init();
836
822
  }
837
- rejectError(err) {
823
+ terminate(err) {
838
824
  if (this.timeout) {
839
825
  clearTimeout(this.timeout);
840
826
  }
841
827
  if (!this.closed) {
842
- this.closed = true;
843
828
  this.cleanup();
844
- this.promise[1](typeof err === 'string' ? new Error(err) : err);
845
- }
846
- if (this.outAbort) {
847
- this.downloading.delete(this.outAbort);
829
+ this.close();
830
+ this.reject(typeof err === 'string' ? new Error(err) : err);
848
831
  }
849
832
  }
850
833
  sendWarning(message) {
@@ -862,6 +845,19 @@ class Fetch {
862
845
  formatRetry(message) {
863
846
  return message + ` (${this.retries} / ${this.retryLimit})`;
864
847
  }
848
+ close() {
849
+ if (this.timeout) {
850
+ clearTimeout(this.timeout);
851
+ }
852
+ this.closed = true;
853
+ const outAbort = this.opts.outAbort;
854
+ if (outAbort) {
855
+ this.downloading.delete(outAbort);
856
+ if (this.aborted && !this.client.aborted && !this.client.destroyed) {
857
+ outAbort.abort();
858
+ }
859
+ }
860
+ }
865
861
  cleanup() {
866
862
  if ((0, types_1.isString)(this.pipeTo) && this.outStream) {
867
863
  (0, util_1.cleanupStream)(this.outStream, this.pipeTo);
@@ -1611,13 +1607,14 @@ class Request extends module_1 {
1611
1607
  if (typeof uri === 'string' && module_1.isURL(uri)) {
1612
1608
  uri = new URL(uri);
1613
1609
  }
1614
- let pathname, headers, binOpts, silent;
1610
+ let pathname, headers, binOpts, signal, silent;
1615
1611
  if (options) {
1616
1612
  if (typeof options === 'string') {
1617
1613
  pathname = options;
1618
1614
  }
1619
1615
  else {
1620
- ({ pathname, headers, binOpts, silent } = options);
1616
+ ({ pathname, binOpts, signal, silent } = options);
1617
+ headers = (0, util_1.parseOutgoingHeaders)(options.headers);
1621
1618
  if ((0, types_1.isArray)(binOpts)) {
1622
1619
  let next = false;
1623
1620
  binOpts = binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt.trim()))).map((opt) => {
@@ -1920,7 +1917,13 @@ class Request extends module_1 {
1920
1917
  }
1921
1918
  for (const item of ARIA2.PID_QUEUE) {
1922
1919
  try {
1923
- process.kill(item[0], 0);
1920
+ if (pid === item[0] && signal?.aborted) {
1921
+ process.kill(item[0]);
1922
+ closeTorrent(item[0]);
1923
+ }
1924
+ else {
1925
+ process.kill(item[0], 0);
1926
+ }
1924
1927
  }
1925
1928
  catch {
1926
1929
  closeTorrent(item[0]);
@@ -1982,9 +1985,17 @@ class Request extends module_1 {
1982
1985
  return { ...options, host, url };
1983
1986
  }
1984
1987
  open(uri, options) {
1985
- let { host, url, httpVersion, method = 'GET', search, encoding, format, headers, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options;
1986
- const getting = method === 'GET';
1987
- const posting = method === 'POST';
1988
+ let { host, url, httpVersion, method = 'GET', search, encoding, format, headers: outgoing, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options, headers = (0, util_1.parseOutgoingHeaders)(outgoing), getting = false, posting = false;
1989
+ switch (method = method.toUpperCase()) {
1990
+ case 'GET':
1991
+ case 'DELETE':
1992
+ getting = true;
1993
+ break;
1994
+ case 'POST':
1995
+ case 'PUT':
1996
+ posting = true;
1997
+ break;
1998
+ }
1988
1999
  if (format) {
1989
2000
  let parser;
1990
2001
  if ((0, types_1.isObject)(format)) {
@@ -2053,12 +2064,12 @@ class Request extends module_1 {
2053
2064
  }
2054
2065
  uri = url.href;
2055
2066
  }
2056
- const { hostname, origin, secure, localhost } = host;
2067
+ const { hostname, origin, secure } = host;
2057
2068
  const pathname = url.pathname + (socketPath ? '' : url.search);
2058
- const proxy = this.proxyOf(uri, localhost);
2069
+ const proxy = this.proxyOf(uri, host.localhost);
2059
2070
  const version = this.httpVersion;
2060
2071
  let request, ca, cert, key, ciphers, minVersion, baseHeaders = this.headersOf(uri);
2061
- if (getting && this.acceptEncoding && !localhost && !baseHeaders?.['accept-encoding']) {
2072
+ if (getting && this.acceptEncoding && !host.localhost && !baseHeaders?.['accept-encoding']) {
2062
2073
  (headers ||= {})['accept-encoding'] ||= 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : '');
2063
2074
  }
2064
2075
  if (secure) {
@@ -2068,7 +2079,7 @@ class Request extends module_1 {
2068
2079
  }
2069
2080
  }
2070
2081
  if (!proxy && httpVersion !== 1 && ((httpVersion || host.version) === 2 && version !== 1 || secure && version === 2 && host.failed(2, true) === 0)) {
2071
- request = (this[kSession][0][origin] ||= http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, ciphers, minVersion, settings: localhost ? { maxFrameSize: 16777215, enablePush: false } : { enablePush: false } })).request({ ...baseHeaders, ...host_1.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
2082
+ request = (this[kSession][0][origin] ||= http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, ciphers, minVersion, settings: host.localhost ? { maxFrameSize: 16777215, enablePush: false } : { enablePush: false } })).request({ ...baseHeaders, ...host_1.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
2072
2083
  if (getting) {
2073
2084
  const listenerMap = {};
2074
2085
  const onEvent = request.on.bind(request);
@@ -2279,6 +2290,9 @@ class Request extends module_1 {
2279
2290
  const ac = new AbortController();
2280
2291
  this[kDownloading].add(options.outAbort = ac);
2281
2292
  stream.addAbortSignal(ac.signal, request);
2293
+ if (options.signal) {
2294
+ stream.addAbortSignal(options.signal, request);
2295
+ }
2282
2296
  this.signal.addEventListener('abort', () => {
2283
2297
  ac.abort(new Error("Aborted by process"));
2284
2298
  }, { once: true });
@@ -2300,8 +2314,21 @@ class Request extends module_1 {
2300
2314
  out.httpVersion = 1;
2301
2315
  return this.open(out.url, out);
2302
2316
  }
2317
+ async put(uri, data, contentType, options) {
2318
+ if ((0, types_1.isPlainObject)(contentType)) {
2319
+ options = contentType;
2320
+ }
2321
+ else {
2322
+ (options ||= {}).contentType = contentType;
2323
+ }
2324
+ options.method = 'PUT';
2325
+ if (options.contentType === "multipart/form-data") {
2326
+ options.contentType = "application/x-www-form-urlencoded";
2327
+ }
2328
+ return this.post(uri, data, options);
2329
+ }
2303
2330
  async post(uri, data, contentType, options) {
2304
- let parts;
2331
+ let putting = false, parts;
2305
2332
  if (Array.isArray(contentType)) {
2306
2333
  parts = contentType;
2307
2334
  contentType = undefined;
@@ -2309,9 +2336,10 @@ class Request extends module_1 {
2309
2336
  else {
2310
2337
  if ((0, types_1.isPlainObject)(contentType)) {
2311
2338
  options = contentType;
2339
+ putting = options.method === 'PUT';
2312
2340
  contentType = undefined;
2313
2341
  }
2314
- if (Array.isArray(data) && (!contentType || contentType === "multipart/form-data")) {
2342
+ if (!putting && Array.isArray(data) && (!contentType || contentType === "multipart/form-data")) {
2315
2343
  parts = data;
2316
2344
  data = undefined;
2317
2345
  }
@@ -2320,7 +2348,7 @@ class Request extends module_1 {
2320
2348
  if ((0, types_1.isPlainObject)(options)) {
2321
2349
  let formData;
2322
2350
  ({ formData, dataEncoding } = options);
2323
- if (formData) {
2351
+ if (!putting && formData) {
2324
2352
  (parts ||= []).push(...Array.isArray(formData) ? formData : [formData]);
2325
2353
  }
2326
2354
  else {
@@ -2330,14 +2358,14 @@ class Request extends module_1 {
2330
2358
  else {
2331
2359
  options = {};
2332
2360
  }
2333
- const headers = options.headers ||= {};
2361
+ const headers = (0, util_1.parseOutgoingHeaders)(options.headers ||= {});
2334
2362
  for (const attr in headers) {
2335
2363
  const name = attr.toLowerCase();
2336
2364
  if (name === 'content-type' || name === 'content-length') {
2337
2365
  delete headers[attr];
2338
2366
  }
2339
2367
  }
2340
- if (parts || contentType === "multipart/form-data" || contentType === 'form-data') {
2368
+ if (!putting && (parts || contentType === "multipart/form-data" || contentType === 'form-data')) {
2341
2369
  let valid;
2342
2370
  if ((0, types_1.isArray)(parts)) {
2343
2371
  const write = combined.create();
@@ -2434,7 +2462,9 @@ class Request extends module_1 {
2434
2462
  }
2435
2463
  headers['content-length'] = Buffer.byteLength(data, (0, types_1.getEncoding)(dataEncoding)).toString();
2436
2464
  }
2437
- options.method = 'POST';
2465
+ if (!putting) {
2466
+ options.method = 'POST';
2467
+ }
2438
2468
  options.httpVersion = 1;
2439
2469
  options.postData = data;
2440
2470
  headers['content-type'] = contentType || "text/plain";
@@ -2474,7 +2504,7 @@ class Request extends module_1 {
2474
2504
  for (const callback of called) {
2475
2505
  try {
2476
2506
  if (callback(code, headers, url) === true) {
2477
- abortHeaders.call(this, href, request, options);
2507
+ abortHeaders.call(this, href, request, options, code);
2478
2508
  return false;
2479
2509
  }
2480
2510
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/request",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Request constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -17,11 +17,11 @@
17
17
  "squared-functions"
18
18
  ],
19
19
  "author": "An Pham <anpham6@gmail.com>",
20
- "license": "BSD 3-Clause",
20
+ "license": "BSD-3-Clause",
21
21
  "homepage": "https://github.com/anpham6/e-mc#readme",
22
22
  "dependencies": {
23
- "@e-mc/module": "0.10.2",
24
- "@e-mc/types": "0.10.2",
23
+ "@e-mc/module": "0.10.3",
24
+ "@e-mc/types": "0.10.3",
25
25
  "combined-stream": "^1.0.8",
26
26
  "js-yaml": "^4.1.0",
27
27
  "picomatch": "^4.0.2",
package/util.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import type { AuthValue } from '../types/lib/http';
2
- import type { HttpProxySettings } from '../types/lib/settings';
1
+ import type { AuthValue } from '@e-mc/types/lib/http';
2
+ import type { HttpProxySettings } from '@e-mc/types/lib/settings';
3
3
 
4
4
  import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http';
5
5
  import type { Readable, Writable } from 'stream';
6
6
 
7
7
  declare namespace util {
8
8
  function parseHeader<T = unknown>(headers: IncomingHttpHeaders, name: string): T | undefined;
9
+ function parseOutgoingHeaders(headers: OutgoingHttpHeaders | Headers | undefined): OutgoingHttpHeaders | undefined;
9
10
  function normalizeHeaders(headers: OutgoingHttpHeaders): OutgoingHttpHeaders;
10
11
  function getBasicAuth(auth: AuthValue): string;
11
12
  function getBasicAuth(username: unknown, password?: unknown): string;
package/util.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  exports.parseHeader = parseHeader;
3
+ exports.parseOutgoingHeaders = parseOutgoingHeaders;
3
4
  exports.normalizeHeaders = normalizeHeaders;
4
5
  exports.getBasicAuth = getBasicAuth;
5
6
  exports.hasBasicAuth = hasBasicAuth;
@@ -19,8 +20,8 @@ exports.cleanupStream = cleanupStream;
19
20
  const path = require("path");
20
21
  const fs = require("fs");
21
22
  const util = require("util");
22
- const module_1 = require("@e-mc/module");
23
23
  const types_1 = require("@e-mc/types");
24
+ const module_1 = require("@e-mc/module");
24
25
  const SUPPORTED_USVSTRING = (0, types_1.supported)(16, 8);
25
26
  const safeInt = (value) => value >= 0 ? Math.min(value, Number.MAX_SAFE_INTEGER) : NaN;
26
27
  function parseHeader(headers, name) {
@@ -40,6 +41,23 @@ function parseHeader(headers, name) {
40
41
  }
41
42
  }
42
43
  }
44
+ function parseOutgoingHeaders(headers) {
45
+ if (headers) {
46
+ if (globalThis.Headers && headers instanceof Headers) {
47
+ const result = {};
48
+ headers.forEach((value, key) => {
49
+ if (key === 'set-cookie') {
50
+ (result[key] ||= []).push(value);
51
+ }
52
+ else {
53
+ result[key] = value;
54
+ }
55
+ });
56
+ return result;
57
+ }
58
+ return headers;
59
+ }
60
+ }
43
61
  function normalizeHeaders(headers) {
44
62
  const result = Object.create(null);
45
63
  for (const name in headers) {
@@ -52,11 +70,11 @@ function normalizeHeaders(headers) {
52
70
  value = value.trim();
53
71
  break;
54
72
  default:
55
- if (Array.isArray(value)) {
56
- value = value.map(out => module_1.asString(out).trim());
57
- break;
73
+ if (!(0, types_1.isArray)(value)) {
74
+ continue;
58
75
  }
59
- continue;
76
+ value = value.map(out => module_1.asString(out).trim());
77
+ break;
60
78
  }
61
79
  if (value) {
62
80
  result[trimPath(name.trim().toLowerCase())] = value;