@whatwg-node/node-fetch 0.7.8-alpha-20250122135958-d7c45737356867271ee584ba6eb3446d0bfa504b → 0.7.8-alpha-20250122150621-99aa3b02dabf84434a687202da321ea8807e453d
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 -152
- package/esm/fetch.js +14 -1
- package/esm/fetchUndici.js +163 -153
- 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,168 +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
|
-
|
30
|
-
}
|
31
|
-
else if (fetchRequest.body != null) {
|
32
|
-
if ((0, utils_js_1.isNodeReadable)(fetchRequest.body?.readable)) {
|
33
|
-
body = fetchRequest.body.readable;
|
34
|
-
}
|
35
|
-
else {
|
36
|
-
body = node_stream_1.Readable.from(fetchRequest.body);
|
37
|
-
}
|
38
|
-
}
|
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;
|
39
33
|
}
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
case 'x-deflate':
|
47
|
-
case 'deflate':
|
48
|
-
passthrough = (0, node_zlib_1.createInflate)();
|
49
|
-
break;
|
50
|
-
case 'x-deflate-raw':
|
51
|
-
case 'deflate-raw':
|
52
|
-
passthrough = (0, node_zlib_1.createInflateRaw)();
|
53
|
-
break;
|
54
|
-
case 'br':
|
55
|
-
passthrough = (0, node_zlib_1.createBrotliDecompress)();
|
56
|
-
break;
|
57
|
-
default:
|
58
|
-
passthrough = new node_stream_1.PassThrough();
|
34
|
+
else if (fetchRequest.body != null) {
|
35
|
+
if ((0, utils_js_1.isNodeReadable)(fetchRequest.body?.readable)) {
|
36
|
+
body = fetchRequest.body.readable;
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
body = node_stream_1.Readable.from(fetchRequest.body);
|
59
40
|
}
|
60
|
-
return passthrough;
|
61
41
|
}
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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();
|
66
62
|
}
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
status: statusCode,
|
111
|
-
statusText: statusMessage,
|
112
|
-
headers: headers,
|
113
|
-
url: fetchRequest.url,
|
114
|
-
}));
|
115
|
-
},
|
116
|
-
onResponseData(_controller, chunk) {
|
117
|
-
passthrough.write(chunk);
|
118
|
-
},
|
119
|
-
onResponseEnd(_controller, _trailers) {
|
120
|
-
passthrough.end();
|
121
|
-
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
122
|
-
},
|
123
|
-
onResponseError(_controller, error) {
|
124
|
-
if (passthrough) {
|
125
|
-
passthrough.destroy(error);
|
126
|
-
}
|
127
|
-
else {
|
128
|
-
reject(error);
|
129
|
-
}
|
130
|
-
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
131
|
-
},
|
132
|
-
// Old Undici support
|
133
|
-
onConnect(abort) {
|
134
|
-
abortListener = function abortListener() {
|
135
|
-
abort(fetchRequest['_signal']?.reason);
|
136
|
-
};
|
137
|
-
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
138
|
-
},
|
139
|
-
onError(error) {
|
140
|
-
if (passthrough) {
|
141
|
-
passthrough.destroy(error);
|
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);
|
97
|
+
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
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;
|
142
106
|
}
|
143
|
-
|
144
|
-
|
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;
|
145
116
|
}
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
url: fetchRequest.url,
|
167
|
-
}));
|
168
|
-
return true;
|
169
|
-
},
|
170
|
-
onData(chunk) {
|
171
|
-
return passthrough.write(chunk);
|
172
|
-
},
|
173
|
-
onComplete() {
|
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 {
|
174
137
|
passthrough.end();
|
175
138
|
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
176
|
-
}
|
177
|
-
}
|
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
|
+
},
|
178
184
|
});
|
185
|
+
if (!dispatcherReturn) {
|
186
|
+
console.warn('Undici dispatcher returned false');
|
187
|
+
}
|
188
|
+
return deferred.promise;
|
179
189
|
};
|
180
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,173 +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
|
-
|
27
|
-
}
|
28
|
-
else if (fetchRequest.body != null) {
|
29
|
-
if (isNodeReadable(fetchRequest.body?.readable)) {
|
30
|
-
body = fetchRequest.body.readable;
|
31
|
-
}
|
32
|
-
else {
|
33
|
-
body = Readable.from(fetchRequest.body);
|
34
|
-
}
|
35
|
-
}
|
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;
|
36
30
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
case 'x-deflate':
|
44
|
-
case 'deflate':
|
45
|
-
passthrough = createInflate();
|
46
|
-
break;
|
47
|
-
case 'x-deflate-raw':
|
48
|
-
case 'deflate-raw':
|
49
|
-
passthrough = createInflateRaw();
|
50
|
-
break;
|
51
|
-
case 'br':
|
52
|
-
passthrough = createBrotliDecompress();
|
53
|
-
break;
|
54
|
-
default:
|
55
|
-
passthrough = new PassThrough();
|
31
|
+
else if (fetchRequest.body != null) {
|
32
|
+
if (isNodeReadable(fetchRequest.body?.readable)) {
|
33
|
+
body = fetchRequest.body.readable;
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
body = Readable.from(fetchRequest.body);
|
56
37
|
}
|
57
|
-
return passthrough;
|
58
38
|
}
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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();
|
63
59
|
}
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
status: statusCode,
|
108
|
-
statusText: statusMessage,
|
109
|
-
headers: headers,
|
110
|
-
url: fetchRequest.url,
|
111
|
-
}));
|
112
|
-
},
|
113
|
-
onResponseData(_controller, chunk) {
|
114
|
-
passthrough.write(chunk);
|
115
|
-
},
|
116
|
-
onResponseEnd(_controller, _trailers) {
|
117
|
-
passthrough.end();
|
118
|
-
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
119
|
-
},
|
120
|
-
onResponseError(_controller, error) {
|
121
|
-
if (passthrough) {
|
122
|
-
passthrough.destroy(error);
|
123
|
-
}
|
124
|
-
else {
|
125
|
-
reject(error);
|
126
|
-
}
|
127
|
-
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
128
|
-
},
|
129
|
-
// Old Undici support
|
130
|
-
onConnect(abort) {
|
131
|
-
abortListener = function abortListener() {
|
132
|
-
abort(fetchRequest['_signal']?.reason);
|
133
|
-
};
|
134
|
-
fetchRequest['_signal']?.addEventListener('abort', abortListener, { once: true });
|
135
|
-
},
|
136
|
-
onError(error) {
|
137
|
-
if (passthrough) {
|
138
|
-
passthrough.destroy(error);
|
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);
|
94
|
+
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
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;
|
139
103
|
}
|
140
|
-
|
141
|
-
|
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;
|
142
113
|
}
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
url: fetchRequest.url,
|
164
|
-
}));
|
165
|
-
return true;
|
166
|
-
},
|
167
|
-
onData(chunk) {
|
168
|
-
return passthrough.write(chunk);
|
169
|
-
},
|
170
|
-
onComplete() {
|
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 {
|
171
134
|
passthrough.end();
|
172
135
|
fetchRequest['_signal']?.removeEventListener('abort', abortListener);
|
173
|
-
}
|
174
|
-
}
|
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
|
+
},
|
175
181
|
});
|
182
|
+
if (!dispatcherReturn) {
|
183
|
+
console.warn('Undici dispatcher returned false');
|
184
|
+
}
|
185
|
+
return deferred.promise;
|
176
186
|
};
|
177
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-20250122150621-99aa3b02dabf84434a687202da321ea8807e453d",
|
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>;
|