@whatwg-node/node-fetch 0.4.0 → 0.5.0-alpha-20230525150618-0ecd502
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/Blob.js +5 -2
- package/cjs/Body.js +20 -20
- package/cjs/File.js +1 -1
- package/cjs/FormData.js +6 -0
- package/cjs/ReadableStream.js +5 -9
- package/cjs/Request.js +12 -13
- package/cjs/Response.js +1 -1
- package/cjs/URL.js +2 -4
- package/cjs/fetch.js +54 -104
- package/esm/Blob.js +5 -2
- package/esm/Body.js +20 -20
- package/esm/File.js +1 -1
- package/esm/FormData.js +6 -0
- package/esm/ReadableStream.js +5 -9
- package/esm/Request.js +12 -13
- package/esm/Response.js +1 -1
- package/esm/URL.js +2 -4
- package/esm/fetch.js +54 -104
- package/package.json +3 -2
- package/typings/Blob.d.cts +1 -0
- package/typings/Blob.d.ts +1 -0
- package/typings/FormData.d.cts +2 -0
- package/typings/FormData.d.ts +2 -0
package/cjs/Blob.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"use strict";
|
2
|
+
var _a;
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
4
|
exports.PonyfillBlob = void 0;
|
4
5
|
const ReadableStream_js_1 = require("./ReadableStream.js");
|
@@ -28,8 +29,9 @@ function isBlob(obj) {
|
|
28
29
|
class PonyfillBlob {
|
29
30
|
constructor(blobParts, options) {
|
30
31
|
this.blobParts = blobParts;
|
31
|
-
this
|
32
|
-
this.
|
32
|
+
this[_a] = 'Blob';
|
33
|
+
this.type = options?.type || 'application/octet-stream';
|
34
|
+
this.encoding = options?.encoding || 'utf8';
|
33
35
|
}
|
34
36
|
async buffer() {
|
35
37
|
const bufferChunks = [];
|
@@ -117,3 +119,4 @@ class PonyfillBlob {
|
|
117
119
|
}
|
118
120
|
}
|
119
121
|
exports.PonyfillBlob = PonyfillBlob;
|
122
|
+
_a = Symbol.toStringTag;
|
package/cjs/Body.js
CHANGED
@@ -134,7 +134,7 @@ class PonyfillBody {
|
|
134
134
|
}
|
135
135
|
const formDataLimits = {
|
136
136
|
...this.options.formDataLimits,
|
137
|
-
...opts
|
137
|
+
...opts?.formDataLimits,
|
138
138
|
};
|
139
139
|
return new Promise((resolve, reject) => {
|
140
140
|
const bb = (0, busboy_1.default)({
|
@@ -146,37 +146,37 @@ class PonyfillBody {
|
|
146
146
|
});
|
147
147
|
bb.on('field', (name, value, { nameTruncated, valueTruncated }) => {
|
148
148
|
if (nameTruncated) {
|
149
|
-
reject(new Error(`Field name size exceeded: ${formDataLimits
|
149
|
+
reject(new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`));
|
150
150
|
}
|
151
151
|
if (valueTruncated) {
|
152
|
-
reject(new Error(`Field value size exceeded: ${formDataLimits
|
152
|
+
reject(new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`));
|
153
153
|
}
|
154
154
|
formData.set(name, value);
|
155
155
|
});
|
156
156
|
bb.on('fieldsLimit', () => {
|
157
|
-
reject(new Error(`Fields limit exceeded: ${formDataLimits
|
157
|
+
reject(new Error(`Fields limit exceeded: ${formDataLimits?.fields}`));
|
158
158
|
});
|
159
159
|
bb.on('file', (name, fileStream, { filename, mimeType }) => {
|
160
160
|
const chunks = [];
|
161
161
|
fileStream.on('limit', () => {
|
162
|
-
reject(new Error(`File size limit exceeded: ${formDataLimits
|
162
|
+
reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
163
163
|
});
|
164
164
|
fileStream.on('data', chunk => {
|
165
165
|
chunks.push(Buffer.from(chunk));
|
166
166
|
});
|
167
167
|
fileStream.on('close', () => {
|
168
168
|
if (fileStream.truncated) {
|
169
|
-
reject(new Error(`File size limit exceeded: ${formDataLimits
|
169
|
+
reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
170
170
|
}
|
171
171
|
const file = new File_js_1.PonyfillFile(chunks, filename, { type: mimeType });
|
172
172
|
formData.set(name, file);
|
173
173
|
});
|
174
174
|
});
|
175
175
|
bb.on('filesLimit', () => {
|
176
|
-
reject(new Error(`Files limit exceeded: ${formDataLimits
|
176
|
+
reject(new Error(`Files limit exceeded: ${formDataLimits?.files}`));
|
177
177
|
});
|
178
178
|
bb.on('partsLimit', () => {
|
179
|
-
reject(new Error(`Parts limit exceeded: ${formDataLimits
|
179
|
+
reject(new Error(`Parts limit exceeded: ${formDataLimits?.parts}`));
|
180
180
|
});
|
181
181
|
bb.on('close', () => {
|
182
182
|
resolve(formData);
|
@@ -184,7 +184,7 @@ class PonyfillBody {
|
|
184
184
|
bb.on('error', err => {
|
185
185
|
reject(err);
|
186
186
|
});
|
187
|
-
_body
|
187
|
+
_body?.readable.pipe(bb);
|
188
188
|
});
|
189
189
|
}
|
190
190
|
async buffer() {
|
@@ -324,17 +324,6 @@ function processBodyInit(bodyInit) {
|
|
324
324
|
},
|
325
325
|
};
|
326
326
|
}
|
327
|
-
if ('stream' in bodyInit) {
|
328
|
-
return {
|
329
|
-
contentType: bodyInit.type,
|
330
|
-
contentLength: bodyInit.size,
|
331
|
-
bodyFactory() {
|
332
|
-
const bodyStream = bodyInit.stream();
|
333
|
-
const body = new ReadableStream_js_1.PonyfillReadableStream(bodyStream);
|
334
|
-
return body;
|
335
|
-
},
|
336
|
-
};
|
337
|
-
}
|
338
327
|
if ('sort' in bodyInit) {
|
339
328
|
const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
|
340
329
|
return {
|
@@ -358,6 +347,17 @@ function processBodyInit(bodyInit) {
|
|
358
347
|
},
|
359
348
|
};
|
360
349
|
}
|
350
|
+
if ('stream' in bodyInit) {
|
351
|
+
return {
|
352
|
+
contentType: bodyInit.type,
|
353
|
+
contentLength: bodyInit.size,
|
354
|
+
bodyFactory() {
|
355
|
+
const bodyStream = bodyInit.stream();
|
356
|
+
const body = new ReadableStream_js_1.PonyfillReadableStream(bodyStream);
|
357
|
+
return body;
|
358
|
+
},
|
359
|
+
};
|
360
|
+
}
|
361
361
|
if (bodyInit[Symbol.iterator] || bodyInit[Symbol.asyncIterator]) {
|
362
362
|
return {
|
363
363
|
contentType: null,
|
package/cjs/File.js
CHANGED
@@ -7,7 +7,7 @@ class PonyfillFile extends Blob_js_1.PonyfillBlob {
|
|
7
7
|
super(fileBits, options);
|
8
8
|
this.name = name;
|
9
9
|
this.webkitRelativePath = '';
|
10
|
-
this.lastModified =
|
10
|
+
this.lastModified = options?.lastModified || Date.now();
|
11
11
|
}
|
12
12
|
}
|
13
13
|
exports.PonyfillFile = PonyfillFile;
|
package/cjs/FormData.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"use strict";
|
2
|
+
var _a;
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
4
|
exports.getStreamFromFormData = exports.PonyfillFormData = void 0;
|
4
5
|
const File_js_1 = require("./File.js");
|
@@ -6,6 +7,10 @@ const ReadableStream_js_1 = require("./ReadableStream.js");
|
|
6
7
|
class PonyfillFormData {
|
7
8
|
constructor() {
|
8
9
|
this.map = new Map();
|
10
|
+
this[_a] = 'FormData';
|
11
|
+
Object.defineProperty(this.constructor, 'name', {
|
12
|
+
value: 'FormData',
|
13
|
+
});
|
9
14
|
}
|
10
15
|
append(name, value, fileName) {
|
11
16
|
let values = this.map.get(name);
|
@@ -64,6 +69,7 @@ class PonyfillFormData {
|
|
64
69
|
}
|
65
70
|
}
|
66
71
|
exports.PonyfillFormData = PonyfillFormData;
|
72
|
+
_a = Symbol.toStringTag;
|
67
73
|
function getStreamFromFormData(formData, boundary = '---') {
|
68
74
|
const entries = [];
|
69
75
|
let sentInitialHeader = false;
|
package/cjs/ReadableStream.js
CHANGED
@@ -90,26 +90,24 @@ class PonyfillReadableStream {
|
|
90
90
|
}
|
91
91
|
ongoing = true;
|
92
92
|
return Promise.resolve().then(async () => {
|
93
|
-
var _a, _b;
|
94
93
|
if (!started) {
|
95
94
|
const controller = createController(desiredSize, this);
|
96
95
|
started = true;
|
97
|
-
await
|
96
|
+
await underlyingSource?.start?.(controller);
|
98
97
|
controller._flush();
|
99
98
|
if (controller._closed) {
|
100
99
|
return;
|
101
100
|
}
|
102
101
|
}
|
103
102
|
const controller = createController(desiredSize, this);
|
104
|
-
await
|
103
|
+
await underlyingSource?.pull?.(controller);
|
105
104
|
controller._flush();
|
106
105
|
ongoing = false;
|
107
106
|
});
|
108
107
|
},
|
109
108
|
async destroy(err, callback) {
|
110
|
-
var _a;
|
111
109
|
try {
|
112
|
-
await
|
110
|
+
await underlyingSource?.cancel?.(err);
|
113
111
|
callback(null);
|
114
112
|
}
|
115
113
|
catch (err) {
|
@@ -131,13 +129,11 @@ class PonyfillReadableStream {
|
|
131
129
|
return iterator.next();
|
132
130
|
},
|
133
131
|
releaseLock: () => {
|
134
|
-
|
135
|
-
(_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator);
|
132
|
+
iterator.return?.();
|
136
133
|
this.locked = false;
|
137
134
|
},
|
138
135
|
cancel: async (reason) => {
|
139
|
-
|
140
|
-
await ((_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator, reason));
|
136
|
+
await iterator.return?.(reason);
|
141
137
|
this.locked = false;
|
142
138
|
},
|
143
139
|
closed: new Promise((resolve, reject) => {
|
package/cjs/Request.js
CHANGED
@@ -9,7 +9,6 @@ function isRequest(input) {
|
|
9
9
|
}
|
10
10
|
class PonyfillRequest extends Body_js_1.PonyfillBody {
|
11
11
|
constructor(input, options) {
|
12
|
-
var _a;
|
13
12
|
let url;
|
14
13
|
let bodyInit = null;
|
15
14
|
let requestInit;
|
@@ -31,18 +30,18 @@ class PonyfillRequest extends Body_js_1.PonyfillBody {
|
|
31
30
|
super(bodyInit, options);
|
32
31
|
this.destination = '';
|
33
32
|
this.priority = 'auto';
|
34
|
-
this.cache =
|
35
|
-
this.credentials =
|
36
|
-
this.headers = new Headers_js_1.PonyfillHeaders(requestInit
|
37
|
-
this.integrity =
|
38
|
-
this.keepalive =
|
39
|
-
this.method =
|
40
|
-
this.mode =
|
41
|
-
this.redirect =
|
42
|
-
this.referrer =
|
43
|
-
this.referrerPolicy =
|
44
|
-
this.signal =
|
45
|
-
this.headersSerializer =
|
33
|
+
this.cache = requestInit?.cache || 'default';
|
34
|
+
this.credentials = requestInit?.credentials || 'same-origin';
|
35
|
+
this.headers = new Headers_js_1.PonyfillHeaders(requestInit?.headers);
|
36
|
+
this.integrity = requestInit?.integrity || '';
|
37
|
+
this.keepalive = requestInit?.keepalive != null ? requestInit?.keepalive : false;
|
38
|
+
this.method = requestInit?.method?.toUpperCase() || 'GET';
|
39
|
+
this.mode = requestInit?.mode || 'cors';
|
40
|
+
this.redirect = requestInit?.redirect || 'follow';
|
41
|
+
this.referrer = requestInit?.referrer || 'about:client';
|
42
|
+
this.referrerPolicy = requestInit?.referrerPolicy || 'no-referrer';
|
43
|
+
this.signal = requestInit?.signal || new AbortController().signal;
|
44
|
+
this.headersSerializer = requestInit?.headersSerializer || utils_js_1.getHeadersObj;
|
46
45
|
this.url = url || '';
|
47
46
|
const contentTypeInHeaders = this.headers.get('content-type');
|
48
47
|
if (!contentTypeInHeaders) {
|
package/cjs/Response.js
CHANGED
package/cjs/URL.js
CHANGED
@@ -32,15 +32,13 @@ class PonyfillURL extends fast_url_parser_1.default {
|
|
32
32
|
return this._searchParams;
|
33
33
|
}
|
34
34
|
get username() {
|
35
|
-
|
36
|
-
return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[0]) || '';
|
35
|
+
return this.auth?.split(':')[0] || '';
|
37
36
|
}
|
38
37
|
set username(value) {
|
39
38
|
this.auth = `${value}:${this.password}`;
|
40
39
|
}
|
41
40
|
get password() {
|
42
|
-
|
43
|
-
return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[1]) || '';
|
41
|
+
return this.auth?.split(':')[1] || '';
|
44
42
|
}
|
45
43
|
set password(value) {
|
46
44
|
this.auth = `${this.username}:${value}`;
|
package/cjs/fetch.js
CHANGED
@@ -2,12 +2,10 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.fetchPonyfill = void 0;
|
4
4
|
const fs_1 = require("fs");
|
5
|
-
const http_1 = require("http");
|
6
|
-
const https_1 = require("https");
|
7
5
|
const stream_1 = require("stream");
|
8
6
|
const url_1 = require("url");
|
9
7
|
const zlib_1 = require("zlib");
|
10
|
-
const
|
8
|
+
const undici_1 = require("undici");
|
11
9
|
const Blob_js_1 = require("./Blob.js");
|
12
10
|
const Request_js_1 = require("./Request.js");
|
13
11
|
const Response_js_1 = require("./Response.js");
|
@@ -38,113 +36,65 @@ function getResponseForDataUri(url) {
|
|
38
36
|
},
|
39
37
|
});
|
40
38
|
}
|
41
|
-
function getRequestFnForProtocol(protocol) {
|
42
|
-
switch (protocol) {
|
43
|
-
case 'http:':
|
44
|
-
return http_1.request;
|
45
|
-
case 'https:':
|
46
|
-
return https_1.request;
|
47
|
-
}
|
48
|
-
throw new Error(`Unsupported protocol: ${protocol}`);
|
49
|
-
}
|
50
39
|
const BASE64_SUFFIX = ';base64';
|
51
|
-
function fetchPonyfill(info, init) {
|
40
|
+
async function fetchPonyfill(info, init) {
|
52
41
|
if (typeof info === 'string' || 'href' in info) {
|
53
42
|
const ponyfillRequest = new Request_js_1.PonyfillRequest(info, init);
|
54
43
|
return fetchPonyfill(ponyfillRequest);
|
55
44
|
}
|
56
45
|
const fetchRequest = info;
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
108
|
-
break;
|
109
|
-
}
|
110
|
-
if (nodeResponse.headers.location) {
|
111
|
-
if (fetchRequest.redirect === 'error') {
|
112
|
-
const redirectError = new Error('Redirects are not allowed');
|
113
|
-
reject(redirectError);
|
114
|
-
nodeResponse.resume();
|
115
|
-
return;
|
116
|
-
}
|
117
|
-
if (fetchRequest.redirect === 'follow') {
|
118
|
-
const redirectedUrl = new URL_js_1.PonyfillURL(nodeResponse.headers.location, url);
|
119
|
-
const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
|
120
|
-
resolve(redirectResponse$.then(redirectResponse => {
|
121
|
-
redirectResponse.redirected = true;
|
122
|
-
return redirectResponse;
|
123
|
-
}));
|
124
|
-
nodeResponse.resume();
|
125
|
-
return;
|
126
|
-
}
|
127
|
-
}
|
128
|
-
const responseHeaders = nodeResponse.headers;
|
129
|
-
const ponyfillResponse = new Response_js_1.PonyfillResponse(responseBody, {
|
130
|
-
status: nodeResponse.statusCode,
|
131
|
-
statusText: nodeResponse.statusMessage,
|
132
|
-
headers: responseHeaders,
|
133
|
-
url: info.url,
|
134
|
-
});
|
135
|
-
resolve(ponyfillResponse);
|
136
|
-
});
|
137
|
-
nodeRequest.once('error', reject);
|
138
|
-
if (nodeReadable) {
|
139
|
-
nodeReadable.pipe(nodeRequest);
|
140
|
-
}
|
141
|
-
else {
|
142
|
-
nodeRequest.end();
|
143
|
-
}
|
144
|
-
}
|
145
|
-
catch (e) {
|
146
|
-
reject(e);
|
147
|
-
}
|
46
|
+
const url = new URL_js_1.PonyfillURL(fetchRequest.url, 'http://localhost');
|
47
|
+
if (url.protocol === 'data:') {
|
48
|
+
const response = getResponseForDataUri(url);
|
49
|
+
return response;
|
50
|
+
}
|
51
|
+
if (url.protocol === 'file:') {
|
52
|
+
const response = getResponseForFile(fetchRequest.url);
|
53
|
+
return response;
|
54
|
+
}
|
55
|
+
const requestBody = (fetchRequest['bodyInit'] != null
|
56
|
+
? fetchRequest['bodyInit']
|
57
|
+
: fetchRequest.body != null
|
58
|
+
? 'pipe' in fetchRequest.body
|
59
|
+
? fetchRequest.body
|
60
|
+
: stream_1.Readable.from(fetchRequest.body)
|
61
|
+
: null);
|
62
|
+
const headersSerializer = fetchRequest.headersSerializer || utils_js_1.getHeadersObj;
|
63
|
+
const nodeHeaders = headersSerializer(fetchRequest.headers);
|
64
|
+
if (requestBody?.[Symbol.toStringTag] === 'FormData') {
|
65
|
+
delete nodeHeaders['content-type'];
|
66
|
+
}
|
67
|
+
const undiciData = await (0, undici_1.request)(fetchRequest.url, {
|
68
|
+
method: fetchRequest.method,
|
69
|
+
headers: nodeHeaders,
|
70
|
+
body: requestBody,
|
71
|
+
signal: fetchRequest.signal,
|
72
|
+
maxRedirections: fetchRequest.redirect === 'follow' ? 20 : 0,
|
73
|
+
});
|
74
|
+
if (fetchRequest.redirect === 'error' && undiciData.headers.location) {
|
75
|
+
const redirectError = new Error('Redirects are not allowed');
|
76
|
+
throw redirectError;
|
77
|
+
}
|
78
|
+
let responseBody = undiciData.body;
|
79
|
+
const contentEncoding = undiciData.headers['content-encoding'];
|
80
|
+
switch (contentEncoding) {
|
81
|
+
case 'x-gzip':
|
82
|
+
case 'gzip':
|
83
|
+
responseBody = responseBody.pipe((0, zlib_1.createGunzip)());
|
84
|
+
break;
|
85
|
+
case 'x-deflate':
|
86
|
+
case 'deflate':
|
87
|
+
responseBody = responseBody.pipe((0, zlib_1.createInflate)());
|
88
|
+
break;
|
89
|
+
case 'br':
|
90
|
+
responseBody = responseBody.pipe((0, zlib_1.createBrotliDecompress)());
|
91
|
+
break;
|
92
|
+
}
|
93
|
+
const ponyfillResponse = new Response_js_1.PonyfillResponse(responseBody, {
|
94
|
+
status: undiciData.statusCode,
|
95
|
+
headers: undiciData.headers,
|
96
|
+
url: fetchRequest.url,
|
148
97
|
});
|
98
|
+
return ponyfillResponse;
|
149
99
|
}
|
150
100
|
exports.fetchPonyfill = fetchPonyfill;
|
package/esm/Blob.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
var _a;
|
1
2
|
import { PonyfillReadableStream } from './ReadableStream.js';
|
2
3
|
import { uint8ArrayToArrayBuffer } from './utils.js';
|
3
4
|
function getBlobPartAsBuffer(blobPart) {
|
@@ -25,8 +26,9 @@ function isBlob(obj) {
|
|
25
26
|
export class PonyfillBlob {
|
26
27
|
constructor(blobParts, options) {
|
27
28
|
this.blobParts = blobParts;
|
28
|
-
this
|
29
|
-
this.
|
29
|
+
this[_a] = 'Blob';
|
30
|
+
this.type = options?.type || 'application/octet-stream';
|
31
|
+
this.encoding = options?.encoding || 'utf8';
|
30
32
|
}
|
31
33
|
async buffer() {
|
32
34
|
const bufferChunks = [];
|
@@ -113,3 +115,4 @@ export class PonyfillBlob {
|
|
113
115
|
throw new Error('Not implemented');
|
114
116
|
}
|
115
117
|
}
|
118
|
+
_a = Symbol.toStringTag;
|
package/esm/Body.js
CHANGED
@@ -130,7 +130,7 @@ export class PonyfillBody {
|
|
130
130
|
}
|
131
131
|
const formDataLimits = {
|
132
132
|
...this.options.formDataLimits,
|
133
|
-
...opts
|
133
|
+
...opts?.formDataLimits,
|
134
134
|
};
|
135
135
|
return new Promise((resolve, reject) => {
|
136
136
|
const bb = busboy({
|
@@ -142,37 +142,37 @@ export class PonyfillBody {
|
|
142
142
|
});
|
143
143
|
bb.on('field', (name, value, { nameTruncated, valueTruncated }) => {
|
144
144
|
if (nameTruncated) {
|
145
|
-
reject(new Error(`Field name size exceeded: ${formDataLimits
|
145
|
+
reject(new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`));
|
146
146
|
}
|
147
147
|
if (valueTruncated) {
|
148
|
-
reject(new Error(`Field value size exceeded: ${formDataLimits
|
148
|
+
reject(new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`));
|
149
149
|
}
|
150
150
|
formData.set(name, value);
|
151
151
|
});
|
152
152
|
bb.on('fieldsLimit', () => {
|
153
|
-
reject(new Error(`Fields limit exceeded: ${formDataLimits
|
153
|
+
reject(new Error(`Fields limit exceeded: ${formDataLimits?.fields}`));
|
154
154
|
});
|
155
155
|
bb.on('file', (name, fileStream, { filename, mimeType }) => {
|
156
156
|
const chunks = [];
|
157
157
|
fileStream.on('limit', () => {
|
158
|
-
reject(new Error(`File size limit exceeded: ${formDataLimits
|
158
|
+
reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
159
159
|
});
|
160
160
|
fileStream.on('data', chunk => {
|
161
161
|
chunks.push(Buffer.from(chunk));
|
162
162
|
});
|
163
163
|
fileStream.on('close', () => {
|
164
164
|
if (fileStream.truncated) {
|
165
|
-
reject(new Error(`File size limit exceeded: ${formDataLimits
|
165
|
+
reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
166
166
|
}
|
167
167
|
const file = new PonyfillFile(chunks, filename, { type: mimeType });
|
168
168
|
formData.set(name, file);
|
169
169
|
});
|
170
170
|
});
|
171
171
|
bb.on('filesLimit', () => {
|
172
|
-
reject(new Error(`Files limit exceeded: ${formDataLimits
|
172
|
+
reject(new Error(`Files limit exceeded: ${formDataLimits?.files}`));
|
173
173
|
});
|
174
174
|
bb.on('partsLimit', () => {
|
175
|
-
reject(new Error(`Parts limit exceeded: ${formDataLimits
|
175
|
+
reject(new Error(`Parts limit exceeded: ${formDataLimits?.parts}`));
|
176
176
|
});
|
177
177
|
bb.on('close', () => {
|
178
178
|
resolve(formData);
|
@@ -180,7 +180,7 @@ export class PonyfillBody {
|
|
180
180
|
bb.on('error', err => {
|
181
181
|
reject(err);
|
182
182
|
});
|
183
|
-
_body
|
183
|
+
_body?.readable.pipe(bb);
|
184
184
|
});
|
185
185
|
}
|
186
186
|
async buffer() {
|
@@ -319,17 +319,6 @@ function processBodyInit(bodyInit) {
|
|
319
319
|
},
|
320
320
|
};
|
321
321
|
}
|
322
|
-
if ('stream' in bodyInit) {
|
323
|
-
return {
|
324
|
-
contentType: bodyInit.type,
|
325
|
-
contentLength: bodyInit.size,
|
326
|
-
bodyFactory() {
|
327
|
-
const bodyStream = bodyInit.stream();
|
328
|
-
const body = new PonyfillReadableStream(bodyStream);
|
329
|
-
return body;
|
330
|
-
},
|
331
|
-
};
|
332
|
-
}
|
333
322
|
if ('sort' in bodyInit) {
|
334
323
|
const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
|
335
324
|
return {
|
@@ -353,6 +342,17 @@ function processBodyInit(bodyInit) {
|
|
353
342
|
},
|
354
343
|
};
|
355
344
|
}
|
345
|
+
if ('stream' in bodyInit) {
|
346
|
+
return {
|
347
|
+
contentType: bodyInit.type,
|
348
|
+
contentLength: bodyInit.size,
|
349
|
+
bodyFactory() {
|
350
|
+
const bodyStream = bodyInit.stream();
|
351
|
+
const body = new PonyfillReadableStream(bodyStream);
|
352
|
+
return body;
|
353
|
+
},
|
354
|
+
};
|
355
|
+
}
|
356
356
|
if (bodyInit[Symbol.iterator] || bodyInit[Symbol.asyncIterator]) {
|
357
357
|
return {
|
358
358
|
contentType: null,
|
package/esm/File.js
CHANGED
@@ -4,6 +4,6 @@ export class PonyfillFile extends PonyfillBlob {
|
|
4
4
|
super(fileBits, options);
|
5
5
|
this.name = name;
|
6
6
|
this.webkitRelativePath = '';
|
7
|
-
this.lastModified =
|
7
|
+
this.lastModified = options?.lastModified || Date.now();
|
8
8
|
}
|
9
9
|
}
|
package/esm/FormData.js
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
+
var _a;
|
1
2
|
import { PonyfillFile } from './File.js';
|
2
3
|
import { PonyfillReadableStream } from './ReadableStream.js';
|
3
4
|
export class PonyfillFormData {
|
4
5
|
constructor() {
|
5
6
|
this.map = new Map();
|
7
|
+
this[_a] = 'FormData';
|
8
|
+
Object.defineProperty(this.constructor, 'name', {
|
9
|
+
value: 'FormData',
|
10
|
+
});
|
6
11
|
}
|
7
12
|
append(name, value, fileName) {
|
8
13
|
let values = this.map.get(name);
|
@@ -60,6 +65,7 @@ export class PonyfillFormData {
|
|
60
65
|
}
|
61
66
|
}
|
62
67
|
}
|
68
|
+
_a = Symbol.toStringTag;
|
63
69
|
export function getStreamFromFormData(formData, boundary = '---') {
|
64
70
|
const entries = [];
|
65
71
|
let sentInitialHeader = false;
|
package/esm/ReadableStream.js
CHANGED
@@ -87,26 +87,24 @@ export class PonyfillReadableStream {
|
|
87
87
|
}
|
88
88
|
ongoing = true;
|
89
89
|
return Promise.resolve().then(async () => {
|
90
|
-
var _a, _b;
|
91
90
|
if (!started) {
|
92
91
|
const controller = createController(desiredSize, this);
|
93
92
|
started = true;
|
94
|
-
await
|
93
|
+
await underlyingSource?.start?.(controller);
|
95
94
|
controller._flush();
|
96
95
|
if (controller._closed) {
|
97
96
|
return;
|
98
97
|
}
|
99
98
|
}
|
100
99
|
const controller = createController(desiredSize, this);
|
101
|
-
await
|
100
|
+
await underlyingSource?.pull?.(controller);
|
102
101
|
controller._flush();
|
103
102
|
ongoing = false;
|
104
103
|
});
|
105
104
|
},
|
106
105
|
async destroy(err, callback) {
|
107
|
-
var _a;
|
108
106
|
try {
|
109
|
-
await
|
107
|
+
await underlyingSource?.cancel?.(err);
|
110
108
|
callback(null);
|
111
109
|
}
|
112
110
|
catch (err) {
|
@@ -128,13 +126,11 @@ export class PonyfillReadableStream {
|
|
128
126
|
return iterator.next();
|
129
127
|
},
|
130
128
|
releaseLock: () => {
|
131
|
-
|
132
|
-
(_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator);
|
129
|
+
iterator.return?.();
|
133
130
|
this.locked = false;
|
134
131
|
},
|
135
132
|
cancel: async (reason) => {
|
136
|
-
|
137
|
-
await ((_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator, reason));
|
133
|
+
await iterator.return?.(reason);
|
138
134
|
this.locked = false;
|
139
135
|
},
|
140
136
|
closed: new Promise((resolve, reject) => {
|
package/esm/Request.js
CHANGED
@@ -6,7 +6,6 @@ function isRequest(input) {
|
|
6
6
|
}
|
7
7
|
export class PonyfillRequest extends PonyfillBody {
|
8
8
|
constructor(input, options) {
|
9
|
-
var _a;
|
10
9
|
let url;
|
11
10
|
let bodyInit = null;
|
12
11
|
let requestInit;
|
@@ -28,18 +27,18 @@ export class PonyfillRequest extends PonyfillBody {
|
|
28
27
|
super(bodyInit, options);
|
29
28
|
this.destination = '';
|
30
29
|
this.priority = 'auto';
|
31
|
-
this.cache =
|
32
|
-
this.credentials =
|
33
|
-
this.headers = new PonyfillHeaders(requestInit
|
34
|
-
this.integrity =
|
35
|
-
this.keepalive =
|
36
|
-
this.method =
|
37
|
-
this.mode =
|
38
|
-
this.redirect =
|
39
|
-
this.referrer =
|
40
|
-
this.referrerPolicy =
|
41
|
-
this.signal =
|
42
|
-
this.headersSerializer =
|
30
|
+
this.cache = requestInit?.cache || 'default';
|
31
|
+
this.credentials = requestInit?.credentials || 'same-origin';
|
32
|
+
this.headers = new PonyfillHeaders(requestInit?.headers);
|
33
|
+
this.integrity = requestInit?.integrity || '';
|
34
|
+
this.keepalive = requestInit?.keepalive != null ? requestInit?.keepalive : false;
|
35
|
+
this.method = requestInit?.method?.toUpperCase() || 'GET';
|
36
|
+
this.mode = requestInit?.mode || 'cors';
|
37
|
+
this.redirect = requestInit?.redirect || 'follow';
|
38
|
+
this.referrer = requestInit?.referrer || 'about:client';
|
39
|
+
this.referrerPolicy = requestInit?.referrerPolicy || 'no-referrer';
|
40
|
+
this.signal = requestInit?.signal || new AbortController().signal;
|
41
|
+
this.headersSerializer = requestInit?.headersSerializer || getHeadersObj;
|
43
42
|
this.url = url || '';
|
44
43
|
const contentTypeInHeaders = this.headers.get('content-type');
|
45
44
|
if (!contentTypeInHeaders) {
|
package/esm/Response.js
CHANGED
package/esm/URL.js
CHANGED
@@ -28,15 +28,13 @@ export class PonyfillURL extends FastUrl {
|
|
28
28
|
return this._searchParams;
|
29
29
|
}
|
30
30
|
get username() {
|
31
|
-
|
32
|
-
return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[0]) || '';
|
31
|
+
return this.auth?.split(':')[0] || '';
|
33
32
|
}
|
34
33
|
set username(value) {
|
35
34
|
this.auth = `${value}:${this.password}`;
|
36
35
|
}
|
37
36
|
get password() {
|
38
|
-
|
39
|
-
return ((_a = this.auth) === null || _a === void 0 ? void 0 : _a.split(':')[1]) || '';
|
37
|
+
return this.auth?.split(':')[1] || '';
|
40
38
|
}
|
41
39
|
set password(value) {
|
42
40
|
this.auth = `${this.username}:${value}`;
|
package/esm/fetch.js
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
import { createReadStream } from 'fs';
|
2
|
-
import { request as httpRequest } from 'http';
|
3
|
-
import { request as httpsRequest } from 'https';
|
4
2
|
import { Readable } from 'stream';
|
5
3
|
import { fileURLToPath } from 'url';
|
6
4
|
import { createBrotliDecompress, createGunzip, createInflate } from 'zlib';
|
7
|
-
import {
|
5
|
+
import { request } from 'undici';
|
8
6
|
import { PonyfillBlob } from './Blob.js';
|
9
7
|
import { PonyfillRequest } from './Request.js';
|
10
8
|
import { PonyfillResponse } from './Response.js';
|
@@ -35,112 +33,64 @@ function getResponseForDataUri(url) {
|
|
35
33
|
},
|
36
34
|
});
|
37
35
|
}
|
38
|
-
function getRequestFnForProtocol(protocol) {
|
39
|
-
switch (protocol) {
|
40
|
-
case 'http:':
|
41
|
-
return httpRequest;
|
42
|
-
case 'https:':
|
43
|
-
return httpsRequest;
|
44
|
-
}
|
45
|
-
throw new Error(`Unsupported protocol: ${protocol}`);
|
46
|
-
}
|
47
36
|
const BASE64_SUFFIX = ';base64';
|
48
|
-
export function fetchPonyfill(info, init) {
|
37
|
+
export async function fetchPonyfill(info, init) {
|
49
38
|
if (typeof info === 'string' || 'href' in info) {
|
50
39
|
const ponyfillRequest = new PonyfillRequest(info, init);
|
51
40
|
return fetchPonyfill(ponyfillRequest);
|
52
41
|
}
|
53
42
|
const fetchRequest = info;
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
break;
|
106
|
-
}
|
107
|
-
if (nodeResponse.headers.location) {
|
108
|
-
if (fetchRequest.redirect === 'error') {
|
109
|
-
const redirectError = new Error('Redirects are not allowed');
|
110
|
-
reject(redirectError);
|
111
|
-
nodeResponse.resume();
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
if (fetchRequest.redirect === 'follow') {
|
115
|
-
const redirectedUrl = new PonyfillURL(nodeResponse.headers.location, url);
|
116
|
-
const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
|
117
|
-
resolve(redirectResponse$.then(redirectResponse => {
|
118
|
-
redirectResponse.redirected = true;
|
119
|
-
return redirectResponse;
|
120
|
-
}));
|
121
|
-
nodeResponse.resume();
|
122
|
-
return;
|
123
|
-
}
|
124
|
-
}
|
125
|
-
const responseHeaders = nodeResponse.headers;
|
126
|
-
const ponyfillResponse = new PonyfillResponse(responseBody, {
|
127
|
-
status: nodeResponse.statusCode,
|
128
|
-
statusText: nodeResponse.statusMessage,
|
129
|
-
headers: responseHeaders,
|
130
|
-
url: info.url,
|
131
|
-
});
|
132
|
-
resolve(ponyfillResponse);
|
133
|
-
});
|
134
|
-
nodeRequest.once('error', reject);
|
135
|
-
if (nodeReadable) {
|
136
|
-
nodeReadable.pipe(nodeRequest);
|
137
|
-
}
|
138
|
-
else {
|
139
|
-
nodeRequest.end();
|
140
|
-
}
|
141
|
-
}
|
142
|
-
catch (e) {
|
143
|
-
reject(e);
|
144
|
-
}
|
43
|
+
const url = new PonyfillURL(fetchRequest.url, 'http://localhost');
|
44
|
+
if (url.protocol === 'data:') {
|
45
|
+
const response = getResponseForDataUri(url);
|
46
|
+
return response;
|
47
|
+
}
|
48
|
+
if (url.protocol === 'file:') {
|
49
|
+
const response = getResponseForFile(fetchRequest.url);
|
50
|
+
return response;
|
51
|
+
}
|
52
|
+
const requestBody = (fetchRequest['bodyInit'] != null
|
53
|
+
? fetchRequest['bodyInit']
|
54
|
+
: fetchRequest.body != null
|
55
|
+
? 'pipe' in fetchRequest.body
|
56
|
+
? fetchRequest.body
|
57
|
+
: Readable.from(fetchRequest.body)
|
58
|
+
: null);
|
59
|
+
const headersSerializer = fetchRequest.headersSerializer || getHeadersObj;
|
60
|
+
const nodeHeaders = headersSerializer(fetchRequest.headers);
|
61
|
+
if (requestBody?.[Symbol.toStringTag] === 'FormData') {
|
62
|
+
delete nodeHeaders['content-type'];
|
63
|
+
}
|
64
|
+
const undiciData = await request(fetchRequest.url, {
|
65
|
+
method: fetchRequest.method,
|
66
|
+
headers: nodeHeaders,
|
67
|
+
body: requestBody,
|
68
|
+
signal: fetchRequest.signal,
|
69
|
+
maxRedirections: fetchRequest.redirect === 'follow' ? 20 : 0,
|
70
|
+
});
|
71
|
+
if (fetchRequest.redirect === 'error' && undiciData.headers.location) {
|
72
|
+
const redirectError = new Error('Redirects are not allowed');
|
73
|
+
throw redirectError;
|
74
|
+
}
|
75
|
+
let responseBody = undiciData.body;
|
76
|
+
const contentEncoding = undiciData.headers['content-encoding'];
|
77
|
+
switch (contentEncoding) {
|
78
|
+
case 'x-gzip':
|
79
|
+
case 'gzip':
|
80
|
+
responseBody = responseBody.pipe(createGunzip());
|
81
|
+
break;
|
82
|
+
case 'x-deflate':
|
83
|
+
case 'deflate':
|
84
|
+
responseBody = responseBody.pipe(createInflate());
|
85
|
+
break;
|
86
|
+
case 'br':
|
87
|
+
responseBody = responseBody.pipe(createBrotliDecompress());
|
88
|
+
break;
|
89
|
+
}
|
90
|
+
const ponyfillResponse = new PonyfillResponse(responseBody, {
|
91
|
+
status: undiciData.statusCode,
|
92
|
+
headers: undiciData.headers,
|
93
|
+
url: fetchRequest.url,
|
145
94
|
});
|
95
|
+
return ponyfillResponse;
|
146
96
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@whatwg-node/node-fetch",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.0-alpha-20230525150618-0ecd502",
|
4
4
|
"description": "Fetch API implementation for Node",
|
5
5
|
"sideEffects": false,
|
6
6
|
"dependencies": {
|
@@ -8,7 +8,8 @@
|
|
8
8
|
"busboy": "^1.6.0",
|
9
9
|
"fast-querystring": "^1.1.1",
|
10
10
|
"fast-url-parser": "^1.1.3",
|
11
|
-
"tslib": "^2.3.1"
|
11
|
+
"tslib": "^2.3.1",
|
12
|
+
"undici": "^5.22.1"
|
12
13
|
},
|
13
14
|
"repository": {
|
14
15
|
"type": "git",
|
package/typings/Blob.d.cts
CHANGED
package/typings/Blob.d.ts
CHANGED
package/typings/FormData.d.cts
CHANGED
@@ -2,6 +2,7 @@ import { PonyfillBlob } from './Blob.cjs';
|
|
2
2
|
import { PonyfillReadableStream } from './ReadableStream.cjs';
|
3
3
|
export declare class PonyfillFormData implements FormData {
|
4
4
|
private map;
|
5
|
+
constructor();
|
5
6
|
append(name: string, value: PonyfillBlob | string, fileName?: string): void;
|
6
7
|
delete(name: string): void;
|
7
8
|
get(name: string): FormDataEntryValue | null;
|
@@ -13,5 +14,6 @@ export declare class PonyfillFormData implements FormData {
|
|
13
14
|
keys(): IterableIterator<string>;
|
14
15
|
values(): IterableIterator<FormDataEntryValue>;
|
15
16
|
forEach(callback: (value: FormDataEntryValue, key: string, parent: this) => void): void;
|
17
|
+
[Symbol.toStringTag]: string;
|
16
18
|
}
|
17
19
|
export declare function getStreamFromFormData(formData: FormData, boundary?: string): PonyfillReadableStream<Uint8Array>;
|
package/typings/FormData.d.ts
CHANGED
@@ -2,6 +2,7 @@ import { PonyfillBlob } from './Blob.js';
|
|
2
2
|
import { PonyfillReadableStream } from './ReadableStream.js';
|
3
3
|
export declare class PonyfillFormData implements FormData {
|
4
4
|
private map;
|
5
|
+
constructor();
|
5
6
|
append(name: string, value: PonyfillBlob | string, fileName?: string): void;
|
6
7
|
delete(name: string): void;
|
7
8
|
get(name: string): FormDataEntryValue | null;
|
@@ -13,5 +14,6 @@ export declare class PonyfillFormData implements FormData {
|
|
13
14
|
keys(): IterableIterator<string>;
|
14
15
|
values(): IterableIterator<FormDataEntryValue>;
|
15
16
|
forEach(callback: (value: FormDataEntryValue, key: string, parent: this) => void): void;
|
17
|
+
[Symbol.toStringTag]: string;
|
16
18
|
}
|
17
19
|
export declare function getStreamFromFormData(formData: FormData, boundary?: string): PonyfillReadableStream<Uint8Array>;
|