@whatwg-node/node-fetch 0.0.1-alpha-20230117084928-a052439 → 0.0.1-alpha-20230117102027-734f015

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/AbortSignal.d.ts CHANGED
@@ -6,4 +6,6 @@ export declare class PonyfillAbortSignal extends EventTarget implements AbortSig
6
6
  throwIfAborted(): void;
7
7
  get onabort(): ((this: AbortSignal, ev: Event) => any) | null;
8
8
  set onabort(value: ((this: AbortSignal, ev: Event) => any) | null);
9
+ abort(reason?: any): void;
10
+ static timeout(milliseconds: number): PonyfillAbortSignal;
9
11
  }
package/index.js CHANGED
@@ -16,7 +16,11 @@ const fs = require('fs');
16
16
  // Will be removed after v14 reaches EOL
17
17
  class PonyfillAbortError extends Error {
18
18
  constructor(reason) {
19
- super('The operation was aborted.', {
19
+ let message = 'The operation was aborted.';
20
+ if (reason) {
21
+ message += ` reason: ${reason}`;
22
+ }
23
+ super(message, {
20
24
  cause: reason,
21
25
  });
22
26
  this.name = 'AbortError';
@@ -46,6 +50,15 @@ class PonyfillAbortSignal extends events.EventTarget {
46
50
  }
47
51
  this.addEventListener('abort', value);
48
52
  }
53
+ abort(reason) {
54
+ const abortEvent = new events.CustomEvent('abort', { detail: reason });
55
+ this.dispatchEvent(abortEvent);
56
+ }
57
+ static timeout(milliseconds) {
58
+ const signal = new PonyfillAbortSignal();
59
+ setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
60
+ return signal;
61
+ }
49
62
  }
50
63
 
51
64
  // Will be removed after v14 reaches EOL
@@ -54,7 +67,7 @@ class PonyfillAbortController {
54
67
  this.signal = new PonyfillAbortSignal();
55
68
  }
56
69
  abort(reason) {
57
- this.signal.dispatchEvent(new events.CustomEvent('abort', { detail: reason }));
70
+ this.signal.abort(reason);
58
71
  }
59
72
  }
60
73
 
@@ -303,6 +316,10 @@ class PonyfillFormData {
303
316
  controller.enqueue(Buffer.from(`\r\n--${boundary}\r\n`));
304
317
  }
305
318
  }
319
+ else {
320
+ controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
321
+ controller.close();
322
+ }
306
323
  },
307
324
  });
308
325
  }
@@ -540,6 +557,39 @@ function processBodyInit(bodyInit) {
540
557
  body,
541
558
  };
542
559
  }
560
+ if ('stream' in bodyInit) {
561
+ const bodyStream = bodyInit.stream();
562
+ const body = new PonyfillReadableStream(bodyStream);
563
+ return {
564
+ contentType: bodyInit.type,
565
+ contentLength: bodyInit.size,
566
+ body,
567
+ };
568
+ }
569
+ if (bodyInit instanceof URLSearchParams) {
570
+ const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
571
+ const body = new PonyfillReadableStream(stream.Readable.from(bodyInit.toString()));
572
+ return {
573
+ bodyType: BodyInitType.String,
574
+ contentType,
575
+ contentLength: null,
576
+ body,
577
+ };
578
+ }
579
+ if ('forEach' in bodyInit) {
580
+ const formData = new PonyfillFormData();
581
+ bodyInit.forEach((value, key) => {
582
+ formData.append(key, value);
583
+ });
584
+ const boundary = Math.random().toString(36).substr(2);
585
+ const contentType = `multipart/form-data; boundary=${boundary}`;
586
+ const body = formData.stream(boundary);
587
+ return {
588
+ contentType,
589
+ contentLength: null,
590
+ body,
591
+ };
592
+ }
543
593
  throw new Error('Unknown body type');
544
594
  }
545
595
 
@@ -620,6 +670,7 @@ function isRequest(input) {
620
670
  }
