@whatwg-node/node-fetch 0.0.1-alpha-20230117081522-969e299 → 0.0.1-alpha-20230117095738-14df726
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 +94 -17
- package/index.mjs +96 -19
- package/package.json +1 -2
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
@@ -10,14 +10,13 @@ const events = require('@whatwg-node/events');
|
|
10
10
|
const buffer = require('buffer');
|
11
11
|
const stream = require('stream');
|
12
12
|
const busboy = _interopDefault(require('busboy'));
|
13
|
-
const headerCase = require('header-case');
|
14
13
|
const url = require('url');
|
15
14
|
const fs = require('fs');
|
16
15
|
|
17
16
|
// Will be removed after v14 reaches EOL
|
18
17
|
class PonyfillAbortError extends Error {
|
19
18
|
constructor(reason) {
|
20
|
-
super('The operation was aborted
|
19
|
+
super('The operation was aborted' + reason || '', {
|
21
20
|
cause: reason,
|
22
21
|
});
|
23
22
|
this.name = 'AbortError';
|
@@ -47,6 +46,14 @@ class PonyfillAbortSignal extends events.EventTarget {
|
|
47
46
|
}
|
48
47
|
this.addEventListener('abort', value);
|
49
48
|
}
|
49
|
+
abort(reason) {
|
50
|
+
this.dispatchEvent(new CustomEvent('abort', { detail: reason }));
|
51
|
+
}
|
52
|
+
static timeout(milliseconds) {
|
53
|
+
const signal = new PonyfillAbortSignal();
|
54
|
+
setTimeout(() => signal.abort(`Operation timed out`), milliseconds);
|
55
|
+
return signal;
|
56
|
+
}
|
50
57
|
}
|
51
58
|
|
52
59
|
// Will be removed after v14 reaches EOL
|
@@ -304,6 +311,10 @@ class PonyfillFormData {
|
|
304
311
|
controller.enqueue(Buffer.from(`\r\n--${boundary}\r\n`));
|
305
312
|
}
|
306
313
|
}
|
314
|
+
else {
|
315
|
+
controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
|
316
|
+
controller.close();
|
317
|
+
}
|
307
318
|
},
|
308
319
|
});
|
309
320
|
}
|
@@ -541,6 +552,39 @@ function processBodyInit(bodyInit) {
|
|
541
552
|
body,
|
542
553
|
};
|
543
554
|
}
|
555
|
+
if ('stream' in bodyInit) {
|
556
|
+
const bodyStream = bodyInit.stream();
|
557
|
+
const body = new PonyfillReadableStream(bodyStream);
|
558
|
+
return {
|
559
|
+
contentType: bodyInit.type,
|
560
|
+
contentLength: bodyInit.size,
|
561
|
+
body,
|
562
|
+
};
|
563
|
+
}
|
564
|
+
if (bodyInit instanceof URLSearchParams) {
|
565
|
+
const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
|
566
|
+
const body = new PonyfillReadableStream(stream.Readable.from(bodyInit.toString()));
|
567
|
+
return {
|
568
|
+
bodyType: BodyInitType.String,
|
569
|
+
contentType,
|
570
|
+
contentLength: null,
|
571
|
+
body,
|
572
|
+
};
|
573
|
+
}
|
574
|
+
if ('forEach' in bodyInit) {
|
575
|
+
const formData = new PonyfillFormData();
|
576
|
+
bodyInit.forEach((value, key) => {
|
577
|
+
formData.append(key, value);
|
578
|
+
});
|
579
|
+
const boundary = Math.random().toString(36).substr(2);
|
580
|
+
const contentType = `multipart/form-data; boundary=${boundary}`;
|
581
|
+
const body = formData.stream(boundary);
|
582
|
+
return {
|
583
|
+
contentType,
|
584
|
+
contentLength: null,
|
585
|
+
body,
|
586
|
+
};
|
587
|
+
}
|
544
588
|
throw new Error('Unknown body type');
|
545
589
|
}
|
546
590
|
|
@@ -581,26 +625,26 @@ class PonyfillHeaders {
|
|
581
625
|
}
|
582
626
|
}
|
583
627
|
append(name, value) {
|
584
|
-
const key =
|
628
|
+
const key = name.toLowerCase();
|
585
629
|
if (this.map.has(key)) {
|
586
630
|
value = this.map.get(key) + ', ' + value;
|
587
631
|
}
|
588
632
|
this.map.set(key, value);
|
589
633
|
}
|
590
634
|
get(name) {
|
591
|
-
const key =
|
635
|
+
const key = name.toLowerCase();
|
592
636
|
return this.map.get(key) || null;
|
593
637
|
}
|
594
638
|
has(name) {
|
595
|
-
const key =
|
639
|
+
const key = name.toLowerCase();
|
596
640
|
return this.map.has(key);
|
597
641
|
}
|
598
642
|
set(name, value) {
|
599
|
-
const key =
|
643
|
+
const key = name.toLowerCase();
|
600
644
|
this.map.set(key, value);
|
601
645
|
}
|
602
646
|
delete(name) {
|
603
|
-
const key =
|
647
|
+
const key = name.toLowerCase();
|
604
648
|
this.map.delete(key);
|
605
649
|
}
|
606
650
|
forEach(callback) {
|
@@ -621,6 +665,7 @@ function isRequest(input) {
|
|
621
665
|
}
|
622
666
|
class PonyfillRequest extends PonyfillBody {
|
623
667
|
constructor(input, options) {
|
668
|
+
var _a;
|
624
669
|
let url;
|
625
670
|
let bodyInit = null;
|
626
671
|
let requestInit;
|
@@ -647,7 +692,7 @@ class PonyfillRequest extends PonyfillBody {
|
|
647
692
|
this.headers = new PonyfillHeaders(requestInit === null || requestInit === void 0 ? void 0 : requestInit.headers);
|
648
693
|
this.integrity = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.integrity) || '';
|
649
694
|
this.keepalive = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive) || true;
|
650
|
-
this.method = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) || 'GET';
|
695
|
+
this.method = ((_a = requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'GET';
|
651
696
|
this.mode = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.mode) || 'cors';
|
652
697
|
this.redirect = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.redirect) || 'follow';
|
653
698
|
this.referrer = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrer) || 'about:client';
|
@@ -753,9 +798,9 @@ function getResponseForFile(url$1) {
|
|
753
798
|
}
|
754
799
|
function getRequestFnForProtocol(protocol) {
|
755
800
|
switch (protocol) {
|
756
|
-
case 'http':
|
801
|
+
case 'http:':
|
757
802
|
return http.request;
|
758
|
-
case 'https':
|
803
|
+
case 'https:':
|
759
804
|
return https.request;
|
760
805
|
}
|
761
806
|
throw new Error(`Unsupported protocol: ${protocol}`);
|
@@ -768,13 +813,39 @@ function fetchPonyfill(info, init) {
|
|
768
813
|
const fetchRequest = info;
|
769
814
|
return new Promise((resolve, reject) => {
|
770
815
|
try {
|
771
|
-
const
|
772
|
-
if (protocol === '
|
773
|
-
const
|
816
|
+
const url = new URL(fetchRequest.url, 'http://localhost');
|
817
|
+
if (url.protocol === 'data:') {
|
818
|
+
const [mimeType = 'text/plain', base64FlagOrText, base64String] = url.pathname.split(',');
|
819
|
+
if (base64FlagOrText === 'base64' && base64String) {
|
820
|
+
const buffer = Buffer.from(base64String, 'base64');
|
821
|
+
const response = new PonyfillResponse(buffer, {
|
822
|
+
status: 200,
|
823
|
+
statusText: 'OK',
|
824
|
+
headers: {
|
825
|
+
'content-type': mimeType,
|
826
|
+
},
|
827
|
+
});
|
828
|
+
resolve(response);
|
829
|
+
return;
|
830
|
+
}
|
831
|
+
if (base64FlagOrText) {
|
832
|
+
const response = new PonyfillResponse(base64FlagOrText, {
|
833
|
+
status: 200,
|
834
|
+
statusText: 'OK',
|
835
|
+
headers: {
|
836
|
+
'content-type': mimeType,
|
837
|
+
},
|
838
|
+
});
|
839
|
+
resolve(response);
|
840
|
+
return;
|
841
|
+
}
|
842
|
+
}
|
843
|
+
if (url.protocol === 'file:') {
|
844
|
+
const response = getResponseForFile(url);
|
774
845
|
resolve(response);
|
775
846
|
return;
|
776
847
|
}
|
777
|
-
const requestFn = getRequestFnForProtocol(protocol);
|
848
|
+
const requestFn = getRequestFnForProtocol(url.protocol);
|
778
849
|
const nodeReadable = (fetchRequest.body != null
|
779
850
|
? 'pipe' in fetchRequest.body
|
780
851
|
? fetchRequest.body
|
@@ -783,10 +854,16 @@ function fetchPonyfill(info, init) {
|
|
783
854
|
const nodeHeaders = getHeadersObj(fetchRequest.headers);
|
784
855
|
const abortListener = function abortListener(event) {
|
785
856
|
nodeRequest.destroy();
|
786
|
-
|
857
|
+
const reason = event.detail;
|
858
|
+
if (reason instanceof Error) {
|
859
|
+
reject(reason);
|
860
|
+
}
|
861
|
+
else {
|
862
|
+
reject(new PonyfillAbortError(reason));
|
863
|
+
}
|
787
864
|
};
|
788
865
|
fetchRequest.signal.addEventListener('abort', abortListener);
|
789
|
-
const nodeRequest = requestFn(
|
866
|
+
const nodeRequest = requestFn(url, {
|
790
867
|
// signal: fetchRequest.signal will be added when v14 reaches EOL
|
791
868
|
method: fetchRequest.method,
|
792
869
|
headers: nodeHeaders,
|
@@ -800,7 +877,7 @@ function fetchPonyfill(info, init) {
|
|
800
877
|
return;
|
801
878
|
}
|
802
879
|
if (fetchRequest.redirect === 'follow') {
|
803
|
-
const redirectedUrl = new URL(nodeResponse.headers.location,
|
880
|
+
const redirectedUrl = new URL(nodeResponse.headers.location, url);
|
804
881
|
const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
|
805
882
|
resolve(redirectResponse$.then(redirectResponse => {
|
806
883
|
redirectResponse.redirected = true;
|
package/index.mjs
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
import { request as request$1 } from 'http';
|
2
2
|
import { request } from 'https';
|
3
|
-
import { EventTarget, CustomEvent } from '@whatwg-node/events';
|
3
|
+
import { EventTarget, CustomEvent as CustomEvent$1 } from '@whatwg-node/events';
|
4
4
|
import { Blob } from 'buffer';
|
5
5
|
import { Readable } from 'stream';
|
6
6
|
import busboy from 'busboy';
|
7
|
-
import { headerCase } from 'header-case';
|
8
7
|
import { fileURLToPath } from 'url';
|
9
8
|
import { createReadStream } from 'fs';
|
10
9
|
|
11
10
|
// Will be removed after v14 reaches EOL
|
12
11
|
class PonyfillAbortError extends Error {
|
13
12
|
constructor(reason) {
|
14
|
-
super('The operation was aborted
|
13
|
+
super('The operation was aborted' + reason || '', {
|
15
14
|
cause: reason,
|
16
15
|
});
|
17
16
|
this.name = 'AbortError';
|
@@ -41,6 +40,14 @@ class PonyfillAbortSignal extends EventTarget {
|
|
41
40
|
}
|
42
41
|
this.addEventListener('abort', value);
|
43
42
|
}
|
43
|
+
abort(reason) {
|
44
|
+
this.dispatchEvent(new CustomEvent('abort', { detail: reason }));
|
45
|
+
}
|
46
|
+
static timeout(milliseconds) {
|
47
|
+
const signal = new PonyfillAbortSignal();
|
48
|
+
setTimeout(() => signal.abort(`Operation timed out`), milliseconds);
|
49
|
+
return signal;
|
50
|
+
}
|
44
51
|
}
|
45
52
|
|
46
53
|
// Will be removed after v14 reaches EOL
|
@@ -49,7 +56,7 @@ class PonyfillAbortController {
|
|
49
56
|
this.signal = new PonyfillAbortSignal();
|
50
57
|
}
|
51
58
|
abort(reason) {
|
52
|
-
this.signal.dispatchEvent(new CustomEvent('abort', { detail: reason }));
|
59
|
+
this.signal.dispatchEvent(new CustomEvent$1('abort', { detail: reason }));
|
53
60
|
}
|
54
61
|
}
|
55
62
|
|
@@ -298,6 +305,10 @@ class PonyfillFormData {
|
|
298
305
|
controller.enqueue(Buffer.from(`\r\n--${boundary}\r\n`));
|
299
306
|
}
|
300
307
|
}
|
308
|
+
else {
|
309
|
+
controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
|
310
|
+
controller.close();
|
311
|
+
}
|
301
312
|
},
|
302
313
|
});
|
303
314
|
}
|
@@ -535,6 +546,39 @@ function processBodyInit(bodyInit) {
|
|
535
546
|
body,
|
536
547
|
};
|
537
548
|
}
|
549
|
+
if ('stream' in bodyInit) {
|
550
|
+
const bodyStream = bodyInit.stream();
|
551
|
+
const body = new PonyfillReadableStream(bodyStream);
|
552
|
+
return {
|
553
|
+
contentType: bodyInit.type,
|
554
|
+
contentLength: bodyInit.size,
|
555
|
+
body,
|
556
|
+
};
|
557
|
+
}
|
558
|
+
if (bodyInit instanceof URLSearchParams) {
|
559
|
+
const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
|
560
|
+
const body = new PonyfillReadableStream(Readable.from(bodyInit.toString()));
|
561
|
+
return {
|
562
|
+
bodyType: BodyInitType.String,
|
563
|
+
contentType,
|
564
|
+
contentLength: null,
|
565
|
+
body,
|
566
|
+
};
|
567
|
+
}
|
568
|
+
if ('forEach' in bodyInit) {
|
569
|
+
const formData = new PonyfillFormData();
|
570
|
+
bodyInit.forEach((value, key) => {
|
571
|
+
formData.append(key, value);
|
572
|
+
});
|
573
|
+
const boundary = Math.random().toString(36).substr(2);
|
574
|
+
const contentType = `multipart/form-data; boundary=${boundary}`;
|
575
|
+
const body = formData.stream(boundary);
|
576
|
+
return {
|
577
|
+
contentType,
|
578
|
+
contentLength: null,
|
579
|
+
body,
|
580
|
+
};
|
581
|
+
}
|
538
582
|
throw new Error('Unknown body type');
|
539
583
|
}
|
540
584
|
|
@@ -575,26 +619,26 @@ class PonyfillHeaders {
|
|
575
619
|
}
|
576
620
|
}
|
577
621
|
append(name, value) {
|
578
|
-
const key =
|
622
|
+
const key = name.toLowerCase();
|
579
623
|
if (this.map.has(key)) {
|
580
624
|
value = this.map.get(key) + ', ' + value;
|
581
625
|
}
|
582
626
|
this.map.set(key, value);
|
583
627
|
}
|
584
628
|
get(name) {
|
585
|
-
const key =
|
629
|
+
const key = name.toLowerCase();
|
586
630
|
return this.map.get(key) || null;
|
587
631
|
}
|
588
632
|
has(name) {
|
589
|
-
const key =
|
633
|
+
const key = name.toLowerCase();
|
590
634
|
return this.map.has(key);
|
591
635
|
}
|
592
636
|
set(name, value) {
|
593
|
-
const key =
|
637
|
+
const key = name.toLowerCase();
|
594
638
|
this.map.set(key, value);
|
595
639
|
}
|
596
640
|
delete(name) {
|
597
|
-
const key =
|
641
|
+
const key = name.toLowerCase();
|
598
642
|
this.map.delete(key);
|
599
643
|
}
|
600
644
|
forEach(callback) {
|
@@ -615,6 +659,7 @@ function isRequest(input) {
|
|
615
659
|
}
|
616
660
|
class PonyfillRequest extends PonyfillBody {
|
617
661
|
constructor(input, options) {
|
662
|
+
var _a;
|
618
663
|
let url;
|
619
664
|
let bodyInit = null;
|
620
665
|
let requestInit;
|
@@ -641,7 +686,7 @@ class PonyfillRequest extends PonyfillBody {
|
|
641
686
|
this.headers = new PonyfillHeaders(requestInit === null || requestInit === void 0 ? void 0 : requestInit.headers);
|
642
687
|
this.integrity = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.integrity) || '';
|
643
688
|
this.keepalive = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive) || true;
|
644
|
-
this.method = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) || 'GET';
|
689
|
+
this.method = ((_a = requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'GET';
|
645
690
|
this.mode = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.mode) || 'cors';
|
646
691
|
this.redirect = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.redirect) || 'follow';
|
647
692
|
this.referrer = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrer) || 'about:client';
|
@@ -747,9 +792,9 @@ function getResponseForFile(url) {
|
|
747
792
|
}
|
748
793
|
function getRequestFnForProtocol(protocol) {
|
749
794
|
switch (protocol) {
|
750
|
-
case 'http':
|
795
|
+
case 'http:':
|
751
796
|
return request$1;
|
752
|
-
case 'https':
|
797
|
+
case 'https:':
|
753
798
|
return request;
|
754
799
|
}
|
755
800
|
throw new Error(`Unsupported protocol: ${protocol}`);
|
@@ -762,13 +807,39 @@ function fetchPonyfill(info, init) {
|
|
762
807
|
const fetchRequest = info;
|
763
808
|
return new Promise((resolve, reject) => {
|
764
809
|
try {
|
765
|
-
const
|
766
|
-
if (protocol === '
|
767
|
-
const
|
810
|
+
const url = new URL(fetchRequest.url, 'http://localhost');
|
811
|
+
if (url.protocol === 'data:') {
|
812
|
+
const [mimeType = 'text/plain', base64FlagOrText, base64String] = url.pathname.split(',');
|
813
|
+
if (base64FlagOrText === 'base64' && base64String) {
|
814
|
+
const buffer = Buffer.from(base64String, 'base64');
|
815
|
+
const response = new PonyfillResponse(buffer, {
|
816
|
+
status: 200,
|
817
|
+
statusText: 'OK',
|
818
|
+
headers: {
|
819
|
+
'content-type': mimeType,
|
820
|
+
},
|
821
|
+
});
|
822
|
+
resolve(response);
|
823
|
+
return;
|
824
|
+
}
|
825
|
+
if (base64FlagOrText) {
|
826
|
+
const response = new PonyfillResponse(base64FlagOrText, {
|
827
|
+
status: 200,
|
828
|
+
statusText: 'OK',
|
829
|
+
headers: {
|
830
|
+
'content-type': mimeType,
|
831
|
+
},
|
832
|
+
});
|
833
|
+
resolve(response);
|
834
|
+
return;
|
835
|
+
}
|
836
|
+
}
|
837
|
+
if (url.protocol === 'file:') {
|
838
|
+
const response = getResponseForFile(url);
|
768
839
|
resolve(response);
|
769
840
|
return;
|
770
841
|
}
|
771
|
-
const requestFn = getRequestFnForProtocol(protocol);
|
842
|
+
const requestFn = getRequestFnForProtocol(url.protocol);
|
772
843
|
const nodeReadable = (fetchRequest.body != null
|
773
844
|
? 'pipe' in fetchRequest.body
|
774
845
|
? fetchRequest.body
|
@@ -777,10 +848,16 @@ function fetchPonyfill(info, init) {
|
|
777
848
|
const nodeHeaders = getHeadersObj(fetchRequest.headers);
|
778
849
|
const abortListener = function abortListener(event) {
|
779
850
|
nodeRequest.destroy();
|
780
|
-
|
851
|
+
const reason = event.detail;
|
852
|
+
if (reason instanceof Error) {
|
853
|
+
reject(reason);
|
854
|
+
}
|
855
|
+
else {
|
856
|
+
reject(new PonyfillAbortError(reason));
|
857
|
+
}
|
781
858
|
};
|
782
859
|
fetchRequest.signal.addEventListener('abort', abortListener);
|
783
|
-
const nodeRequest = requestFn(
|
860
|
+
const nodeRequest = requestFn(url, {
|
784
861
|
// signal: fetchRequest.signal will be added when v14 reaches EOL
|
785
862
|
method: fetchRequest.method,
|
786
863
|
headers: nodeHeaders,
|
@@ -794,7 +871,7 @@ function fetchPonyfill(info, init) {
|
|
794
871
|
return;
|
795
872
|
}
|
796
873
|
if (fetchRequest.redirect === 'follow') {
|
797
|
-
const redirectedUrl = new URL(nodeResponse.headers.location,
|
874
|
+
const redirectedUrl = new URL(nodeResponse.headers.location, url);
|
798
875
|
const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
|
799
876
|
resolve(redirectResponse$.then(redirectResponse => {
|
800
877
|
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-
|
3
|
+
"version": "0.0.1-alpha-20230117095738-14df726",
|
4
4
|
"description": "Fetch API implementation for Node",
|
5
5
|
"sideEffects": false,
|
6
6
|
"peerDependencies": {
|
@@ -9,7 +9,6 @@
|
|
9
9
|
"dependencies": {
|
10
10
|
"@whatwg-node/events": "0.0.2",
|
11
11
|
"busboy": "1.6.0",
|
12
|
-
"header-case": "^2.0.4",
|
13
12
|
"tslib": "^2.3.1"
|
14
13
|
},
|
15
14
|
"repository": {
|