@e-mc/request 0.10.2 → 0.10.4

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.4/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.4/lib/http.d.ts
209
+ - https://www.unpkg.com/@e-mc/types@0.10.4/lib/request.d.ts
210
+ - https://www.unpkg.com/@e-mc/types@0.10.4/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,15 +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
- this.cleanup();
423
- this.aborted = false;
424
- }
422
+ this.aborted = false;
425
423
  this.setWriteStream();
426
424
  const config = this.config;
427
425
  const client = this.instance.open(this.uri, config);
@@ -445,7 +443,7 @@ class Fetch {
445
443
  statusCode === 404 ||
446
444
  statusCode === 407 ||
447
445
  statusCode === 410) {
448
- this.rejectError(this.formatStatus(statusCode));
446
+ this.terminate(this.formatStatus(statusCode));
449
447
  }
450
448
  else if (this.isRetry(statusCode)) {
451
449
  this.retryResponse(statusCode, headers['retry-after']);
@@ -473,7 +471,7 @@ class Fetch {
473
471
  })
474
472
  .on('aborted', () => {
475
473
  this.aborted = true;
476
- this.rejectError((0, types_1.createAbortError)());
474
+ this.terminate((0, types_1.createAbortError)());
477
475
  })
478
476
  .on('error', async (err) => {
479
477
  if (this.aborted) {
@@ -514,13 +512,12 @@ class Fetch {
514
512
  this.retryResponse(statusCode, res.headers['retry-after']);
515
513
  }
516
514
  else {
517
- this.abortResponse();
518
- this.rejectError(this.formatStatus(statusCode));
515
+ this.terminate(this.formatStatus(statusCode));
519
516
  }
520
517
  })
521
518
  .on('abort', () => {
522
519
  this.aborted = true;
523
- this.rejectError((0, types_1.createAbortError)());
520
+ this.terminate((0, types_1.createAbortError)());
524
521
  })
525
522
  .on('error', err => {
526
523
  if (!this.aborted) {
@@ -532,12 +529,12 @@ class Fetch {
532
529
  if (this.aborted) {
533
530
  return;
534
531
  }
535
- this.abortResponse();
536
532
  if (++this.retries <= this.retryLimit) {
533
+ this.abortResponse();
537
534
  this.retryTimeout();
538
535
  }
539
536
  else {
540
- this.rejectError(this.formatStatus(408));
537
+ this.terminate(this.formatStatus(408));
541
538
  }
542
539
  });
543
540
  }
@@ -553,7 +550,7 @@ class Fetch {
553
550
  this.config.outStream = this.outStream;
554
551
  }
555
552
  catch (err) {
556
- this.rejectError(err);
553
+ this.terminate(err);
557
554
  }
558
555
  }
559
556
  else {
@@ -568,13 +565,8 @@ class Fetch {
568
565
  clearTimeout(this.timeout);
569
566
  }
570
567
  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
568
  this.client.destroy();
569
+ this.cleanup();
578
570
  }
579
571
  retryDownload(downgrade, message) {
580
572
  if (this.aborted) {
@@ -613,8 +605,7 @@ class Fetch {
613
605
  client.once('readable', () => {
614
606
  if (instance.readTimeout > 0) {
615
607
  this.timeout = setTimeout(() => {
616
- this.abortResponse();
617
- this.rejectError((0, types_1.errorValue)("Timeout was exceeded", this.uri.toString()));
608
+ this.terminate((0, types_1.errorValue)("Timeout was exceeded", this.uri.toString()));
618
609
  }, instance.readTimeout);
619
610
  }
620
611
  if (log) {
@@ -664,8 +655,7 @@ class Fetch {
664
655
  dataLength += Buffer.byteLength(chunk, encoding);
665
656
  }
666
657
  if (dataLength > maxBufferSize) {
667
- this.abortResponse();
668
- this.rejectError((0, types_1.errorValue)("Size limit was exceeded", this.uri.toString()));
658
+ this.terminate((0, types_1.errorValue)("Size limit was exceeded", this.uri.toString()));
669
659
  }
670
660
  }
671
661
  });
@@ -674,13 +664,7 @@ class Fetch {
674
664
  if (this.closed || this.aborted) {
675
665
  return;
676
666
  }
677
- if (this.timeout) {
678
- clearTimeout(this.timeout);
679
- }
680
- if (this.outAbort) {
681
- this.downloading.delete(this.outAbort);
682
- }
683
- this.closed = true;
667
+ this.close();
684
668
  const encoding = opts.encoding;
685
669
  let result, messageUnit, titleBgColor;
686
670
  if (buffer) {
@@ -743,7 +727,7 @@ class Fetch {
743
727
  parent.updateProgress("request", progressId, 0, contentLength);
744
728
  }
745
729
  if (enabled && instance.readExpect === 'always') {
746
- this.rejectError("No data received");
730
+ this.terminate("No data received");
747
731
  return;
748
732
  }
749
733
  result = encoding && !pipeline ? '' : null;
@@ -752,34 +736,34 @@ class Fetch {
752
736
  if (log) {
753
737
  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
738
  }
755
- this.promise[0](result);
739
+ this.resolve(result);
756
740
  });
757
741
  config.host.success(this.httpVersion);
758
742
  }
759
743
  redirectResponse(statusCode, location) {
760
- this.abortResponse();
761
744
  if (location) {
762
745
  if (this.config.follow_redirect === false || this.config.followRedirect === false) {
763
- this.rejectError(this.formatStatus(statusCode, "Follow redirect was disabled"));
746
+ this.terminate(this.formatStatus(statusCode, "Follow redirect was disabled"));
764
747
  }
765
748
  else if (++this.redirects <= this.redirectLimit) {
749
+ this.abortResponse();
766
750
  this.setConfig(Request.fromURL(this.config.url, location));
767
751
  this.init();
768
752
  }
769
753
  else {
770
- this.rejectError(this.formatStatus(statusCode, "Exceeded redirect limit"));
754
+ this.terminate(this.formatStatus(statusCode, "Exceeded redirect limit"));
771
755
  }
772
756
  }
773
757
  else {
774
- this.rejectError(this.formatStatus(statusCode, "Missing redirect location"));
758
+ this.terminate(this.formatStatus(statusCode, "Missing redirect location"));
775
759
  }
776
760
  }
777
761
  errorResponse(err) {
778
- this.abortResponse();
779
762
  if (Fetch.wasAborted(err)) {
780
- this.rejectError(err);
763
+ this.terminate(err);
781
764
  }
782
765
  else if ((0, util_1.checkRetryable)(err) && ++this.retries <= this.retryLimit) {
766
+ this.abortResponse();
783
767
  if (Fetch.isConnectionTimeout(err)) {
784
768
  this.retryTimeout();
785
769
  }
@@ -791,7 +775,7 @@ class Fetch {
791
775
  }
792
776
  else {
793
777
  this.config.host.error(this.httpVersion);
794
- this.rejectError(err);
778
+ this.terminate(err);
795
779
  }
796
780
  }
797
781
  retryResponse(statusCode, retryAfter) {
@@ -812,7 +796,7 @@ class Fetch {
812
796
  }, offset);
813
797
  }
814
798
  else {
815
- this.rejectError(this.formatStatus(statusCode));
799
+ this.terminate(this.formatStatus(statusCode));
816
800
  }
817
801
  return;
818
802
  }
@@ -834,17 +818,14 @@ class Fetch {
834
818
  this.sendWarning(this.formatRetry("HTTP connection timeout"));
835
819
  this.init();
836
820
  }
837
- rejectError(err) {
821
+ terminate(err) {
838
822
  if (this.timeout) {
839
823
  clearTimeout(this.timeout);
840
824
  }
841
825
  if (!this.closed) {
842
- this.closed = true;
843
826
  this.cleanup();
844
- this.promise[1](typeof err === 'string' ? new Error(err) : err);
845
- }
846
- if (this.outAbort) {
847
- this.downloading.delete(this.outAbort);
827
+ this.close();
828
+ this.reject(typeof err === 'string' ? new Error(err) : err);
848
829
  }
849
830
  }
850
831
  sendWarning(message) {
@@ -862,7 +843,20 @@ class Fetch {
862
843
  formatRetry(message) {
863
844
  return message + ` (${this.retries} / ${this.retryLimit})`;
864
845
  }
846
+ close() {
847
+ if (this.timeout) {
848
+ clearTimeout(this.timeout);
849
+ }
850
+ this.closed = true;
851
+ if (this.aborted && !this.client.aborted && !this.client.destroyed) {
852
+ this.opts.outAbort?.abort();
853
+ }
854
+ }
865
855
  cleanup() {
856
+ const outAbort = this.opts.outAbort;
857
+ if (outAbort) {
858
+ this.downloading.delete(outAbort);
859
+ }
866
860
  if ((0, types_1.isString)(this.pipeTo) && this.outStream) {
867
861
  (0, util_1.cleanupStream)(this.outStream, this.pipeTo);
868
862
  }
@@ -1611,13 +1605,14 @@ class Request extends module_1 {
1611
1605
  if (typeof uri === 'string' && module_1.isURL(uri)) {
1612
1606
  uri = new URL(uri);
1613
1607
  }
1614
- let pathname, headers, binOpts, silent;
1608
+ let pathname, headers, binOpts, signal, silent;
1615
1609
  if (options) {
1616
1610
  if (typeof options === 'string') {
1617
1611
  pathname = options;
1618
1612
  }
1619
1613
  else {
1620
- ({ pathname, headers, binOpts, silent } = options);
1614
+ ({ pathname, binOpts, signal, silent } = options);
1615
+ headers = (0, util_1.parseOutgoingHeaders)(options.headers);
1621
1616
  if ((0, types_1.isArray)(binOpts)) {
1622
1617
  let next = false;
1623
1618
  binOpts = binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt.trim()))).map((opt) => {
@@ -1920,7 +1915,13 @@ class Request extends module_1 {
1920
1915
  }
1921
1916
  for (const item of ARIA2.PID_QUEUE) {
1922
1917
  try {
1923
- process.kill(item[0], 0);
1918
+ if (pid === item[0] && signal?.aborted) {
1919
+ process.kill(item[0]);
1920
+ closeTorrent(item[0]);
1921
+ }
1922
+ else {
1923
+ process.kill(item[0], 0);
1924
+ }
1924
1925
  }
1925
1926
  catch {
1926
1927
  closeTorrent(item[0]);
@@ -1982,9 +1983,17 @@ class Request extends module_1 {
1982
1983
  return { ...options, host, url };
1983
1984
  }
1984
1985
  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';
1986
+ 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;
1987
+ switch (method = method.toUpperCase()) {
1988
+ case 'GET':
1989
+ case 'DELETE':
1990
+ getting = true;
1991
+ break;
1992
+ case 'POST':
1993
+ case 'PUT':
1994
+ posting = true;
1995
+ break;
1996
+ }
1988
1997
  if (format) {
1989
1998
  let parser;
1990
1999
  if ((0, types_1.isObject)(format)) {
@@ -2053,12 +2062,12 @@ class Request extends module_1 {
2053
2062
  }
2054
2063
  uri = url.href;
2055
2064
  }
2056
- const { hostname, origin, secure, localhost } = host;
2065
+ const { hostname, origin, secure } = host;
2057
2066
  const pathname = url.pathname + (socketPath ? '' : url.search);
2058
- const proxy = this.proxyOf(uri, localhost);
2067
+ const proxy = this.proxyOf(uri, host.localhost);
2059
2068
  const version = this.httpVersion;
2060
2069
  let request, ca, cert, key, ciphers, minVersion, baseHeaders = this.headersOf(uri);
2061
- if (getting && this.acceptEncoding && !localhost && !baseHeaders?.['accept-encoding']) {
2070
+ if (getting && this.acceptEncoding && !host.localhost && !baseHeaders?.['accept-encoding']) {
2062
2071
  (headers ||= {})['accept-encoding'] ||= 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : '');
2063
2072
  }
2064
2073
  if (secure) {
@@ -2068,7 +2077,7 @@ class Request extends module_1 {
2068
2077
  }
2069
2078
  }
2070
2079
  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 });
2080
+ 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
2081
  if (getting) {
2073
2082
  const listenerMap = {};
2074
2083
  const onEvent = request.on.bind(request);
@@ -2279,6 +2288,9 @@ class Request extends module_1 {
2279
2288
  const ac = new AbortController();
2280
2289
  this[kDownloading].add(options.outAbort = ac);
2281
2290
  stream.addAbortSignal(ac.signal, request);
2291
+ if (options.signal) {
2292
+ stream.addAbortSignal(options.signal, request);
2293
+ }
2282
2294
  this.signal.addEventListener('abort', () => {
2283
2295
  ac.abort(new Error("Aborted by process"));
2284
2296
  }, { once: true });
@@ -2300,8 +2312,21 @@ class Request extends module_1 {
2300
2312
  out.httpVersion = 1;
2301
2313
  return this.open(out.url, out);
2302
2314
  }
2315
+ async put(uri, data, contentType, options) {
2316
+ if ((0, types_1.isPlainObject)(contentType)) {
2317
+ options = contentType;
2318
+ }
2319
+ else {
2320
+ (options ||= {}).contentType = contentType;
2321
+ }
2322
+ options.method = 'PUT';
2323
+ if (options.contentType === "multipart/form-data") {
2324
+ options.contentType = "application/x-www-form-urlencoded";
2325
+ }
2326
+ return this.post(uri, data, options);
2327
+ }
2303
2328
  async post(uri, data, contentType, options) {
2304
- let parts;
2329
+ let putting = false, parts;
2305
2330
  if (Array.isArray(contentType)) {
2306
2331
  parts = contentType;
2307
2332
  contentType = undefined;
@@ -2309,9 +2334,10 @@ class Request extends module_1 {
2309
2334
  else {
2310
2335
  if ((0, types_1.isPlainObject)(contentType)) {
2311
2336
  options = contentType;
2337
+ putting = options.method === 'PUT';
2312
2338
  contentType = undefined;
2313
2339
  }
2314
- if (Array.isArray(data) && (!contentType || contentType === "multipart/form-data")) {
2340
+ if (!putting && Array.isArray(data) && (!contentType || contentType === "multipart/form-data")) {
2315
2341
  parts = data;
2316
2342
  data = undefined;
2317
2343
  }
@@ -2320,7 +2346,7 @@ class Request extends module_1 {
2320
2346
  if ((0, types_1.isPlainObject)(options)) {
2321
2347
  let formData;
2322
2348
  ({ formData, dataEncoding } = options);
2323
- if (formData) {
2349
+ if (!putting && formData) {
2324
2350
  (parts ||= []).push(...Array.isArray(formData) ? formData : [formData]);
2325
2351
  }
2326
2352
  else {
@@ -2330,14 +2356,14 @@ class Request extends module_1 {
2330
2356
  else {
2331
2357
  options = {};
2332
2358
  }
2333
- const headers = options.headers ||= {};
2359
+ const headers = (0, util_1.parseOutgoingHeaders)(options.headers ||= {});
2334
2360
  for (const attr in headers) {
2335
2361
  const name = attr.toLowerCase();
2336
2362
  if (name === 'content-type' || name === 'content-length') {
2337
2363
  delete headers[attr];
2338
2364
  }
2339
2365
  }
2340
- if (parts || contentType === "multipart/form-data" || contentType === 'form-data') {
2366
+ if (!putting && (parts || contentType === "multipart/form-data" || contentType === 'form-data')) {
2341
2367
  let valid;
2342
2368
  if ((0, types_1.isArray)(parts)) {
2343
2369
  const write = combined.create();
@@ -2434,7 +2460,9 @@ class Request extends module_1 {
2434
2460
  }
2435
2461
  headers['content-length'] = Buffer.byteLength(data, (0, types_1.getEncoding)(dataEncoding)).toString();
2436
2462
  }
2437
- options.method = 'POST';
2463
+ if (!putting) {
2464
+ options.method = 'POST';
2465
+ }
2438
2466
  options.httpVersion = 1;
2439
2467
  options.postData = data;
2440
2468
  headers['content-type'] = contentType || "text/plain";
@@ -2474,7 +2502,7 @@ class Request extends module_1 {
2474
2502
  for (const callback of called) {
2475
2503
  try {
2476
2504
  if (callback(code, headers, url) === true) {
2477
- abortHeaders.call(this, href, request, options);
2505
+ abortHeaders.call(this, href, request, options, code);
2478
2506
  return false;
2479
2507
  }
2480
2508
  }
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.4",
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.4",
24
+ "@e-mc/types": "0.10.4",
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;