621
671
  class PonyfillRequest extends PonyfillBody {
622
672
  constructor(input, options) {
673
+ var _a;
623
674
  let url;
624
675
  let bodyInit = null;
625
676
  let requestInit;
@@ -646,7 +697,7 @@ class PonyfillRequest extends PonyfillBody {
646
697
  this.headers = new PonyfillHeaders(requestInit === null || requestInit === void 0 ? void 0 : requestInit.headers);
647
698
  this.integrity = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.integrity) || '';
648
699
  this.keepalive = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive) || true;
649
- this.method = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) || 'GET';
700
+ this.method = ((_a = requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'GET';
650
701
  this.mode = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.mode) || 'cors';
651
702
  this.redirect = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.redirect) || 'follow';
652
703
  this.referrer = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrer) || 'about:client';
@@ -752,13 +803,14 @@ function getResponseForFile(url$1) {
752
803
  }
753
804
  function getRequestFnForProtocol(protocol) {
754
805
  switch (protocol) {
755
- case 'http':
806
+ case 'http:':
756
807
  return http.request;
757
- case 'https':
808
+ case 'https:':
758
809
  return https.request;
759
810
  }
760
811
  throw new Error(`Unsupported protocol: ${protocol}`);
761
812
  }
813
+ const BASE64_SUFFIX = ';base64';
762
814
  function fetchPonyfill(info, init) {
763
815
  if (typeof info === 'string' || info instanceof URL) {
764
816
  const ponyfillRequest = new PonyfillRequest(info, init);
@@ -767,13 +819,39 @@ function fetchPonyfill(info, init) {
767
819
  const fetchRequest = info;
768
820
  return new Promise((resolve, reject) => {
769
821
  try {
770
- const protocol = fetchRequest.url.split('://')[0];
771
- if (protocol === 'file') {
772
- const response = getResponseForFile(fetchRequest.url);
822
+ const url = new URL(fetchRequest.url, 'http://localhost');
823
+ if (url.protocol === 'data:') {
824
+ const [mimeType = 'text/plain', ...datas] = url.pathname.split(',');
825
+ const data = decodeURIComponent(datas.join(','));
826
+ if (mimeType.endsWith(BASE64_SUFFIX)) {
827
+ const buffer = Buffer.from(data, 'base64');
828
+ const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
829
+ const response = new PonyfillResponse(buffer, {
830
+ status: 200,
831
+ statusText: 'OK',
832
+ headers: {
833
+ 'content-type': realMimeType,
834
+ },
835
+ });
836
+ resolve(response);
837
+ return;
838
+ }
839
+ const response = new PonyfillResponse(data, {
840
+ status: 200,
841
+ statusText: 'OK',
842
+ headers: {
843
+ 'content-type': mimeType,
844
+ },
845
+ });
846
+ resolve(response);
847
+ return;
848
+ }
849
+ if (url.protocol === 'file:') {
850
+ const response = getResponseForFile(url);
773
851
  resolve(response);
774
852
  return;
775
853
  }
776
- const requestFn = getRequestFnForProtocol(protocol);
854
+ const requestFn = getRequestFnForProtocol(url.protocol);
777
855
  const nodeReadable = (fetchRequest.body != null
778
856
  ? 'pipe' in fetchRequest.body
779
857
  ? fetchRequest.body
@@ -782,10 +860,11 @@ function fetchPonyfill(info, init) {
782
860
  const nodeHeaders = getHeadersObj(fetchRequest.headers);
783
861
  const abortListener = function abortListener(event) {
784
862
  nodeRequest.destroy();
785
- reject(new PonyfillAbortError(event.detail));
863
+ const reason = event.detail;
864
+ reject(new PonyfillAbortError(reason));
786
865
  };
787
866
  fetchRequest.signal.addEventListener('abort', abortListener);
788
- const nodeRequest = requestFn(fetchRequest.url, {
867
+ const nodeRequest = requestFn(url, {
789
868
  // signal: fetchRequest.signal will be added when v14 reaches EOL
790
869
  method: fetchRequest.method,
791
870
  headers: nodeHeaders,
@@ -799,7 +878,7 @@ function fetchPonyfill(info, init) {
799
878
  return;
800
879
  }
801
880
  if (fetchRequest.redirect === 'follow') {
802
- const redirectedUrl = new URL(nodeResponse.headers.location, fetchRequest.url);
881
+ const redirectedUrl = new URL(nodeResponse.headers.location, url);
803
882
  const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
804
883
  resolve(redirectResponse$.then(redirectResponse => {
805
884
  redirectResponse.redirected = true;
package/index.mjs CHANGED
@@ -10,7 +10,11 @@ import { createReadStream } from 'fs';
10
10
  // Will be removed after v14 reaches EOL
11
11
  class PonyfillAbortError extends Error {
12
12
  constructor(reason) {
13
- super('The operation was aborted.', {
13
+ let message = 'The operation was aborted.';
14
+ if (reason) {
15
+ message += ` reason: ${reason}`;
16
+ }
17
+ super(message, {
14
18
  cause: reason,
15
19
  });
16
20
  this.name = 'AbortError';
@@ -40,6 +44,15 @@ class PonyfillAbortSignal extends EventTarget {
40
44
  }
41
45
  this.addEventListener('abort', value);
42
46
  }
47
+ abort(reason) {
48
+ const abortEvent = new CustomEvent('abort', { detail: reason });
49
+ this.dispatchEvent(abortEvent);
50
+ }
51
+ static timeout(milliseconds) {
52
+ const signal = new PonyfillAbortSignal();
53
+ setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
54
+ return signal;
55
+ }
43
56
  }
44
57
 
45
58
  // Will be removed after v14 reaches EOL
@@ -48,7 +61,7 @@ class PonyfillAbortController {
48
61
  this.signal = new PonyfillAbortSignal();
49
62
  }
50
63
  abort(reason) {
51
- this.signal.dispatchEvent(new CustomEvent('abort', { detail: reason }));
64
+ this.signal.abort(reason);
52
65
  }
53
66
  }
54
67
 
@@ -297,6 +310,10 @@ class PonyfillFormData {
297
310
  controller.enqueue(Buffer.from(`\r\n--${boundary}\r\n`));
298
311
  }
299
312
  }
313
+ else {
314
+ controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
315
+ controller.close();
316
+ }
300
317
  },
301
318
  });
302
319
  }
@@ -534,6 +551,39 @@ function processBodyInit(bodyInit) {
534
551
  body,
535
552
  };
536
553
  }
554
+ if ('stream' in bodyInit) {
555
+ const bodyStream = bodyInit.stream();
556
+ const body = new PonyfillReadableStream(bodyStream);
557
+ return {
558
+ contentType: bodyInit.type,
559
+ contentLength: bodyInit.size,
560
+ body,
561
+ };
562
+ }
563
+ if (bodyInit instanceof URLSearchParams) {
564
+ const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
565
+ const body = new PonyfillReadableStream(Readable.from(bodyInit.toString()));
566
+ return {
567
+ bodyType: BodyInitType.String,
568
+ contentType,
569
+ contentLength: null,
570
+ body,
571
+ };
572
+ }
573
+ if ('forEach' in bodyInit) {
574
+ const formData = new PonyfillFormData();
575
+ bodyInit.forEach((value, key) => {
576
+ formData.append(key, value);
577
+ });
578
+ const boundary = Math.random().toString(36).substr(2);
579
+ const contentType = `multipart/form-data; boundary=${boundary}`;
580
+ const body = formData.stream(boundary);
581
+ return {
582
+ contentType,
583
+ contentLength: null,
584
+ body,
585
+ };
586
+ }
537
587
  throw new Error('Unknown body type');
538
588
  }
539
589
 
@@ -614,6 +664,7 @@ function isRequest(input) {
614
664
  }
615
665
  class PonyfillRequest extends PonyfillBody {
616
666
  constructor(input, options) {
667
+ var _a;
617
668
  let url;
618
669
  let bodyInit = null;
619
670
  let requestInit;
@@ -640,7 +691,7 @@ class PonyfillRequest extends PonyfillBody {
640
691
  this.headers = new PonyfillHeaders(requestInit === null || requestInit === void 0 ? void 0 : requestInit.headers);
641
692
  this.integrity = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.integrity) || '';
642
693
  this.keepalive = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive) || true;
643
- this.method = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) || 'GET';
694
+ this.method = ((_a = requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'GET';
644
695
  this.mode = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.mode) || 'cors';
645
696
  this.redirect = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.redirect) || 'follow';
646
697
  this.referrer = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrer) || 'about:client';
@@ -746,13 +797,14 @@ function getResponseForFile(url) {
746
797
  }
747
798
  function getRequestFnForProtocol(protocol) {
748
799
  switch (protocol) {
749
- case 'http':
800
+ case 'http:':
750
801
  return request$1;
751
- case 'https':
802
+ case 'https:':
752
803
  return request;
753
804
  }
754
805
  throw new Error(`Unsupported protocol: ${protocol}`);
755
806
  }
807
+ const BASE64_SUFFIX = ';base64';
756
808
  function fetchPonyfill(info, init) {
757
809
  if (typeof info === 'string' || info instanceof URL) {
758
810
  const ponyfillRequest = new PonyfillRequest(info, init);
@@ -761,13 +813,39 @@ function fetchPonyfill(info, init) {
761
813
  const fetchRequest = info;
762
814
  return new Promise((resolve, reject) => {
763
815
  try {
764
- const protocol = fetchRequest.url.split('://')[0];
765
- if (protocol === 'file') {
766
- const response = getResponseForFile(fetchRequest.url);
816
+ const url = new URL(fetchRequest.url, 'http://localhost');
817
+ if (url.protocol === 'data:') {
818
+ const [mimeType = 'text/plain', ...datas] = url.pathname.split(',');
819
+ const data = decodeURIComponent(datas.join(','));
820
+ if (mimeType.endsWith(BASE64_SUFFIX)) {
821
+ const buffer = Buffer.from(data, 'base64');
822
+ const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
823
+ const response = new PonyfillResponse(buffer, {
824
+ status: 200,
825
+ statusText: 'OK',
826
+ headers: {
827
+ 'content-type': realMimeType,
828
+ },
829
+ });
830
+ resolve(response);
831
+ return;
832
+ }
833
+ const response = new PonyfillResponse(data, {
834
+ status: 200,
835
+ statusText: 'OK',
836
+ headers: {
837
+ 'content-type': mimeType,
838
+ },
839
+ });
840
+ resolve(response);
841
+ return;
842
+ }
843
+ if (url.protocol === 'file:') {
844
+ const response = getResponseForFile(url);
767
845
  resolve(response);
768
846
  return;
769
847
  }
770
- const requestFn = getRequestFnForProtocol(protocol);
848
+ const requestFn = getRequestFnForProtocol(url.protocol);
771
849
  const nodeReadable = (fetchRequest.body != null
772
850
  ? 'pipe' in fetchRequest.body
773
851
  ? fetchRequest.body
@@ -776,10 +854,11 @@ function fetchPonyfill(info, init) {
776
854
  const nodeHeaders = getHeadersObj(fetchRequest.headers);
777
855
  const abortListener = function abortListener(event) {
778
856
  nodeRequest.destroy();
779
- reject(new PonyfillAbortError(event.detail));
857
+ const reason = event.detail;
858
+ reject(new PonyfillAbortError(reason));
780
859
  };
781
860
  fetchRequest.signal.addEventListener('abort', abortListener);
782
- const nodeRequest = requestFn(fetchRequest.url, {
861
+ const nodeRequest = requestFn(url, {
783
862
  // signal: fetchRequest.signal will be added when v14 reaches EOL
784
863
  method: fetchRequest.method,
785
864
  headers: nodeHeaders,
@@ -793,7 +872,7 @@ function fetchPonyfill(info, init) {
793
872
  return;
794
873
  }
795
874
  if (fetchRequest.redirect === 'follow') {
796
- const redirectedUrl = new URL(nodeResponse.headers.location, fetchRequest.url);
875
+ const redirectedUrl = new URL(nodeResponse.headers.location, url);
797
876
  const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
798
877
  resolve(redirectResponse$.then(redirectResponse => {
799
878
  redirectResponse.redirected = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/node-fetch",
3
- "version": "0.0.1-alpha-20230117084928-a052439",
3
+ "version": "0.0.1-alpha-20230117102027-734f015",
4
4
  "description": "Fetch API implementation for Node",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {