@whatwg-node/node-fetch 0.7.8-alpha-20250122230954-3105b2fac861fe650311d5dc0f4a88470234b0b5 → 0.7.8-alpha-20250124215951-ab82e441881dc42c7b236e47e5cbd62a5e2a359d
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/Request.js +0 -1
- package/cjs/fetch.js +40 -97
- package/cjs/fetchCurl.js +137 -139
- package/esm/Request.js +0 -1
- package/esm/fetch.js +42 -65
- package/esm/fetchCurl.js +136 -138
- package/package.json +1 -1
- package/typings/Request.d.cts +0 -1
- package/typings/Request.d.ts +0 -1
- package/typings/fetch.d.cts +0 -2
- package/typings/fetch.d.ts +0 -2
- package/typings/fetchCurl.d.cts +1 -1
- package/typings/fetchCurl.d.ts +1 -1
- package/typings/utils.d.cts +1 -1
- package/typings/utils.d.ts +1 -1
- package/cjs/fetchUndici.js +0 -190
- package/esm/fetchUndici.js +0 -187
- package/typings/fetchUndici.d.cts +0 -3
- package/typings/fetchUndici.d.ts +0 -3
package/cjs/Request.js
CHANGED
package/cjs/fetch.js
CHANGED
@@ -1,55 +1,47 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
-
if (k2 === undefined) k2 = k;
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
-
}
|
8
|
-
Object.defineProperty(o, k2, desc);
|
9
|
-
}) : (function(o, m, k, k2) {
|
10
|
-
if (k2 === undefined) k2 = k;
|
11
|
-
o[k2] = m[k];
|
12
|
-
}));
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
-
}) : function(o, v) {
|
16
|
-
o["default"] = v;
|
17
|
-
});
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
19
|
-
var ownKeys = function(o) {
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
-
var ar = [];
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
-
return ar;
|
24
|
-
};
|
25
|
-
return ownKeys(o);
|
26
|
-
};
|
27
|
-
return function (mod) {
|
28
|
-
if (mod && mod.__esModule) return mod;
|
29
|
-
var result = {};
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
-
__setModuleDefault(result, mod);
|
32
|
-
return result;
|
33
|
-
};
|
34
|
-
})();
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
-
exports.createFetchPonyfill = createFetchPonyfill;
|
37
3
|
exports.fetchPonyfill = fetchPonyfill;
|
38
4
|
const node_buffer_1 = require("node:buffer");
|
39
5
|
const node_fs_1 = require("node:fs");
|
40
6
|
const node_url_1 = require("node:url");
|
41
|
-
const types_1 = require("node:util/types");
|
42
7
|
const fetchCurl_js_1 = require("./fetchCurl.js");
|
43
|
-
const
|
8
|
+
const fetchNodeHttp_js_1 = require("./fetchNodeHttp.js");
|
44
9
|
const Request_js_1 = require("./Request.js");
|
45
10
|
const Response_js_1 = require("./Response.js");
|
46
11
|
const URL_js_1 = require("./URL.js");
|
47
12
|
const utils_js_1 = require("./utils.js");
|
48
13
|
const BASE64_SUFFIX = ';base64';
|
49
|
-
function getResponseForFile(url) {
|
14
|
+
async function getResponseForFile(url) {
|
50
15
|
const path = (0, node_url_1.fileURLToPath)(url);
|
51
|
-
|
52
|
-
|
16
|
+
try {
|
17
|
+
const stats = await node_fs_1.promises.stat(path, {
|
18
|
+
bigint: true,
|
19
|
+
});
|
20
|
+
const readable = (0, node_fs_1.createReadStream)(path);
|
21
|
+
return new Response_js_1.PonyfillResponse(readable, {
|
22
|
+
status: 200,
|
23
|
+
statusText: 'OK',
|
24
|
+
headers: {
|
25
|
+
'content-type': 'application/octet-stream',
|
26
|
+
'last-modified': stats.mtime.toUTCString(),
|
27
|
+
},
|
28
|
+
});
|
29
|
+
}
|
30
|
+
catch (err) {
|
31
|
+
if (err.code === 'ENOENT') {
|
32
|
+
return new Response_js_1.PonyfillResponse(null, {
|
33
|
+
status: 404,
|
34
|
+
statusText: 'Not Found',
|
35
|
+
});
|
36
|
+
}
|
37
|
+
else if (err.code === 'EACCES') {
|
38
|
+
return new Response_js_1.PonyfillResponse(null, {
|
39
|
+
status: 403,
|
40
|
+
statusText: 'Forbidden',
|
41
|
+
});
|
42
|
+
}
|
43
|
+
throw err;
|
44
|
+
}
|
53
45
|
}
|
54
46
|
function getResponseForDataUri(url) {
|
55
47
|
const [mimeType = 'text/plain', ...datas] = url.substring(5).split(',');
|
@@ -89,75 +81,26 @@ function getResponseForBlob(url) {
|
|
89
81
|
function isURL(obj) {
|
90
82
|
return obj != null && obj.href != null;
|
91
83
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
return globalThis[Symbol.for('undici.globalDispatcher.1')];
|
97
|
-
}
|
98
|
-
function createFetchFn() {
|
99
|
-
const libcurlModuleName = 'node-libcurl';
|
100
|
-
const undiciModuleName = 'undici';
|
101
|
-
if (process.env.DEBUG) {
|
102
|
-
console.debug(`[@whatwg-node/node-fetch] - Trying to import ${libcurlModuleName} for fetch ponyfill`);
|
84
|
+
function fetchPonyfill(info, init) {
|
85
|
+
if (typeof info === 'string' || isURL(info)) {
|
86
|
+
const ponyfillRequest = new Request_js_1.PonyfillRequest(info, init);
|
87
|
+
return fetchPonyfill(ponyfillRequest);
|
103
88
|
}
|
104
|
-
|
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
|
-
});
|
115
|
-
}
|
116
|
-
function fetchNonHttp(fetchRequest) {
|
89
|
+
const fetchRequest = info;
|
117
90
|
if (fetchRequest.url.startsWith('data:')) {
|
118
91
|
const response = getResponseForDataUri(fetchRequest.url);
|
119
92
|
return (0, utils_js_1.fakePromise)(response);
|
120
93
|
}
|
121
94
|
if (fetchRequest.url.startsWith('file:')) {
|
122
95
|
const response = getResponseForFile(fetchRequest.url);
|
123
|
-
return
|
96
|
+
return response;
|
124
97
|
}
|
125
98
|
if (fetchRequest.url.startsWith('blob:')) {
|
126
99
|
const response = getResponseForBlob(fetchRequest.url);
|
127
100
|
return (0, utils_js_1.fakePromise)(response);
|
128
101
|
}
|
129
|
-
|
130
|
-
|
131
|
-
if (typeof info === 'string' || isURL(info)) {
|
132
|
-
return new Request_js_1.PonyfillRequest(info, init);
|
133
|
-
}
|
134
|
-
return info;
|
135
|
-
}
|
136
|
-
function createFetchPonyfill(fetchFn) {
|
137
|
-
return function fetchPonyfill(info, init) {
|
138
|
-
info = normalizeInfo(info, init);
|
139
|
-
const nonHttpRes = fetchNonHttp(info);
|
140
|
-
if (nonHttpRes) {
|
141
|
-
return nonHttpRes;
|
142
|
-
}
|
143
|
-
return fetchFn(info);
|
144
|
-
};
|
145
|
-
}
|
146
|
-
function fetchPonyfill(info, init) {
|
147
|
-
info = normalizeInfo(info, init);
|
148
|
-
const nonHttpRes = fetchNonHttp(info);
|
149
|
-
if (nonHttpRes) {
|
150
|
-
return nonHttpRes;
|
151
|
-
}
|
152
|
-
if (!fetchFn) {
|
153
|
-
fetchFn$ ||= createFetchFn();
|
154
|
-
if ((0, types_1.isPromise)(fetchFn$)) {
|
155
|
-
return fetchFn$.then(newFetchFn => {
|
156
|
-
fetchFn = newFetchFn;
|
157
|
-
return fetchFn(info);
|
158
|
-
});
|
159
|
-
}
|
160
|
-
fetchFn = fetchFn$;
|
102
|
+
if (globalThis.libcurl && !fetchRequest.agent) {
|
103
|
+
return (0, fetchCurl_js_1.fetchCurl)(fetchRequest);
|
161
104
|
}
|
162
|
-
return
|
105
|
+
return (0, fetchNodeHttp_js_1.fetchNodeHttp)(fetchRequest);
|
163
106
|
}
|
package/cjs/fetchCurl.js
CHANGED
@@ -1,162 +1,160 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.fetchCurl = fetchCurl;
|
4
4
|
const node_stream_1 = require("node:stream");
|
5
5
|
const promises_1 = require("node:stream/promises");
|
6
6
|
const node_tls_1 = require("node:tls");
|
7
7
|
const Response_js_1 = require("./Response.js");
|
8
8
|
const utils_js_1 = require("./utils.js");
|
9
|
-
function
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
function fetchCurl(fetchRequest) {
|
10
|
+
const { Curl, CurlFeature, CurlPause, CurlProgressFunc } = globalThis['libcurl'];
|
11
|
+
const curlHandle = new Curl();
|
12
|
+
curlHandle.enable(CurlFeature.NoDataParsing);
|
13
|
+
curlHandle.setOpt('URL', fetchRequest.url);
|
14
|
+
if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
|
15
|
+
curlHandle.setOpt('SSL_VERIFYPEER', false);
|
16
|
+
}
|
17
|
+
if (process.env.NODE_EXTRA_CA_CERTS) {
|
18
|
+
curlHandle.setOpt('CAINFO', process.env.NODE_EXTRA_CA_CERTS);
|
19
|
+
}
|
20
|
+
else {
|
21
|
+
curlHandle.setOpt('CAINFO_BLOB', node_tls_1.rootCertificates.join('\n'));
|
22
|
+
}
|
23
|
+
curlHandle.enable(CurlFeature.StreamResponse);
|
24
|
+
curlHandle.setStreamProgressCallback(function () {
|
25
|
+
return fetchRequest['_signal']?.aborted
|
26
|
+
? process.env.DEBUG
|
27
|
+
? CurlProgressFunc.Continue
|
28
|
+
: 1
|
29
|
+
: 0;
|
30
|
+
});
|
31
|
+
if (fetchRequest['bodyType'] === 'String') {
|
32
|
+
curlHandle.setOpt('POSTFIELDS', fetchRequest['bodyInit']);
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
const nodeReadable = (fetchRequest.body != null
|
36
|
+
? (0, utils_js_1.isNodeReadable)(fetchRequest.body)
|
37
|
+
? fetchRequest.body
|
38
|
+
: node_stream_1.Readable.from(fetchRequest.body)
|
39
|
+
: null);
|
40
|
+
if (nodeReadable) {
|
41
|
+
curlHandle.setOpt('UPLOAD', true);
|
42
|
+
curlHandle.setUploadStream(nodeReadable);
|
17
43
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
44
|
+
}
|
45
|
+
if (process.env.DEBUG) {
|
46
|
+
curlHandle.setOpt('VERBOSE', true);
|
47
|
+
}
|
48
|
+
curlHandle.setOpt('TRANSFER_ENCODING', false);
|
49
|
+
curlHandle.setOpt('HTTP_TRANSFER_DECODING', true);
|
50
|
+
curlHandle.setOpt('FOLLOWLOCATION', fetchRequest.redirect === 'follow');
|
51
|
+
curlHandle.setOpt('MAXREDIRS', 20);
|
52
|
+
curlHandle.setOpt('ACCEPT_ENCODING', '');
|
53
|
+
curlHandle.setOpt('CUSTOMREQUEST', fetchRequest.method);
|
54
|
+
const headersSerializer = fetchRequest.headersSerializer || utils_js_1.defaultHeadersSerializer;
|
55
|
+
let size;
|
56
|
+
const curlHeaders = headersSerializer(fetchRequest.headers, value => {
|
57
|
+
size = Number(value);
|
58
|
+
});
|
59
|
+
if (size != null) {
|
60
|
+
curlHandle.setOpt('INFILESIZE', size);
|
61
|
+
}
|
62
|
+
curlHandle.setOpt('HTTPHEADER', curlHeaders);
|
63
|
+
curlHandle.enable(CurlFeature.NoHeaderParsing);
|
64
|
+
const deferredPromise = (0, utils_js_1.createDeferredPromise)();
|
65
|
+
let streamResolved;
|
66
|
+
function onAbort() {
|
67
|
+
if (curlHandle.isOpen) {
|
68
|
+
try {
|
69
|
+
curlHandle.pause(CurlPause.Recv);
|
70
|
+
}
|
71
|
+
catch (e) {
|
72
|
+
deferredPromise.reject(e);
|
73
|
+
}
|
23
74
|
}
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
});
|
32
|
-
if (fetchRequest['bodyType'] === 'String') {
|
33
|
-
curlHandle.setOpt('POSTFIELDS', fetchRequest['bodyInit']);
|
75
|
+
}
|
76
|
+
if (fetchRequest['_signal']) {
|
77
|
+
fetchRequest['_signal'].addEventListener('abort', onAbort, { once: true });
|
78
|
+
}
|
79
|
+
curlHandle.once('end', function endListener() {
|
80
|
+
try {
|
81
|
+
curlHandle.close();
|
34
82
|
}
|
35
|
-
|
36
|
-
|
37
|
-
? (0, utils_js_1.isNodeReadable)(fetchRequest.body)
|
38
|
-
? fetchRequest.body
|
39
|
-
: node_stream_1.Readable.from(fetchRequest.body)
|
40
|
-
: null);
|
41
|
-
if (nodeReadable) {
|
42
|
-
curlHandle.setOpt('UPLOAD', true);
|
43
|
-
curlHandle.setUploadStream(nodeReadable);
|
44
|
-
}
|
83
|
+
catch (e) {
|
84
|
+
deferredPromise.reject(e);
|
45
85
|
}
|
46
|
-
if (
|
47
|
-
|
86
|
+
if (fetchRequest['_signal']) {
|
87
|
+
fetchRequest['_signal'].removeEventListener('abort', onAbort);
|
48
88
|
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
curlHandle.setOpt('ACCEPT_ENCODING', '');
|
54
|
-
curlHandle.setOpt('CUSTOMREQUEST', fetchRequest.method);
|
55
|
-
const headersSerializer = fetchRequest.headersSerializer || utils_js_1.defaultHeadersSerializer;
|
56
|
-
let size;
|
57
|
-
const curlHeaders = headersSerializer(fetchRequest.headers, value => {
|
58
|
-
size = Number(value);
|
59
|
-
});
|
60
|
-
if (size != null) {
|
61
|
-
curlHandle.setOpt('INFILESIZE', size);
|
89
|
+
});
|
90
|
+
curlHandle.once('error', function errorListener(error) {
|
91
|
+
if (streamResolved && !streamResolved.closed && !streamResolved.destroyed) {
|
92
|
+
streamResolved.destroy(error);
|
62
93
|
}
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
let streamResolved;
|
67
|
-
function onAbort() {
|
68
|
-
if (curlHandle.isOpen) {
|
69
|
-
try {
|
70
|
-
curlHandle.pause(CurlPause.Recv);
|
71
|
-
}
|
72
|
-
catch (e) {
|
73
|
-
deferredPromise.reject(e);
|
74
|
-
}
|
94
|
+
else {
|
95
|
+
if (error.message === 'Operation was aborted by an application callback') {
|
96
|
+
error.message = 'The operation was aborted.';
|
75
97
|
}
|
98
|
+
deferredPromise.reject(error);
|
76
99
|
}
|
77
|
-
|
78
|
-
|
100
|
+
try {
|
101
|
+
curlHandle.close();
|
79
102
|
}
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
streamResolved.destroy(error);
|
103
|
+
catch (e) {
|
104
|
+
deferredPromise.reject(e);
|
105
|
+
}
|
106
|
+
});
|
107
|
+
curlHandle.once('stream', function streamListener(stream, status, headersBuf) {
|
108
|
+
const outputStream = new node_stream_1.PassThrough();
|
109
|
+
(0, promises_1.pipeline)(stream, outputStream, {
|
110
|
+
end: true,
|
111
|
+
signal: fetchRequest['_signal'] ?? undefined,
|
112
|
+
})
|
113
|
+
.then(() => {
|
114
|
+
if (!stream.destroyed) {
|
115
|
+
stream.resume();
|
94
116
|
}
|
95
|
-
|
96
|
-
|
97
|
-
|
117
|
+
})
|
118
|
+
.catch(deferredPromise.reject);
|
119
|
+
const headersFlat = headersBuf
|
120
|
+
.toString('utf8')
|
121
|
+
.split(/\r?\n|\r/g)
|
122
|
+
.filter(headerFilter => {
|
123
|
+
if (headerFilter && !headerFilter.startsWith('HTTP/')) {
|
124
|
+
if (fetchRequest.redirect === 'error' &&
|
125
|
+
(headerFilter.includes('location') || headerFilter.includes('Location'))) {
|
126
|
+
if (!stream.destroyed) {
|
127
|
+
stream.resume();
|
128
|
+
}
|
129
|
+
outputStream.destroy();
|
130
|
+
deferredPromise.reject(new Error('redirect is not allowed'));
|
98
131
|
}
|
99
|
-
|
100
|
-
}
|
101
|
-
try {
|
102
|
-
curlHandle.close();
|
103
|
-
}
|
104
|
-
catch (e) {
|
105
|
-
deferredPromise.reject(e);
|
132
|
+
return true;
|
106
133
|
}
|
134
|
+
return false;
|
107
135
|
});
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
.then(() => {
|
115
|
-
if (!stream.destroyed) {
|
116
|
-
stream.resume();
|
117
|
-
}
|
118
|
-
})
|
119
|
-
.catch(deferredPromise.reject);
|
120
|
-
const headersFlat = headersBuf
|
121
|
-
.toString('utf8')
|
122
|
-
.split(/\r?\n|\r/g)
|
123
|
-
.filter(headerFilter => {
|
124
|
-
if (headerFilter && !headerFilter.startsWith('HTTP/')) {
|
125
|
-
if (fetchRequest.redirect === 'error' &&
|
126
|
-
(headerFilter.includes('location') || headerFilter.includes('Location'))) {
|
127
|
-
if (!stream.destroyed) {
|
128
|
-
stream.resume();
|
129
|
-
}
|
130
|
-
outputStream.destroy();
|
131
|
-
deferredPromise.reject(new Error('redirect is not allowed'));
|
132
|
-
}
|
133
|
-
return true;
|
134
|
-
}
|
135
|
-
return false;
|
136
|
-
});
|
137
|
-
const headersInit = headersFlat.map(headerFlat => headerFlat.split(/:\s(.+)/).slice(0, 2));
|
138
|
-
const ponyfillResponse = new Response_js_1.PonyfillResponse(outputStream, {
|
139
|
-
status,
|
140
|
-
headers: headersInit,
|
141
|
-
url: curlHandle.getInfo(Curl.info.REDIRECT_URL)?.toString() || fetchRequest.url,
|
142
|
-
redirected: Number(curlHandle.getInfo(Curl.info.REDIRECT_COUNT)) > 0,
|
143
|
-
});
|
144
|
-
deferredPromise.resolve(ponyfillResponse);
|
145
|
-
streamResolved = outputStream;
|
136
|
+
const headersInit = headersFlat.map(headerFlat => headerFlat.split(/:\s(.+)/).slice(0, 2));
|
137
|
+
const ponyfillResponse = new Response_js_1.PonyfillResponse(outputStream, {
|
138
|
+
status,
|
139
|
+
headers: headersInit,
|
140
|
+
url: curlHandle.getInfo(Curl.info.REDIRECT_URL)?.toString() || fetchRequest.url,
|
141
|
+
redirected: Number(curlHandle.getInfo(Curl.info.REDIRECT_COUNT)) > 0,
|
146
142
|
});
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
else {
|
143
|
+
deferredPromise.resolve(ponyfillResponse);
|
144
|
+
streamResolved = outputStream;
|
145
|
+
});
|
146
|
+
let count = 0;
|
147
|
+
try {
|
148
|
+
count = Curl.getCount();
|
149
|
+
}
|
150
|
+
catch { }
|
151
|
+
if (count > 0) {
|
152
|
+
setImmediate(() => {
|
158
153
|
curlHandle.perform();
|
159
|
-
}
|
160
|
-
|
161
|
-
|
154
|
+
});
|
155
|
+
}
|
156
|
+
else {
|
157
|
+
curlHandle.perform();
|
158
|
+
}
|
159
|
+
return deferredPromise.promise;
|
162
160
|
}
|
package/esm/Request.js
CHANGED
package/esm/fetch.js
CHANGED
@@ -1,18 +1,44 @@
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
2
|
-
import { createReadStream } from 'node:fs';
|
2
|
+
import { createReadStream, promises as fsPromises } from 'node:fs';
|
3
3
|
import { fileURLToPath } from 'node:url';
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import { createFetchUndici } from './fetchUndici.js';
|
4
|
+
import { fetchCurl } from './fetchCurl.js';
|
5
|
+
import { fetchNodeHttp } from './fetchNodeHttp.js';
|
7
6
|
import { PonyfillRequest } from './Request.js';
|
8
7
|
import { PonyfillResponse } from './Response.js';
|
9
8
|
import { PonyfillURL } from './URL.js';
|
10
9
|
import { fakePromise } from './utils.js';
|
11
10
|
const BASE64_SUFFIX = ';base64';
|
12
|
-
function getResponseForFile(url) {
|
11
|
+
async function getResponseForFile(url) {
|
13
12
|
const path = fileURLToPath(url);
|
14
|
-
|
15
|
-
|
13
|
+
try {
|
14
|
+
const stats = await fsPromises.stat(path, {
|
15
|
+
bigint: true,
|
16
|
+
});
|
17
|
+
const readable = createReadStream(path);
|
18
|
+
return new PonyfillResponse(readable, {
|
19
|
+
status: 200,
|
20
|
+
statusText: 'OK',
|
21
|
+
headers: {
|
22
|
+
'content-type': 'application/octet-stream',
|
23
|
+
'last-modified': stats.mtime.toUTCString(),
|
24
|
+
},
|
25
|
+
});
|
26
|
+
}
|
27
|
+
catch (err) {
|
28
|
+
if (err.code === 'ENOENT') {
|
29
|
+
return new PonyfillResponse(null, {
|
30
|
+
status: 404,
|
31
|
+
statusText: 'Not Found',
|
32
|
+
});
|
33
|
+
}
|
34
|
+
else if (err.code === 'EACCES') {
|
35
|
+
return new PonyfillResponse(null, {
|
36
|
+
status: 403,
|
37
|
+
statusText: 'Forbidden',
|
38
|
+
});
|
39
|
+
}
|
40
|
+
throw err;
|
41
|
+
}
|
16
42
|
}
|
17
43
|
function getResponseForDataUri(url) {
|
18
44
|
const [mimeType = 'text/plain', ...datas] = url.substring(5).split(',');
|
@@ -52,75 +78,26 @@ function getResponseForBlob(url) {
|
|
52
78
|
function isURL(obj) {
|
53
79
|
return obj != null && obj.href != null;
|
54
80
|
}
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
return globalThis[Symbol.for('undici.globalDispatcher.1')];
|
60
|
-
}
|
61
|
-
function createFetchFn() {
|
62
|
-
const libcurlModuleName = 'node-libcurl';
|
63
|
-
const undiciModuleName = 'undici';
|
64
|
-
if (process.env.DEBUG) {
|
65
|
-
console.debug(`[@whatwg-node/node-fetch] - Trying to import ${libcurlModuleName} for fetch ponyfill`);
|
81
|
+
export function fetchPonyfill(info, init) {
|
82
|
+
if (typeof info === 'string' || isURL(info)) {
|
83
|
+
const ponyfillRequest = new PonyfillRequest(info, init);
|
84
|
+
return fetchPonyfill(ponyfillRequest);
|
66
85
|
}
|
67
|
-
|
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
|
-
});
|
78
|
-
}
|
79
|
-
function fetchNonHttp(fetchRequest) {
|
86
|
+
const fetchRequest = info;
|
80
87
|
if (fetchRequest.url.startsWith('data:')) {
|
81
88
|
const response = getResponseForDataUri(fetchRequest.url);
|
82
89
|
return fakePromise(response);
|
83
90
|
}
|
84
91
|
if (fetchRequest.url.startsWith('file:')) {
|
85
92
|
const response = getResponseForFile(fetchRequest.url);
|
86
|
-
return
|
93
|
+
return response;
|
87
94
|
}
|
88
95
|
if (fetchRequest.url.startsWith('blob:')) {
|
89
96
|
const response = getResponseForBlob(fetchRequest.url);
|
90
97
|
return fakePromise(response);
|
91
98
|
}
|
92
|
-
|
93
|
-
|
94
|
-
if (typeof info === 'string' || isURL(info)) {
|
95
|
-
return new PonyfillRequest(info, init);
|
96
|
-
}
|
97
|
-
return info;
|
98
|
-
}
|
99
|
-
export function createFetchPonyfill(fetchFn) {
|
100
|
-
return function fetchPonyfill(info, init) {
|
101
|
-
info = normalizeInfo(info, init);
|
102
|
-
const nonHttpRes = fetchNonHttp(info);
|
103
|
-
if (nonHttpRes) {
|
104
|
-
return nonHttpRes;
|
105
|
-
}
|
106
|
-
return fetchFn(info);
|
107
|
-
};
|
108
|
-
}
|
109
|
-
export function fetchPonyfill(info, init) {
|
110
|
-
info = normalizeInfo(info, init);
|
111
|
-
const nonHttpRes = fetchNonHttp(info);
|
112
|
-
if (nonHttpRes) {
|
113
|
-
return nonHttpRes;
|
114
|
-
}
|
115
|
-
if (!fetchFn) {
|
116
|
-
fetchFn$ ||= createFetchFn();
|
117
|
-
if (isPromise(fetchFn$)) {
|
118
|
-
return fetchFn$.then(newFetchFn => {
|
119
|
-
fetchFn = newFetchFn;
|
120
|
-
return fetchFn(info);
|
121
|
-
});
|
122
|
-
}
|
123
|
-
fetchFn = fetchFn$;
|
99
|
+
if (globalThis.libcurl && !fetchRequest.agent) {
|
100
|
+
return fetchCurl(fetchRequest);
|
124
101
|
}
|
125
|
-
return
|
102
|
+
return fetchNodeHttp(fetchRequest);
|
126
103
|
}
|