@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 +2 -0
- package/index.js +91 -12
- package/index.mjs +91 -12
- package/package.json +1 -1
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
|
-
|
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.
|
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
|
771
|
-
if (protocol === '
|
772
|
-
const
|
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
|
-
|
863
|
+
const reason = event.detail;
|
864
|
+
reject(new PonyfillAbortError(reason));
|
786
865
|
};
|
787
866
|
fetchRequest.signal.addEventListener('abort', abortListener);
|
788
|
-
const nodeRequest = requestFn(
|
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,
|
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
|
-
|
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.
|
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
|
765
|
-
if (protocol === '
|
766
|
-
const
|
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
|
-
|
857
|
+
const reason = event.detail;
|
858
|
+
reject(new PonyfillAbortError(reason));
|
780
859
|
};
|
781
860
|
fetchRequest.signal.addEventListener('abort', abortListener);
|
782
|
-
const nodeRequest = requestFn(
|
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,
|
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