@whatwg-node/node-fetch 0.3.0 → 0.4.0-alpha-20230215085115-d099e0b
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/cjs/AbortController.js +14 -0
- package/cjs/AbortError.js +20 -0
- package/cjs/AbortSignal.js +37 -0
- package/cjs/Blob.js +119 -0
- package/cjs/Body.js +372 -0
- package/cjs/File.js +13 -0
- package/cjs/FormData.js +121 -0
- package/cjs/Headers.js +121 -0
- package/cjs/ReadableStream.js +172 -0
- package/cjs/Request.js +69 -0
- package/cjs/Response.js +75 -0
- package/cjs/TextEncoderDecoder.js +39 -0
- package/cjs/URL.js +55 -0
- package/cjs/URLSearchParams.js +103 -0
- package/cjs/fetch.js +127 -0
- package/cjs/index.js +35 -0
- package/cjs/package.json +1 -0
- package/cjs/utils.js +18 -0
- package/esm/AbortController.js +10 -0
- package/esm/AbortError.js +16 -0
- package/esm/AbortSignal.js +33 -0
- package/esm/Blob.js +115 -0
- package/esm/Body.js +367 -0
- package/esm/File.js +9 -0
- package/esm/FormData.js +116 -0
- package/esm/Headers.js +117 -0
- package/esm/ReadableStream.js +168 -0
- package/esm/Request.js +65 -0
- package/esm/Response.js +71 -0
- package/esm/TextEncoderDecoder.js +33 -0
- package/esm/URL.js +50 -0
- package/esm/URLSearchParams.js +98 -0
- package/esm/fetch.js +123 -0
- package/esm/index.js +15 -0
- package/esm/utils.js +13 -0
- package/package.json +19 -12
- package/typings/AbortController.d.cts +5 -0
- package/{AbortController.d.ts → typings/AbortController.d.ts} +1 -1
- package/{AbortError.d.ts → typings/AbortError.d.cts} +0 -0
- package/typings/AbortError.d.ts +4 -0
- package/{AbortSignal.d.ts → typings/AbortSignal.d.cts} +0 -0
- package/typings/AbortSignal.d.ts +11 -0
- package/{Blob.d.ts → typings/Blob.d.cts} +0 -0
- package/typings/Blob.d.ts +18 -0
- package/typings/Body.d.cts +41 -0
- package/{Body.d.ts → typings/Body.d.ts} +3 -3
- package/typings/File.d.cts +7 -0
- package/{File.d.ts → typings/File.d.ts} +1 -1
- package/typings/FormData.d.cts +14 -0
- package/{FormData.d.ts → typings/FormData.d.ts} +2 -2
- package/{Headers.d.ts → typings/Headers.d.cts} +0 -0
- package/typings/Headers.d.ts +19 -0
- package/{ReadableStream.d.ts → typings/ReadableStream.d.cts} +0 -0
- package/typings/ReadableStream.d.ts +20 -0
- package/typings/Request.d.cts +24 -0
- package/{Request.d.ts → typings/Request.d.ts} +2 -2
- package/typings/Response.d.cts +22 -0
- package/{Response.d.ts → typings/Response.d.ts} +2 -2
- package/{TextEncoderDecoder.d.ts → typings/TextEncoderDecoder.d.cts} +0 -0
- package/typings/TextEncoderDecoder.d.ts +15 -0
- package/typings/URL.d.cts +14 -0
- package/{URL.d.ts → typings/URL.d.ts} +1 -1
- package/{URLSearchParams.d.ts → typings/URLSearchParams.d.cts} +0 -0
- package/typings/URLSearchParams.d.ts +17 -0
- package/typings/fetch.d.cts +3 -0
- package/{fetch.d.ts → typings/fetch.d.ts} +2 -2
- package/typings/index.d.cts +15 -0
- package/typings/index.d.ts +15 -0
- package/{utils.d.ts → typings/utils.d.cts} +0 -0
- package/typings/utils.d.ts +2 -0
- package/index.d.ts +0 -15
- package/index.js +0 -1417
- package/index.mjs +0 -1395
@@ -0,0 +1,168 @@
|
|
1
|
+
import { Readable } from 'stream';
|
2
|
+
function createController(desiredSize, readable) {
|
3
|
+
let chunks = [];
|
4
|
+
let _closed = false;
|
5
|
+
let flushed = false;
|
6
|
+
return {
|
7
|
+
desiredSize,
|
8
|
+
enqueue(chunk) {
|
9
|
+
const buf = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
|
10
|
+
if (!flushed) {
|
11
|
+
chunks.push(buf);
|
12
|
+
}
|
13
|
+
else {
|
14
|
+
readable.push(buf);
|
15
|
+
}
|
16
|
+
},
|
17
|
+
close() {
|
18
|
+
if (chunks.length > 0) {
|
19
|
+
this._flush();
|
20
|
+
}
|
21
|
+
readable.push(null);
|
22
|
+
_closed = true;
|
23
|
+
},
|
24
|
+
error(error) {
|
25
|
+
if (chunks.length > 0) {
|
26
|
+
this._flush();
|
27
|
+
}
|
28
|
+
readable.destroy(error);
|
29
|
+
},
|
30
|
+
get _closed() {
|
31
|
+
return _closed;
|
32
|
+
},
|
33
|
+
_flush() {
|
34
|
+
flushed = true;
|
35
|
+
if (chunks.length > 0) {
|
36
|
+
const concatenated = Buffer.concat(chunks);
|
37
|
+
readable.push(concatenated);
|
38
|
+
chunks = [];
|
39
|
+
}
|
40
|
+
},
|
41
|
+
};
|
42
|
+
}
|
43
|
+
export class PonyfillReadableStream {
|
44
|
+
constructor(underlyingSource) {
|
45
|
+
this.locked = false;
|
46
|
+
if (underlyingSource instanceof PonyfillReadableStream) {
|
47
|
+
this.readable = underlyingSource.readable;
|
48
|
+
}
|
49
|
+
else if (underlyingSource && 'read' in underlyingSource) {
|
50
|
+
this.readable = underlyingSource;
|
51
|
+
}
|
52
|
+
else if (underlyingSource && 'getReader' in underlyingSource) {
|
53
|
+
let reader;
|
54
|
+
let started = false;
|
55
|
+
this.readable = new Readable({
|
56
|
+
read() {
|
57
|
+
if (!started) {
|
58
|
+
started = true;
|
59
|
+
reader = underlyingSource.getReader();
|
60
|
+
}
|
61
|
+
reader
|
62
|
+
.read()
|
63
|
+
.then(({ value, done }) => {
|
64
|
+
if (done) {
|
65
|
+
this.push(null);
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
this.push(value);
|
69
|
+
}
|
70
|
+
})
|
71
|
+
.catch(err => {
|
72
|
+
this.destroy(err);
|
73
|
+
});
|
74
|
+
},
|
75
|
+
destroy(err, callback) {
|
76
|
+
reader.cancel(err).then(() => callback(err), callback);
|
77
|
+
},
|
78
|
+
});
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
let started = false;
|
82
|
+
let ongoing = false;
|
83
|
+
this.readable = new Readable({
|
84
|
+
read(desiredSize) {
|
85
|
+
if (ongoing) {
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
ongoing = true;
|
89
|
+
return Promise.resolve().then(async () => {
|
90
|
+
var _a, _b;
|
91
|
+
if (!started) {
|
92
|
+
const controller = createController(desiredSize, this);
|
93
|
+
started = true;
|
94
|
+
await ((_a = underlyingSource === null || underlyingSource === void 0 ? void 0 : underlyingSource.start) === null || _a === void 0 ? void 0 : _a.call(underlyingSource, controller));
|
95
|
+
controller._flush();
|
96
|
+
if (controller._closed) {
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
const controller = createController(desiredSize, this);
|
101
|
+
await ((_b = underlyingSource === null || underlyingSource === void 0 ? void 0 : underlyingSource.pull) === null || _b === void 0 ? void 0 : _b.call(underlyingSource, controller));
|
102
|
+
controller._flush();
|
103
|
+
ongoing = false;
|
104
|
+
});
|
105
|
+
},
|
106
|
+
async destroy(err, callback) {
|
107
|
+
var _a;
|
108
|
+
try {
|
109
|
+
await ((_a = underlyingSource === null || underlyingSource === void 0 ? void 0 : underlyingSource.cancel) === null || _a === void 0 ? void 0 : _a.call(underlyingSource, err));
|
110
|
+
callback(null);
|
111
|
+
}
|
112
|
+
catch (err) {
|
113
|
+
callback(err);
|
114
|
+
}
|
115
|
+
},
|
116
|
+
});
|
117
|
+
}
|
118
|
+
}
|
119
|
+
cancel(reason) {
|
120
|
+
this.readable.destroy(reason);
|
121
|
+
return Promise.resolve();
|
122
|
+
}
|
123
|
+
getReader(_options) {
|
124
|
+
const iterator = this.readable[Symbol.asyncIterator]();
|
125
|
+
this.locked = true;
|
126
|
+
return {
|
127
|
+
read() {
|
128
|
+
return iterator.next();
|
129
|
+
},
|
130
|
+
releaseLock: () => {
|
131
|
+
var _a;
|
132
|
+
(_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator);
|
133
|
+
this.locked = false;
|
134
|
+
},
|
135
|
+
cancel: async (reason) => {
|
136
|
+
var _a;
|
137
|
+
await ((_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator, reason));
|
138
|
+
this.locked = false;
|
139
|
+
},
|
140
|
+
closed: new Promise((resolve, reject) => {
|
141
|
+
this.readable.once('end', resolve);
|
142
|
+
this.readable.once('error', reject);
|
143
|
+
}),
|
144
|
+
};
|
145
|
+
}
|
146
|
+
[Symbol.asyncIterator]() {
|
147
|
+
return this.readable[Symbol.asyncIterator]();
|
148
|
+
}
|
149
|
+
tee() {
|
150
|
+
throw new Error('Not implemented');
|
151
|
+
}
|
152
|
+
async pipeTo(destination) {
|
153
|
+
const writer = destination.getWriter();
|
154
|
+
await writer.ready;
|
155
|
+
for await (const chunk of this.readable) {
|
156
|
+
await writer.write(chunk);
|
157
|
+
}
|
158
|
+
await writer.ready;
|
159
|
+
return writer.close();
|
160
|
+
}
|
161
|
+
pipeThrough({ writable, readable, }) {
|
162
|
+
this.pipeTo(writable);
|
163
|
+
return readable;
|
164
|
+
}
|
165
|
+
static [Symbol.hasInstance](instance) {
|
166
|
+
return instance != null && typeof instance === 'object' && 'getReader' in instance;
|
167
|
+
}
|
168
|
+
}
|
package/esm/Request.js
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
import { PonyfillAbortController } from './AbortController.js';
|
2
|
+
import { PonyfillBody } from './Body.js';
|
3
|
+
import { PonyfillHeaders } from './Headers.js';
|
4
|
+
function isRequest(input) {
|
5
|
+
return input[Symbol.toStringTag] === 'Request';
|
6
|
+
}
|
7
|
+
export class PonyfillRequest extends PonyfillBody {
|
8
|
+
constructor(input, options) {
|
9
|
+
var _a;
|
10
|
+
let url;
|
11
|
+
let bodyInit = null;
|
12
|
+
let requestInit;
|
13
|
+
if (typeof input === 'string') {
|
14
|
+
url = input;
|
15
|
+
}
|
16
|
+
else if ('href' in input) {
|
17
|
+
url = input.toString();
|
18
|
+
}
|
19
|
+
else if (isRequest(input)) {
|
20
|
+
url = input.url;
|
21
|
+
bodyInit = input.body;
|
22
|
+
requestInit = input;
|
23
|
+
}
|
24
|
+
if (options != null) {
|
25
|
+
bodyInit = options.body || null;
|
26
|
+
requestInit = options;
|
27
|
+
}
|
28
|
+
super(bodyInit, options);
|
29
|
+
this.destination = '';
|
30
|
+
this.priority = 'auto';
|
31
|
+
this.cache = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.cache) || 'default';
|
32
|
+
this.credentials = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.credentials) || 'same-origin';
|
33
|
+
this.headers = new PonyfillHeaders(requestInit === null || requestInit === void 0 ? void 0 : requestInit.headers);
|
34
|
+
this.integrity = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.integrity) || '';
|
35
|
+
this.keepalive = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive) != null ? requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive : false;
|
36
|
+
this.method = ((_a = requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'GET';
|
37
|
+
this.mode = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.mode) || 'cors';
|
38
|
+
this.redirect = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.redirect) || 'follow';
|
39
|
+
this.referrer = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrer) || 'about:client';
|
40
|
+
this.referrerPolicy = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrerPolicy) || 'no-referrer';
|
41
|
+
this.signal = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.signal) || new PonyfillAbortController().signal;
|
42
|
+
this.url = url || '';
|
43
|
+
const contentTypeInHeaders = this.headers.get('content-type');
|
44
|
+
if (!contentTypeInHeaders) {
|
45
|
+
if (this.contentType) {
|
46
|
+
this.headers.set('content-type', this.contentType);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
this.contentType = contentTypeInHeaders;
|
51
|
+
}
|
52
|
+
const contentLengthInHeaders = this.headers.get('content-length');
|
53
|
+
if (!contentLengthInHeaders) {
|
54
|
+
if (this.contentLength) {
|
55
|
+
this.headers.set('content-length', this.contentLength.toString());
|
56
|
+
}
|
57
|
+
}
|
58
|
+
else {
|
59
|
+
this.contentLength = parseInt(contentLengthInHeaders, 10);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
clone() {
|
63
|
+
return new Request(this);
|
64
|
+
}
|
65
|
+
}
|
package/esm/Response.js
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
import { PonyfillBody } from './Body.js';
|
2
|
+
import { PonyfillHeaders } from './Headers.js';
|
3
|
+
export class PonyfillResponse extends PonyfillBody {
|
4
|
+
constructor(body, init) {
|
5
|
+
super(body || null, init);
|
6
|
+
this.headers = new PonyfillHeaders();
|
7
|
+
this.status = 200;
|
8
|
+
this.statusText = 'OK';
|
9
|
+
this.url = '';
|
10
|
+
this.redirected = false;
|
11
|
+
this.type = 'default';
|
12
|
+
if (init) {
|
13
|
+
this.headers = new PonyfillHeaders(init.headers);
|
14
|
+
this.status = init.status || 200;
|
15
|
+
this.statusText = init.statusText || 'OK';
|
16
|
+
this.url = init.url || '';
|
17
|
+
this.redirected = init.redirected || false;
|
18
|
+
this.type = init.type || 'default';
|
19
|
+
}
|
20
|
+
const contentTypeInHeaders = this.headers.get('content-type');
|
21
|
+
if (!contentTypeInHeaders) {
|
22
|
+
if (this.contentType) {
|
23
|
+
this.headers.set('content-type', this.contentType);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
else {
|
27
|
+
this.contentType = contentTypeInHeaders;
|
28
|
+
}
|
29
|
+
const contentLengthInHeaders = this.headers.get('content-length');
|
30
|
+
if (!contentLengthInHeaders) {
|
31
|
+
if (this.contentLength) {
|
32
|
+
this.headers.set('content-length', this.contentLength.toString());
|
33
|
+
}
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
this.contentLength = parseInt(contentLengthInHeaders, 10);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
get ok() {
|
40
|
+
return this.status >= 200 && this.status < 300;
|
41
|
+
}
|
42
|
+
clone() {
|
43
|
+
return new PonyfillResponse(this.body, this);
|
44
|
+
}
|
45
|
+
static error() {
|
46
|
+
return new PonyfillResponse(null, {
|
47
|
+
status: 500,
|
48
|
+
statusText: 'Internal Server Error',
|
49
|
+
});
|
50
|
+
}
|
51
|
+
static redirect(url, status = 301) {
|
52
|
+
if (status < 300 || status > 399) {
|
53
|
+
throw new RangeError('Invalid status code');
|
54
|
+
}
|
55
|
+
return new PonyfillResponse(null, {
|
56
|
+
headers: {
|
57
|
+
location: url,
|
58
|
+
},
|
59
|
+
status,
|
60
|
+
});
|
61
|
+
}
|
62
|
+
static json(data, init = {}) {
|
63
|
+
return new PonyfillResponse(JSON.stringify(data), {
|
64
|
+
...init,
|
65
|
+
headers: {
|
66
|
+
'Content-Type': 'application/json',
|
67
|
+
...init === null || init === void 0 ? void 0 : init.headers,
|
68
|
+
},
|
69
|
+
});
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
export class PonyfillTextEncoder {
|
2
|
+
constructor(encoding = 'utf-8') {
|
3
|
+
this.encoding = encoding;
|
4
|
+
}
|
5
|
+
encode(input) {
|
6
|
+
return Buffer.from(input, this.encoding);
|
7
|
+
}
|
8
|
+
encodeInto(source, destination) {
|
9
|
+
const buffer = this.encode(source);
|
10
|
+
const copied = buffer.copy(destination);
|
11
|
+
return {
|
12
|
+
read: copied,
|
13
|
+
written: copied,
|
14
|
+
};
|
15
|
+
}
|
16
|
+
}
|
17
|
+
export class PonyfillTextDecoder {
|
18
|
+
constructor(encoding = 'utf-8', options) {
|
19
|
+
this.encoding = encoding;
|
20
|
+
this.fatal = false;
|
21
|
+
this.ignoreBOM = false;
|
22
|
+
if (options) {
|
23
|
+
this.fatal = options.fatal || false;
|
24
|
+
this.ignoreBOM = options.ignoreBOM || false;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
decode(input) {
|
28
|
+
return Buffer.from(input).toString(this.encoding);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
export function PonyfillBtoa(input) {
|
32
|
+
return Buffer.from(input, 'binary').toString('base64');
|
33
|
+
}
|
package/esm/URL.js
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
import FastQuerystring from 'fast-querystring';
|
2
|
+
import FastUrl from 'fast-url-parser';
|
3
|
+
import { PonyfillURLSearchParams } from './URLSearchParams.js';
|
4
|
+
FastUrl.queryString = FastQuerystring;
|
5
|
+
export class PonyfillURL extends FastUrl {
|
6
|
+
constructor(url, base) {
|
7
|
+
super();
|
8
|
+
if (url.startsWith('data:')) {
|
9
|
+
this.protocol = 'data:';
|
10
|
+
this.pathname = url.slice('data:'.length);
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
this.parse(url, false);
|
14
|
+
if (base) {
|
15
|
+
const baseParsed = typeof base === 'string' ? new PonyfillURL(base) : base;
|
16
|
+
this.protocol = this.protocol || baseParsed.protocol;
|
17
|
+
this.host = this.host || baseParsed.host;
|
18
|
+
this.pathname = this.pathname || baseParsed.pathname;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
get origin() {
|
22
|
+
return `${this.protocol}//${this.host}`;
|
23
|
+
}
|
24
|
+
get searchParams() {
|
25
|
+
if (!this._searchParams) {
|
26
|
+
this._searchParams = new PonyfillURLSearchParams(this.query);
|
27
|
+
}
|
28
|
+
return this._searchParams;
|
29
|
+
}
|
30
|
+
get username() {
|
31
|
+
var _a;
|
32
|
+
return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[0]) || '';
|
33
|
+
}
|
34
|
+
set username(value) {
|
35
|
+
this.auth = `${value}:${this.password}`;
|
36
|
+
}
|
37
|
+
get password() {
|
38
|
+
var _a;
|
39
|
+
return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[1]) || '';
|
40
|
+
}
|
41
|
+
set password(value) {
|
42
|
+
this.auth = `${this.username}:${value}`;
|
43
|
+
}
|
44
|
+
toString() {
|
45
|
+
return this.format();
|
46
|
+
}
|
47
|
+
toJSON() {
|
48
|
+
return this.toString();
|
49
|
+
}
|
50
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import FastQuerystring from 'fast-querystring';
|
2
|
+
export class PonyfillURLSearchParams {
|
3
|
+
constructor(init) {
|
4
|
+
if (init) {
|
5
|
+
if (typeof init === 'string') {
|
6
|
+
this.params = FastQuerystring.parse(init);
|
7
|
+
}
|
8
|
+
else if (Array.isArray(init)) {
|
9
|
+
this.params = {};
|
10
|
+
for (const [key, value] of init) {
|
11
|
+
this.params[key] = value;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
else if ('entries' in init) {
|
15
|
+
this.params = {};
|
16
|
+
for (const [key, value] of init.entries()) {
|
17
|
+
this.params[key] = value;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
else {
|
21
|
+
this.params = init;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
else {
|
25
|
+
this.params = {};
|
26
|
+
}
|
27
|
+
}
|
28
|
+
append(name, value) {
|
29
|
+
const existingValue = this.params[name];
|
30
|
+
const finalValue = existingValue ? `${existingValue},${value}` : value;
|
31
|
+
this.params[name] = finalValue;
|
32
|
+
}
|
33
|
+
delete(name) {
|
34
|
+
delete this.params[name];
|
35
|
+
}
|
36
|
+
get(name) {
|
37
|
+
const value = this.params[name];
|
38
|
+
if (Array.isArray(value)) {
|
39
|
+
return value[0] || null;
|
40
|
+
}
|
41
|
+
return value || null;
|
42
|
+
}
|
43
|
+
getAll(name) {
|
44
|
+
const value = this.params[name];
|
45
|
+
if (!Array.isArray(value)) {
|
46
|
+
return value ? [value] : [];
|
47
|
+
}
|
48
|
+
return value;
|
49
|
+
}
|
50
|
+
has(name) {
|
51
|
+
return name in this.params;
|
52
|
+
}
|
53
|
+
set(name, value) {
|
54
|
+
this.params[name] = value;
|
55
|
+
}
|
56
|
+
sort() {
|
57
|
+
const sortedKeys = Object.keys(this.params).sort();
|
58
|
+
const sortedParams = {};
|
59
|
+
for (const key of sortedKeys) {
|
60
|
+
sortedParams[key] = this.params[key];
|
61
|
+
}
|
62
|
+
this.params = sortedParams;
|
63
|
+
}
|
64
|
+
toString() {
|
65
|
+
return FastQuerystring.stringify(this.params);
|
66
|
+
}
|
67
|
+
*keys() {
|
68
|
+
for (const key in this.params) {
|
69
|
+
yield key;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
*entries() {
|
73
|
+
for (const key of this.keys()) {
|
74
|
+
const value = this.params[key];
|
75
|
+
if (Array.isArray(value)) {
|
76
|
+
for (const item of value) {
|
77
|
+
yield [key, item];
|
78
|
+
}
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
yield [key, value];
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
*values() {
|
86
|
+
for (const [, value] of this) {
|
87
|
+
yield value;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
[Symbol.iterator]() {
|
91
|
+
return this.entries();
|
92
|
+
}
|
93
|
+
forEach(callback) {
|
94
|
+
for (const [key, value] of this) {
|
95
|
+
callback(value, key, this);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
package/esm/fetch.js
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
import { createReadStream } from 'fs';
|
2
|
+
import { request as httpRequest } from 'http';
|
3
|
+
import { request as httpsRequest } from 'https';
|
4
|
+
import { Readable } from 'stream';
|
5
|
+
import { fileURLToPath } from 'url';
|
6
|
+
import { PonyfillAbortError } from './AbortError.js';
|
7
|
+
import { PonyfillBlob } from './Blob.js';
|
8
|
+
import { PonyfillRequest } from './Request.js';
|
9
|
+
import { PonyfillResponse } from './Response.js';
|
10
|
+
import { PonyfillURL } from './URL.js';
|
11
|
+
import { getHeadersObj } from './utils.js';
|
12
|
+
function getResponseForFile(url) {
|
13
|
+
const path = fileURLToPath(url);
|
14
|
+
const readable = createReadStream(path);
|
15
|
+
return new PonyfillResponse(readable);
|
16
|
+
}
|
17
|
+
function getRequestFnForProtocol(protocol) {
|
18
|
+
switch (protocol) {
|
19
|
+
case 'http:':
|
20
|
+
return httpRequest;
|
21
|
+
case 'https:':
|
22
|
+
return httpsRequest;
|
23
|
+
}
|
24
|
+
throw new Error(`Unsupported protocol: ${protocol}`);
|
25
|
+
}
|
26
|
+
const BASE64_SUFFIX = ';base64';
|
27
|
+
export function fetchPonyfill(info, init) {
|
28
|
+
if (typeof info === 'string' || 'href' in info) {
|
29
|
+
const ponyfillRequest = new PonyfillRequest(info, init);
|
30
|
+
return fetchPonyfill(ponyfillRequest);
|
31
|
+
}
|
32
|
+
const fetchRequest = info;
|
33
|
+
return new Promise((resolve, reject) => {
|
34
|
+
try {
|
35
|
+
const url = new PonyfillURL(fetchRequest.url, 'http://localhost');
|
36
|
+
if (url.protocol === 'data:') {
|
37
|
+
const [mimeType = 'text/plain', ...datas] = url.pathname.split(',');
|
38
|
+
const data = decodeURIComponent(datas.join(','));
|
39
|
+
if (mimeType.endsWith(BASE64_SUFFIX)) {
|
40
|
+
const buffer = Buffer.from(data, 'base64url');
|
41
|
+
const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
|
42
|
+
const file = new PonyfillBlob([buffer], { type: realMimeType });
|
43
|
+
const response = new PonyfillResponse(file, {
|
44
|
+
status: 200,
|
45
|
+
statusText: 'OK',
|
46
|
+
});
|
47
|
+
resolve(response);
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
const response = new PonyfillResponse(data, {
|
51
|
+
status: 200,
|
52
|
+
statusText: 'OK',
|
53
|
+
headers: {
|
54
|
+
'content-type': mimeType,
|
55
|
+
},
|
56
|
+
});
|
57
|
+
resolve(response);
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
if (url.protocol === 'file:') {
|
61
|
+
const response = getResponseForFile(fetchRequest.url);
|
62
|
+
resolve(response);
|
63
|
+
return;
|
64
|
+
}
|
65
|
+
const requestFn = getRequestFnForProtocol(url.protocol);
|
66
|
+
const nodeReadable = (fetchRequest.body != null
|
67
|
+
? 'pipe' in fetchRequest.body
|
68
|
+
? fetchRequest.body
|
69
|
+
: Readable.from(fetchRequest.body)
|
70
|
+
: null);
|
71
|
+
const nodeHeaders = getHeadersObj(fetchRequest.headers);
|
72
|
+
const abortListener = function abortListener(event) {
|
73
|
+
nodeRequest.destroy();
|
74
|
+
const reason = event.detail;
|
75
|
+
reject(new PonyfillAbortError(reason));
|
76
|
+
};
|
77
|
+
fetchRequest.signal.addEventListener('abort', abortListener);
|
78
|
+
const nodeRequest = requestFn(fetchRequest.url, {
|
79
|
+
// signal: fetchRequest.signal will be added when v14 reaches EOL
|
80
|
+
method: fetchRequest.method,
|
81
|
+
headers: nodeHeaders,
|
82
|
+
});
|
83
|
+
nodeRequest.once('response', nodeResponse => {
|
84
|
+
if (nodeResponse.headers.location) {
|
85
|
+
if (fetchRequest.redirect === 'error') {
|
86
|
+
const redirectError = new Error('Redirects are not allowed');
|
87
|
+
reject(redirectError);
|
88
|
+
nodeResponse.resume();
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
if (fetchRequest.redirect === 'follow') {
|
92
|
+
const redirectedUrl = new PonyfillURL(nodeResponse.headers.location, url);
|
93
|
+
const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
|
94
|
+
resolve(redirectResponse$.then(redirectResponse => {
|
95
|
+
redirectResponse.redirected = true;
|
96
|
+
return redirectResponse;
|
97
|
+
}));
|
98
|
+
nodeResponse.resume();
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
const responseHeaders = nodeResponse.headers;
|
103
|
+
const ponyfillResponse = new PonyfillResponse(nodeResponse, {
|
104
|
+
status: nodeResponse.statusCode,
|
105
|
+
statusText: nodeResponse.statusMessage,
|
106
|
+
headers: responseHeaders,
|
107
|
+
url: info.url,
|
108
|
+
});
|
109
|
+
resolve(ponyfillResponse);
|
110
|
+
});
|
111
|
+
nodeRequest.once('error', reject);
|
112
|
+
if (nodeReadable) {
|
113
|
+
nodeReadable.pipe(nodeRequest);
|
114
|
+
}
|
115
|
+
else {
|
116
|
+
nodeRequest.end();
|
117
|
+
}
|
118
|
+
}
|
119
|
+
catch (e) {
|
120
|
+
reject(e);
|
121
|
+
}
|
122
|
+
});
|
123
|
+
}
|
package/esm/index.js
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
export { fetchPonyfill as fetch } from './fetch.js';
|
2
|
+
export { PonyfillHeaders as Headers } from './Headers.js';
|
3
|
+
export { PonyfillBody as Body } from './Body.js';
|
4
|
+
export { PonyfillRequest as Request } from './Request.js';
|
5
|
+
export { PonyfillResponse as Response } from './Response.js';
|
6
|
+
export { PonyfillReadableStream as ReadableStream } from './ReadableStream.js';
|
7
|
+
export { PonyfillFile as File } from './File.js';
|
8
|
+
export { PonyfillFormData as FormData } from './FormData.js';
|
9
|
+
export { PonyfillAbortController as AbortController } from './AbortController.js';
|
10
|
+
export { PonyfillAbortSignal as AbortSignal } from './AbortSignal.js';
|
11
|
+
export { PonyfillAbortError as AbortError } from './AbortError.js';
|
12
|
+
export { PonyfillBlob as Blob } from './Blob.js';
|
13
|
+
export { PonyfillTextEncoder as TextEncoder, PonyfillTextDecoder as TextDecoder, PonyfillBtoa as btoa, } from './TextEncoderDecoder.js';
|
14
|
+
export { PonyfillURL as URL } from './URL.js';
|
15
|
+
export { PonyfillURLSearchParams as URLSearchParams } from './URLSearchParams.js';
|
package/esm/utils.js
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
export function getHeadersObj(headers) {
|
2
|
+
if (headers == null || !('forEach' in headers)) {
|
3
|
+
return headers;
|
4
|
+
}
|
5
|
+
const obj = {};
|
6
|
+
headers.forEach((value, key) => {
|
7
|
+
obj[key] = value;
|
8
|
+
});
|
9
|
+
return obj;
|
10
|
+
}
|
11
|
+
export function uint8ArrayToArrayBuffer(uint8array) {
|
12
|
+
return uint8array.buffer.slice(uint8array.byteOffset, uint8array.byteOffset + uint8array.byteLength);
|
13
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@whatwg-node/node-fetch",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.4.0-alpha-20230215085115-d099e0b",
|
4
4
|
"description": "Fetch API implementation for Node",
|
5
5
|
"sideEffects": false,
|
6
6
|
"peerDependencies": {
|
@@ -20,21 +20,28 @@
|
|
20
20
|
},
|
21
21
|
"author": "Arda TANRIKULU <ardatanrikulu@gmail.com>",
|
22
22
|
"license": "MIT",
|
23
|
-
"main": "index.js",
|
24
|
-
"module": "index.
|
25
|
-
"typings": "index.d.ts",
|
23
|
+
"main": "cjs/index.js",
|
24
|
+
"module": "esm/index.js",
|
25
|
+
"typings": "typings/index.d.ts",
|
26
26
|
"typescript": {
|
27
|
-
"definition": "index.d.ts"
|
27
|
+
"definition": "typings/index.d.ts"
|
28
28
|
},
|
29
|
+
"type": "module",
|
29
30
|
"exports": {
|
30
31
|
".": {
|
31
|
-
"require":
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
"
|
36
|
-
|
32
|
+
"require": {
|
33
|
+
"types": "./typings/index.d.cts",
|
34
|
+
"default": "./cjs/index.js"
|
35
|
+
},
|
36
|
+
"import": {
|
37
|
+
"types": "./typings/index.d.ts",
|
38
|
+
"default": "./esm/index.js"
|
39
|
+
},
|
40
|
+
"default": {
|
41
|
+
"types": "./typings/index.d.ts",
|
42
|
+
"default": "./esm/index.js"
|
43
|
+
}
|
37
44
|
},
|
38
45
|
"./package.json": "./package.json"
|
39
46
|
}
|
40
|
-
}
|
47
|
+
}
|