@whatwg-node/node-fetch 0.7.8-alpha-20250122141536-187117d0e771637bc659740c29e4b57339e20311 → 0.7.8-alpha-20250122151422-7ab25b35ca978dfc1bf71e0e15f6e0996ef69966
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/fetch.js +14 -1
- package/cjs/fetchUndici.js +162 -147
- package/esm/fetch.js +14 -1
- package/esm/fetchUndici.js +163 -148
- package/package.json +1 -1
- package/typings/utils.d.cts +1 -1
- package/typings/utils.d.ts +1 -1
package/cjs/fetch.js
CHANGED
@@ -98,7 +98,20 @@ function getNativeGlobalDispatcher() {
|
|
98
98
|
function createFetchFn() {
|
99
99
|
const libcurlModuleName = 'node-libcurl';
|
100
100
|
const undiciModuleName = 'undici';
|
101
|
-
|
101
|
+
if (process.env.DEBUG) {
|
102
|
+
console.debug(`[@whatwg-node/node-fetch] - Trying to import ${libcurlModuleName} for fetch ponyfill`);
|
103
|
+
}
|
104
|
+
return Promise.resolve(`${libcurlModuleName}`).then(s => __importStar(require(s))).then(libcurl => (0, fetchCurl_js_1.createFetchCurl)(libcurl), () => {
|
105
|
+
if (process.env.DEBUG) {
|
106
|
+
console.debug(`[@whatwg-node/node-fetch] - Failed to import ${libcurlModuleName}, trying ${undiciModuleName}`);
|
107
|
+
}
|
108
|
+
return Promise.resolve(`${undiciModuleName}`).then(s => __importStar(require(s))).then((undici) => (0, fetchUndici_js_1.createFetchUndici)(() => undici.getGlobalDispatcher()), () => {
|
109
|
+
if (process.env.DEBUG) {
|
110
|
+
console.debug(`[@whatwg-node/node-fetch] - Failed to import ${undiciModuleName}, falling back to built-in undici in Node`);
|
111
|
+
}
|
112
|
+
return (0, fetchUndici_js_1.createFetchUndici)(getNativeGlobalDispatcher);
|
113
|
+
});
|
114
|
+
});
|
102
115
|
}
|
103
116
|
function fetchNonHttp(fetchRequest) {
|
104
117
|
if (fetchRequest.url.startsWith('data:')) {
|
package/cjs/fetchUndici.js
CHANGED
@@ -13,163 +13,178 @@ function createFetchUndici(getGlobalDispatcher) {
|
|
13
13
|
return function fetchUndici(fetchRequest) {
|
14
14
|
const dispatcher = fetchRequest.dispatcher || getGlobalDispatcher();
|
15
15
|
if (!dispatcher) {
|
16
|
+
if (process.env.DEBUG) {
|
17
|
+
console.debug('[@whatwg-node/node-fetch] - native undici dispatcher not available, falling back to node:http');
|
18
|
+
}
|
16
19
|
return (0, fetchNodeHttp_js_1.fetchNodeHttp)(fetchRequest);
|
17
20
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
const deferred = (0, utils_js_1.createDeferredPromise)();
|
22
|
+
let abortListener;
|
23
|
+
let passthrough;
|
24
|
+
let response;
|
25
|
+
let body = null;
|
26
|
+
const bodyInit = fetchRequest['bodyInit'];
|
27
|
+
if (bodyInit != null) {
|
28
|
+
if (typeof bodyInit === 'string' ||
|
29
|
+
Buffer.isBuffer(bodyInit) ||
|
30
|
+
(0, types_1.isUint8Array)(bodyInit) ||
|
31
|
+
bodyInit instanceof node_stream_1.Readable) {
|
32
|
+
body = bodyInit;
|
33
|
+
}
|
34
|
+
else if (fetchRequest.body != null) {
|
35
|
+
if ((0, utils_js_1.isNodeReadable)(fetchRequest.body?.readable)) {
|
36
|
+
body = fetchRequest.body.readable;
|
30
37
|
}
|
31
|
-
else
|
32
|
-
|
33
|
-
body = fetchRequest.body.readable;
|
34
|
-
}
|
35
|
-
else {
|
36
|
-
body = node_stream_1.Readable.from(fetchRequest.body);
|
37
|
-
}
|
38
|
+
else {
|
39
|
+
body = node_stream_1.Readable.from(fetchRequest.body);
|
38
40
|
}
|
39
41
|
}
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return passthrough;
|
42
|
+
}
|
43
|
+
function setPassthrough(contentEncoding) {
|
44
|
+
switch (contentEncoding) {
|
45
|
+
case 'x-gzip':
|
46
|
+
case 'gzip':
|
47
|
+
passthrough = (0, node_zlib_1.createGunzip)();
|
48
|
+
break;
|
49
|
+
case 'x-deflate':
|
50
|
+
case 'deflate':
|
51
|
+
passthrough = (0, node_zlib_1.createInflate)();
|
52
|
+
break;
|
53
|
+
case 'x-deflate-raw':
|
54
|
+
case 'deflate-raw':
|
55
|
+
passthrough = (0, node_zlib_1.createInflateRaw)();
|
56
|
+
break;
|
57
|
+
case 'br':
|
58
|
+
passthrough = (0, node_zlib_1.createBrotliDecompress)();
|
59
|
+
break;
|
60
|
+
default:
|
61
|
+
passthrough = new node_stream_1.PassThrough();
|
61
62
|
}
|
62
|
-
|
63
|
+
return passthrough;
|
64
|
+
}
|
65
|
+
function onAbort(e) {
|
66
|
+
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
67
|
+
passthrough?.destroy(e);
|
68
|
+
deferred.reject(e);
|
69
|
+
}
|
70
|
+
const headersSerializer = fetchRequest.headersSerializer || utils_js_1.getHeadersObj;
|
71
|
+
const nodeHeaders = headersSerializer(fetchRequest.headers);
|
72
|
+
if (nodeHeaders['accept-encoding'] == null) {
|
73
|
+
nodeHeaders['accept-encoding'] = 'gzip, deflate, br';
|
74
|
+
}
|
75
|
+
const dispatcherReturn = dispatcher.dispatch({
|
76
|
+
origin: fetchRequest.parsedUrl.origin,
|
77
|
+
path: fetchRequest.parsedUrl.pathname,
|
78
|
+
query: Object.fromEntries(fetchRequest.parsedUrl.searchParams),
|
79
|
+
method: fetchRequest.method,
|
80
|
+
headers: nodeHeaders,
|
81
|
+
body,
|
82
|
+
}, {
|
83
|
+
onRequestStart(controller) {
|
84
|
+
abortListener = function abortListener() {
|
85
|
+
onAbort(fetchRequest['_signal']?.reason);
|
86
|
+
controller.abort(fetchRequest['_signal']?.reason);
|
87
|
+
};
|
88
|
+
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
89
|
+
},
|
90
|
+
onRequestUpgrade(_controller, statusCode, headers, socket) {
|
91
|
+
response = new Response_js_1.PonyfillResponse(socket, {
|
92
|
+
status: statusCode,
|
93
|
+
headers: headers,
|
94
|
+
url: fetchRequest.url,
|
95
|
+
});
|
96
|
+
deferred.resolve(response);
|
63
97
|
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
(fetchRequest.dispatcher || getGlobalDispatcher()).dispatch({
|
73
|
-
origin: fetchRequest.parsedUrl.origin,
|
74
|
-
path: fetchRequest.parsedUrl.pathname,
|
75
|
-
query: Object.fromEntries(fetchRequest.parsedUrl.searchParams),
|
76
|
-
method: fetchRequest.method,
|
77
|
-
headers: nodeHeaders,
|
78
|
-
body,
|
79
|
-
}, {
|
80
|
-
onRequestStart(controller) {
|
81
|
-
abortListener = function abortListener() {
|
82
|
-
controller.abort(fetchRequest['_signal']?.reason);
|
83
|
-
onAbort(fetchRequest['_signal']?.reason);
|
84
|
-
};
|
85
|
-
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
86
|
-
},
|
87
|
-
onRequestUpgrade(_controller, statusCode, headers, socket) {
|
88
|
-
response = new Response_js_1.PonyfillResponse(socket, {
|
89
|
-
status: statusCode,
|
90
|
-
headers: headers,
|
91
|
-
url: fetchRequest.url,
|
92
|
-
});
|
93
|
-
resolve(response);
|
94
|
-
},
|
95
|
-
onResponseStart(controller, statusCode, headers, statusMessage) {
|
96
|
-
if (headers.location) {
|
97
|
-
if (fetchRequest.redirect === 'error') {
|
98
|
-
const redirectError = new Error('Redirects are not allowed');
|
99
|
-
reject(redirectError);
|
100
|
-
controller.resume();
|
101
|
-
return;
|
102
|
-
}
|
103
|
-
if (fetchRequest.redirect === 'follow') {
|
104
|
-
const redirectedUrl = new URL_js_1.PonyfillURL(headers.location, fetchRequest.parsedUrl || fetchRequest.url);
|
105
|
-
const redirectResponse$ = fetchUndici(new Request_js_1.PonyfillRequest(redirectedUrl, fetchRequest));
|
106
|
-
resolve(redirectResponse$.then(redirectResponse => {
|
107
|
-
redirectResponse.redirected = true;
|
108
|
-
return redirectResponse;
|
109
|
-
}));
|
110
|
-
controller.resume();
|
111
|
-
return;
|
112
|
-
}
|
98
|
+
},
|
99
|
+
onResponseStart(controller, statusCode, headers, statusMessage) {
|
100
|
+
if (headers.location) {
|
101
|
+
if (fetchRequest.redirect === 'error') {
|
102
|
+
const redirectError = new Error('Redirects are not allowed');
|
103
|
+
deferred.reject(redirectError);
|
104
|
+
controller.resume();
|
105
|
+
return;
|
113
106
|
}
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
}
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
}
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
onAbort(
|
142
|
-
}
|
143
|
-
|
144
|
-
onHeaders(statusCode, headersBuf, _resume, statusText) {
|
145
|
-
const headers = headersBuf.map(headerBuf => {
|
146
|
-
const header = headerBuf
|
147
|
-
.toString('utf-8')
|
148
|
-
.split(/:\s(.+)/)
|
149
|
-
.slice(0, 2);
|
150
|
-
if (header[0] === 'content-encoding') {
|
151
|
-
const contentEncoding = header[1];
|
152
|
-
setPassthrough(contentEncoding);
|
153
|
-
}
|
154
|
-
return header;
|
155
|
-
});
|
156
|
-
passthrough ||= new node_stream_1.PassThrough();
|
157
|
-
resolve(new Response_js_1.PonyfillResponse(passthrough, {
|
158
|
-
status: statusCode,
|
159
|
-
statusText,
|
160
|
-
headers,
|
161
|
-
url: fetchRequest.url,
|
162
|
-
}));
|
163
|
-
return true;
|
164
|
-
},
|
165
|
-
onData(chunk) {
|
166
|
-
return passthrough.write(chunk);
|
167
|
-
},
|
168
|
-
onComplete() {
|
107
|
+
if (fetchRequest.redirect === 'follow') {
|
108
|
+
const redirectedUrl = new URL_js_1.PonyfillURL(headers.location, fetchRequest.parsedUrl || fetchRequest.url);
|
109
|
+
const redirectResponse$ = fetchUndici(new Request_js_1.PonyfillRequest(redirectedUrl, fetchRequest));
|
110
|
+
deferred.resolve(redirectResponse$.then(redirectResponse => {
|
111
|
+
redirectResponse.redirected = true;
|
112
|
+
return redirectResponse;
|
113
|
+
}));
|
114
|
+
controller.resume();
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
passthrough = setPassthrough(headers['content-encoding']);
|
119
|
+
deferred.resolve(new Response_js_1.PonyfillResponse(passthrough, {
|
120
|
+
status: statusCode,
|
121
|
+
statusText: statusMessage,
|
122
|
+
headers: headers,
|
123
|
+
url: fetchRequest.url,
|
124
|
+
}));
|
125
|
+
},
|
126
|
+
onResponseData(controller, chunk) {
|
127
|
+
passthrough.write(chunk);
|
128
|
+
if (controller.reason) {
|
129
|
+
onAbort(controller.reason);
|
130
|
+
}
|
131
|
+
},
|
132
|
+
onResponseEnd(controller, _trailers) {
|
133
|
+
if (controller.reason) {
|
134
|
+
onAbort(controller.reason);
|
135
|
+
}
|
136
|
+
else {
|
169
137
|
passthrough.end();
|
170
138
|
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
171
|
-
}
|
172
|
-
}
|
139
|
+
}
|
140
|
+
},
|
141
|
+
onResponseError(controller, error) {
|
142
|
+
onAbort(error || controller.reason);
|
143
|
+
},
|
144
|
+
// Old Undici support
|
145
|
+
onConnect(abort) {
|
146
|
+
abortListener = function abortListener() {
|
147
|
+
abort(fetchRequest['_signal']?.reason);
|
148
|
+
onAbort(fetchRequest['_signal']?.reason);
|
149
|
+
};
|
150
|
+
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
151
|
+
},
|
152
|
+
onError(error) {
|
153
|
+
onAbort(error);
|
154
|
+
},
|
155
|
+
// TODO: onUpgrade
|
156
|
+
onHeaders(statusCode, headersBuf, _resume, statusText) {
|
157
|
+
const headers = headersBuf.map(headerBuf => {
|
158
|
+
const header = headerBuf
|
159
|
+
.toString('utf-8')
|
160
|
+
.split(/:\s(.+)/)
|
161
|
+
.slice(0, 2);
|
162
|
+
if (header[0] === 'content-encoding') {
|
163
|
+
const contentEncoding = header[1];
|
164
|
+
setPassthrough(contentEncoding);
|
165
|
+
}
|
166
|
+
return header;
|
167
|
+
});
|
168
|
+
passthrough ||= new node_stream_1.PassThrough();
|
169
|
+
deferred.resolve(new Response_js_1.PonyfillResponse(passthrough, {
|
170
|
+
status: statusCode,
|
171
|
+
statusText,
|
172
|
+
headers,
|
173
|
+
url: fetchRequest.url,
|
174
|
+
}));
|
175
|
+
return true;
|
176
|
+
},
|
177
|
+
onData(chunk) {
|
178
|
+
return passthrough.write(chunk);
|
179
|
+
},
|
180
|
+
onComplete() {
|
181
|
+
passthrough.end();
|
182
|
+
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
183
|
+
},
|
173
184
|
});
|
185
|
+
if (!dispatcherReturn) {
|
186
|
+
console.warn('Undici dispatcher returned false');
|
187
|
+
}
|
188
|
+
return deferred.promise;
|
174
189
|
};
|
175
190
|
}
|
package/esm/fetch.js
CHANGED
@@ -61,7 +61,20 @@ function getNativeGlobalDispatcher() {
|
|
61
61
|
function createFetchFn() {
|
62
62
|
const libcurlModuleName = 'node-libcurl';
|
63
63
|
const undiciModuleName = 'undici';
|
64
|
-
|
64
|
+
if (process.env.DEBUG) {
|
65
|
+
console.debug(`[@whatwg-node/node-fetch] - Trying to import ${libcurlModuleName} for fetch ponyfill`);
|
66
|
+
}
|
67
|
+
return import(libcurlModuleName).then(libcurl => createFetchCurl(libcurl), () => {
|
68
|
+
if (process.env.DEBUG) {
|
69
|
+
console.debug(`[@whatwg-node/node-fetch] - Failed to import ${libcurlModuleName}, trying ${undiciModuleName}`);
|
70
|
+
}
|
71
|
+
return import(undiciModuleName).then((undici) => createFetchUndici(() => undici.getGlobalDispatcher()), () => {
|
72
|
+
if (process.env.DEBUG) {
|
73
|
+
console.debug(`[@whatwg-node/node-fetch] - Failed to import ${undiciModuleName}, falling back to built-in undici in Node`);
|
74
|
+
}
|
75
|
+
return createFetchUndici(getNativeGlobalDispatcher);
|
76
|
+
});
|
77
|
+
});
|
65
78
|
}
|
66
79
|
function fetchNonHttp(fetchRequest) {
|
67
80
|
if (fetchRequest.url.startsWith('data:')) {
|
package/esm/fetchUndici.js
CHANGED
@@ -5,168 +5,183 @@ import { fetchNodeHttp } from './fetchNodeHttp.js';
|
|
5
5
|
import { PonyfillRequest } from './Request.js';
|
6
6
|
import { PonyfillResponse } from './Response.js';
|
7
7
|
import { PonyfillURL } from './URL.js';
|
8
|
-
import { getHeadersObj, isNodeReadable } from './utils.js';
|
8
|
+
import { createDeferredPromise, getHeadersObj, isNodeReadable } from './utils.js';
|
9
9
|
export function createFetchUndici(getGlobalDispatcher) {
|
10
10
|
return function fetchUndici(fetchRequest) {
|
11
11
|
const dispatcher = fetchRequest.dispatcher || getGlobalDispatcher();
|
12
12
|
if (!dispatcher) {
|
13
|
+
if (process.env.DEBUG) {
|
14
|
+
console.debug('[@whatwg-node/node-fetch] - native undici dispatcher not available, falling back to node:http');
|
15
|
+
}
|
13
16
|
return fetchNodeHttp(fetchRequest);
|
14
17
|
}
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
const deferred = createDeferredPromise();
|
19
|
+
let abortListener;
|
20
|
+
let passthrough;
|
21
|
+
let response;
|
22
|
+
let body = null;
|
23
|
+
const bodyInit = fetchRequest['bodyInit'];
|
24
|
+
if (bodyInit != null) {
|
25
|
+
if (typeof bodyInit === 'string' ||
|
26
|
+
Buffer.isBuffer(bodyInit) ||
|
27
|
+
isUint8Array(bodyInit) ||
|
28
|
+
bodyInit instanceof Readable) {
|
29
|
+
body = bodyInit;
|
30
|
+
}
|
31
|
+
else if (fetchRequest.body != null) {
|
32
|
+
if (isNodeReadable(fetchRequest.body?.readable)) {
|
33
|
+
body = fetchRequest.body.readable;
|
27
34
|
}
|
28
|
-
else
|
29
|
-
|
30
|
-
body = fetchRequest.body.readable;
|
31
|
-
}
|
32
|
-
else {
|
33
|
-
body = Readable.from(fetchRequest.body);
|
34
|
-
}
|
35
|
+
else {
|
36
|
+
body = Readable.from(fetchRequest.body);
|
35
37
|
}
|
36
38
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
return passthrough;
|
39
|
+
}
|
40
|
+
function setPassthrough(contentEncoding) {
|
41
|
+
switch (contentEncoding) {
|
42
|
+
case 'x-gzip':
|
43
|
+
case 'gzip':
|
44
|
+
passthrough = createGunzip();
|
45
|
+
break;
|
46
|
+
case 'x-deflate':
|
47
|
+
case 'deflate':
|
48
|
+
passthrough = createInflate();
|
49
|
+
break;
|
50
|
+
case 'x-deflate-raw':
|
51
|
+
case 'deflate-raw':
|
52
|
+
passthrough = createInflateRaw();
|
53
|
+
break;
|
54
|
+
case 'br':
|
55
|
+
passthrough = createBrotliDecompress();
|
56
|
+
break;
|
57
|
+
default:
|
58
|
+
passthrough = new PassThrough();
|
58
59
|
}
|
59
|
-
|
60
|
+
return passthrough;
|
61
|
+
}
|
62
|
+
function onAbort(e) {
|
63
|
+
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
64
|
+
passthrough?.destroy(e);
|
65
|
+
deferred.reject(e);
|
66
|
+
}
|
67
|
+
const headersSerializer = fetchRequest.headersSerializer || getHeadersObj;
|
68
|
+
const nodeHeaders = headersSerializer(fetchRequest.headers);
|
69
|
+
if (nodeHeaders['accept-encoding'] == null) {
|
70
|
+
nodeHeaders['accept-encoding'] = 'gzip, deflate, br';
|
71
|
+
}
|
72
|
+
const dispatcherReturn = dispatcher.dispatch({
|
73
|
+
origin: fetchRequest.parsedUrl.origin,
|
74
|
+
path: fetchRequest.parsedUrl.pathname,
|
75
|
+
query: Object.fromEntries(fetchRequest.parsedUrl.searchParams),
|
76
|
+
method: fetchRequest.method,
|
77
|
+
headers: nodeHeaders,
|
78
|
+
body,
|
79
|
+
}, {
|
80
|
+
onRequestStart(controller) {
|
81
|
+
abortListener = function abortListener() {
|
82
|
+
onAbort(fetchRequest['_signal']?.reason);
|
83
|
+
controller.abort(fetchRequest['_signal']?.reason);
|
84
|
+
};
|
85
|
+
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
86
|
+
},
|
87
|
+
onRequestUpgrade(_controller, statusCode, headers, socket) {
|
88
|
+
response = new PonyfillResponse(socket, {
|
89
|
+
status: statusCode,
|
90
|
+
headers: headers,
|
91
|
+
url: fetchRequest.url,
|
92
|
+
});
|
93
|
+
deferred.resolve(response);
|
60
94
|
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
(fetchRequest.dispatcher || getGlobalDispatcher()).dispatch({
|
70
|
-
origin: fetchRequest.parsedUrl.origin,
|
71
|
-
path: fetchRequest.parsedUrl.pathname,
|
72
|
-
query: Object.fromEntries(fetchRequest.parsedUrl.searchParams),
|
73
|
-
method: fetchRequest.method,
|
74
|
-
headers: nodeHeaders,
|
75
|
-
body,
|
76
|
-
}, {
|
77
|
-
onRequestStart(controller) {
|
78
|
-
abortListener = function abortListener() {
|
79
|
-
controller.abort(fetchRequest['_signal']?.reason);
|
80
|
-
onAbort(fetchRequest['_signal']?.reason);
|
81
|
-
};
|
82
|
-
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
83
|
-
},
|
84
|
-
onRequestUpgrade(_controller, statusCode, headers, socket) {
|
85
|
-
response = new PonyfillResponse(socket, {
|
86
|
-
status: statusCode,
|
87
|
-
headers: headers,
|
88
|
-
url: fetchRequest.url,
|
89
|
-
});
|
90
|
-
resolve(response);
|
91
|
-
},
|
92
|
-
onResponseStart(controller, statusCode, headers, statusMessage) {
|
93
|
-
if (headers.location) {
|
94
|
-
if (fetchRequest.redirect === 'error') {
|
95
|
-
const redirectError = new Error('Redirects are not allowed');
|
96
|
-
reject(redirectError);
|
97
|
-
controller.resume();
|
98
|
-
return;
|
99
|
-
}
|
100
|
-
if (fetchRequest.redirect === 'follow') {
|
101
|
-
const redirectedUrl = new PonyfillURL(headers.location, fetchRequest.parsedUrl || fetchRequest.url);
|
102
|
-
const redirectResponse$ = fetchUndici(new PonyfillRequest(redirectedUrl, fetchRequest));
|
103
|
-
resolve(redirectResponse$.then(redirectResponse => {
|
104
|
-
redirectResponse.redirected = true;
|
105
|
-
return redirectResponse;
|
106
|
-
}));
|
107
|
-
controller.resume();
|
108
|
-
return;
|
109
|
-
}
|
95
|
+
},
|
96
|
+
onResponseStart(controller, statusCode, headers, statusMessage) {
|
97
|
+
if (headers.location) {
|
98
|
+
if (fetchRequest.redirect === 'error') {
|
99
|
+
const redirectError = new Error('Redirects are not allowed');
|
100
|
+
deferred.reject(redirectError);
|
101
|
+
controller.resume();
|
102
|
+
return;
|
110
103
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
}
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
}
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
onAbort(
|
139
|
-
}
|
140
|
-
|
141
|
-
onHeaders(statusCode, headersBuf, _resume, statusText) {
|
142
|
-
const headers = headersBuf.map(headerBuf => {
|
143
|
-
const header = headerBuf
|
144
|
-
.toString('utf-8')
|
145
|
-
.split(/:\s(.+)/)
|
146
|
-
.slice(0, 2);
|
147
|
-
if (header[0] === 'content-encoding') {
|
148
|
-
const contentEncoding = header[1];
|
149
|
-
setPassthrough(contentEncoding);
|
150
|
-
}
|
151
|
-
return header;
|
152
|
-
});
|
153
|
-
passthrough ||= new PassThrough();
|
154
|
-
resolve(new PonyfillResponse(passthrough, {
|
155
|
-
status: statusCode,
|
156
|
-
statusText,
|
157
|
-
headers,
|
158
|
-
url: fetchRequest.url,
|
159
|
-
}));
|
160
|
-
return true;
|
161
|
-
},
|
162
|
-
onData(chunk) {
|
163
|
-
return passthrough.write(chunk);
|
164
|
-
},
|
165
|
-
onComplete() {
|
104
|
+
if (fetchRequest.redirect === 'follow') {
|
105
|
+
const redirectedUrl = new PonyfillURL(headers.location, fetchRequest.parsedUrl || fetchRequest.url);
|
106
|
+
const redirectResponse$ = fetchUndici(new PonyfillRequest(redirectedUrl, fetchRequest));
|
107
|
+
deferred.resolve(redirectResponse$.then(redirectResponse => {
|
108
|
+
redirectResponse.redirected = true;
|
109
|
+
return redirectResponse;
|
110
|
+
}));
|
111
|
+
controller.resume();
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
passthrough = setPassthrough(headers['content-encoding']);
|
116
|
+
deferred.resolve(new PonyfillResponse(passthrough, {
|
117
|
+
status: statusCode,
|
118
|
+
statusText: statusMessage,
|
119
|
+
headers: headers,
|
120
|
+
url: fetchRequest.url,
|
121
|
+
}));
|
122
|
+
},
|
123
|
+
onResponseData(controller, chunk) {
|
124
|
+
passthrough.write(chunk);
|
125
|
+
if (controller.reason) {
|
126
|
+
onAbort(controller.reason);
|
127
|
+
}
|
128
|
+
},
|
129
|
+
onResponseEnd(controller, _trailers) {
|
130
|
+
if (controller.reason) {
|
131
|
+
onAbort(controller.reason);
|
132
|
+
}
|
133
|
+
else {
|
166
134
|
passthrough.end();
|
167
135
|
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
168
|
-
}
|
169
|
-
}
|
136
|
+
}
|
137
|
+
},
|
138
|
+
onResponseError(controller, error) {
|
139
|
+
onAbort(error || controller.reason);
|
140
|
+
},
|
141
|
+
// Old Undici support
|
142
|
+
onConnect(abort) {
|
143
|
+
abortListener = function abortListener() {
|
144
|
+
abort(fetchRequest['_signal']?.reason);
|
145
|
+
onAbort(fetchRequest['_signal']?.reason);
|
146
|
+
};
|
147
|
+
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
148
|
+
},
|
149
|
+
onError(error) {
|
150
|
+
onAbort(error);
|
151
|
+
},
|
152
|
+
// TODO: onUpgrade
|
153
|
+
onHeaders(statusCode, headersBuf, _resume, statusText) {
|
154
|
+
const headers = headersBuf.map(headerBuf => {
|
155
|
+
const header = headerBuf
|
156
|
+
.toString('utf-8')
|
157
|
+
.split(/:\s(.+)/)
|
158
|
+
.slice(0, 2);
|
159
|
+
if (header[0] === 'content-encoding') {
|
160
|
+
const contentEncoding = header[1];
|
161
|
+
setPassthrough(contentEncoding);
|
162
|
+
}
|
163
|
+
return header;
|
164
|
+
});
|
165
|
+
passthrough ||= new PassThrough();
|
166
|
+
deferred.resolve(new PonyfillResponse(passthrough, {
|
167
|
+
status: statusCode,
|
168
|
+
statusText,
|
169
|
+
headers,
|
170
|
+
url: fetchRequest.url,
|
171
|
+
}));
|
172
|
+
return true;
|
173
|
+
},
|
174
|
+
onData(chunk) {
|
175
|
+
return passthrough.write(chunk);
|
176
|
+
},
|
177
|
+
onComplete() {
|
178
|
+
passthrough.end();
|
179
|
+
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
180
|
+
},
|
170
181
|
});
|
182
|
+
if (!dispatcherReturn) {
|
183
|
+
console.warn('Undici dispatcher returned false');
|
184
|
+
}
|
185
|
+
return deferred.promise;
|
171
186
|
};
|
172
187
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@whatwg-node/node-fetch",
|
3
|
-
"version": "0.7.8-alpha-
|
3
|
+
"version": "0.7.8-alpha-20250122151422-7ab25b35ca978dfc1bf71e0e15f6e0996ef69966",
|
4
4
|
"description": "Fetch API implementation for Node",
|
5
5
|
"sideEffects": false,
|
6
6
|
"dependencies": {
|
package/typings/utils.d.cts
CHANGED
@@ -6,7 +6,7 @@ export declare function isArrayBufferView(obj: any): obj is ArrayBufferView;
|
|
6
6
|
export declare function isNodeReadable(obj: any): obj is Readable;
|
7
7
|
export interface DeferredPromise<T = void> {
|
8
8
|
promise: Promise<T>;
|
9
|
-
resolve: (value: T) => void;
|
9
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
10
10
|
reject: (reason: any) => void;
|
11
11
|
}
|
12
12
|
export declare function createDeferredPromise<T = void>(): DeferredPromise<T>;
|
package/typings/utils.d.ts
CHANGED
@@ -6,7 +6,7 @@ export declare function isArrayBufferView(obj: any): obj is ArrayBufferView;
|
|
6
6
|
export declare function isNodeReadable(obj: any): obj is Readable;
|
7
7
|
export interface DeferredPromise<T = void> {
|
8
8
|
promise: Promise<T>;
|
9
|
-
resolve: (value: T) => void;
|
9
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
10
10
|
reject: (reason: any) => void;
|
11
11
|
}
|
12
12
|
export declare function createDeferredPromise<T = void>(): DeferredPromise<T>;
|