@whatwg-node/node-fetch 0.7.17 → 0.7.18-alpha-20250414141945-85ba4bb116008ce30707b20368f44d791a52afaa
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/Body.js +55 -27
- package/esm/Body.js +55 -26
- package/package.json +3 -3
package/cjs/Body.js
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.PonyfillBody = void 0;
|
4
|
-
const tslib_1 = require("tslib");
|
5
4
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
6
5
|
const node_buffer_1 = require("node:buffer");
|
7
6
|
const node_http_1 = require("node:http");
|
8
7
|
const node_stream_1 = require("node:stream");
|
9
|
-
const busboy_1 =
|
8
|
+
const busboy_1 = require("@fastify/busboy");
|
10
9
|
const promise_helpers_1 = require("@whatwg-node/promise-helpers");
|
11
10
|
const Blob_js_1 = require("./Blob.js");
|
12
11
|
const File_js_1 = require("./File.js");
|
@@ -189,56 +188,85 @@ class PonyfillBody {
|
|
189
188
|
...opts?.formDataLimits,
|
190
189
|
};
|
191
190
|
return new Promise((resolve, reject) => {
|
192
|
-
const
|
191
|
+
const stream = this.body?.readable;
|
192
|
+
if (!stream) {
|
193
|
+
return reject(new Error('No stream available'));
|
194
|
+
}
|
195
|
+
let lastError;
|
196
|
+
// form data file that is currently being processed, it's
|
197
|
+
// important to keep track of it in case the stream ends early
|
198
|
+
let currFile = null;
|
199
|
+
const bb = new busboy_1.Busboy({
|
193
200
|
headers: {
|
201
|
+
'content-length': typeof this.contentLength === 'number'
|
202
|
+
? this.contentLength.toString()
|
203
|
+
: this.contentLength || '',
|
194
204
|
'content-type': this.contentType || '',
|
195
205
|
},
|
196
206
|
limits: formDataLimits,
|
197
|
-
|
207
|
+
defCharset: 'utf-8',
|
198
208
|
});
|
199
|
-
|
200
|
-
|
201
|
-
|
209
|
+
const complete = (err) => {
|
210
|
+
stream.unpipe(bb);
|
211
|
+
bb.destroy();
|
212
|
+
if (currFile) {
|
213
|
+
currFile.destroy();
|
214
|
+
currFile = null;
|
215
|
+
}
|
216
|
+
if (err || lastError) {
|
217
|
+
reject(err || lastError);
|
218
|
+
}
|
219
|
+
else {
|
220
|
+
// no error occured, this is a successful end/complete/finish
|
221
|
+
resolve(this._formData);
|
222
|
+
}
|
223
|
+
};
|
224
|
+
// we dont need to listen to the stream close event because bb will close or error when necessary
|
225
|
+
// stream.on('close', complete);
|
226
|
+
// stream can be aborted, for example
|
227
|
+
stream.on('error', complete);
|
228
|
+
bb.on('field', (name, value, fieldnameTruncated, valueTruncated) => {
|
229
|
+
if (fieldnameTruncated) {
|
230
|
+
return complete(new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`));
|
202
231
|
}
|
203
232
|
if (valueTruncated) {
|
204
|
-
|
233
|
+
return complete(new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`));
|
205
234
|
}
|
206
235
|
this._formData.set(name, value);
|
207
236
|
});
|
208
|
-
bb.on('
|
209
|
-
|
210
|
-
});
|
211
|
-
bb.on('file', (name, fileStream, { filename, mimeType }) => {
|
237
|
+
bb.on('file', (name, fileStream, filename, _transferEncoding, mimeType) => {
|
238
|
+
currFile = fileStream;
|
212
239
|
const chunks = [];
|
213
|
-
fileStream.on('limit', () => {
|
214
|
-
reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
215
|
-
});
|
216
240
|
fileStream.on('data', chunk => {
|
217
241
|
chunks.push(chunk);
|
218
242
|
});
|
243
|
+
fileStream.on('error', complete);
|
244
|
+
fileStream.on('limit', () => {
|
245
|
+
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
246
|
+
});
|
219
247
|
fileStream.on('close', () => {
|
220
248
|
if (fileStream.truncated) {
|
221
|
-
|
249
|
+
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
222
250
|
}
|
251
|
+
currFile = null;
|
223
252
|
const file = new File_js_1.PonyfillFile(chunks, filename, { type: mimeType });
|
224
253
|
this._formData.set(name, file);
|
225
254
|
});
|
226
255
|
});
|
256
|
+
bb.on('fieldsLimit', () => {
|
257
|
+
complete(new Error(`Fields limit exceeded: ${formDataLimits?.fields}`));
|
258
|
+
});
|
227
259
|
bb.on('filesLimit', () => {
|
228
|
-
|
260
|
+
complete(new Error(`Files limit exceeded: ${formDataLimits?.files}`));
|
229
261
|
});
|
230
262
|
bb.on('partsLimit', () => {
|
231
|
-
|
232
|
-
});
|
233
|
-
bb.on('close', () => {
|
234
|
-
resolve(this._formData);
|
235
|
-
});
|
236
|
-
bb.on('error', (err = 'An error occurred while parsing the form data') => {
|
237
|
-
const errMessage = err.message || err.toString();
|
238
|
-
// @ts-ignore - `cause` is in `TypeError`in node
|
239
|
-
reject(new TypeError(errMessage, err.cause));
|
263
|
+
complete(new Error(`Parts limit exceeded: ${formDataLimits?.parts}`));
|
240
264
|
});
|
241
|
-
|
265
|
+
bb.on('end', complete);
|
266
|
+
bb.on('finish', complete);
|
267
|
+
bb.on('close', complete);
|
268
|
+
bb.on('error', complete);
|
269
|
+
stream.pipe(bb);
|
242
270
|
});
|
243
271
|
}
|
244
272
|
buffer() {
|
package/esm/Body.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
import { Buffer } from 'node:buffer';
|
3
3
|
import { IncomingMessage } from 'node:http';
|
4
4
|
import { Readable } from 'node:stream';
|
5
|
-
import
|
5
|
+
import { Busboy } from '@fastify/busboy';
|
6
6
|
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
|
7
7
|
import { hasArrayBufferMethod, hasBufferMethod, hasBytesMethod, PonyfillBlob } from './Blob.js';
|
8
8
|
import { PonyfillFile } from './File.js';
|
@@ -185,56 +185,85 @@ export class PonyfillBody {
|
|
185
185
|
...opts?.formDataLimits,
|
186
186
|
};
|
187
187
|
return new Promise((resolve, reject) => {
|
188
|
-
const
|
188
|
+
const stream = this.body?.readable;
|
189
|
+
if (!stream) {
|
190
|
+
return reject(new Error('No stream available'));
|
191
|
+
}
|
192
|
+
let lastError;
|
193
|
+
// form data file that is currently being processed, it's
|
194
|
+
// important to keep track of it in case the stream ends early
|
195
|
+
let currFile = null;
|
196
|
+
const bb = new Busboy({
|
189
197
|
headers: {
|
198
|
+
'content-length': typeof this.contentLength === 'number'
|
199
|
+
? this.contentLength.toString()
|
200
|
+
: this.contentLength || '',
|
190
201
|
'content-type': this.contentType || '',
|
191
202
|
},
|
192
203
|
limits: formDataLimits,
|
193
|
-
|
204
|
+
defCharset: 'utf-8',
|
194
205
|
});
|
195
|
-
|
196
|
-
|
197
|
-
|
206
|
+
const complete = (err) => {
|
207
|
+
stream.unpipe(bb);
|
208
|
+
bb.destroy();
|
209
|
+
if (currFile) {
|
210
|
+
currFile.destroy();
|
211
|
+
currFile = null;
|
212
|
+
}
|
213
|
+
if (err || lastError) {
|
214
|
+
reject(err || lastError);
|
215
|
+
}
|
216
|
+
else {
|
217
|
+
// no error occured, this is a successful end/complete/finish
|
218
|
+
resolve(this._formData);
|
219
|
+
}
|
220
|
+
};
|
221
|
+
// we dont need to listen to the stream close event because bb will close or error when necessary
|
222
|
+
// stream.on('close', complete);
|
223
|
+
// stream can be aborted, for example
|
224
|
+
stream.on('error', complete);
|
225
|
+
bb.on('field', (name, value, fieldnameTruncated, valueTruncated) => {
|
226
|
+
if (fieldnameTruncated) {
|
227
|
+
return complete(new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`));
|
198
228
|
}
|
199
229
|
if (valueTruncated) {
|
200
|
-
|
230
|
+
return complete(new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`));
|
201
231
|
}
|
202
232
|
this._formData.set(name, value);
|
203
233
|
});
|
204
|
-
bb.on('
|
205
|
-
|
206
|
-
});
|
207
|
-
bb.on('file', (name, fileStream, { filename, mimeType }) => {
|
234
|
+
bb.on('file', (name, fileStream, filename, _transferEncoding, mimeType) => {
|
235
|
+
currFile = fileStream;
|
208
236
|
const chunks = [];
|
209
|
-
fileStream.on('limit', () => {
|
210
|
-
reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
211
|
-
});
|
212
237
|
fileStream.on('data', chunk => {
|
213
238
|
chunks.push(chunk);
|
214
239
|
});
|
240
|
+
fileStream.on('error', complete);
|
241
|
+
fileStream.on('limit', () => {
|
242
|
+
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
243
|
+
});
|
215
244
|
fileStream.on('close', () => {
|
216
245
|
if (fileStream.truncated) {
|
217
|
-
|
246
|
+
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
218
247
|
}
|
248
|
+
currFile = null;
|
219
249
|
const file = new PonyfillFile(chunks, filename, { type: mimeType });
|
220
250
|
this._formData.set(name, file);
|
221
251
|
});
|
222
252
|
});
|
253
|
+
bb.on('fieldsLimit', () => {
|
254
|
+
complete(new Error(`Fields limit exceeded: ${formDataLimits?.fields}`));
|
255
|
+
});
|
223
256
|
bb.on('filesLimit', () => {
|
224
|
-
|
257
|
+
complete(new Error(`Files limit exceeded: ${formDataLimits?.files}`));
|
225
258
|
});
|
226
259
|
bb.on('partsLimit', () => {
|
227
|
-
|
228
|
-
});
|
229
|
-
bb.on('close', () => {
|
230
|
-
resolve(this._formData);
|
231
|
-
});
|
232
|
-
bb.on('error', (err = 'An error occurred while parsing the form data') => {
|
233
|
-
const errMessage = err.message || err.toString();
|
234
|
-
// @ts-ignore - `cause` is in `TypeError`in node
|
235
|
-
reject(new TypeError(errMessage, err.cause));
|
260
|
+
complete(new Error(`Parts limit exceeded: ${formDataLimits?.parts}`));
|
236
261
|
});
|
237
|
-
|
262
|
+
bb.on('end', complete);
|
263
|
+
bb.on('finish', complete);
|
264
|
+
bb.on('close', complete);
|
265
|
+
bb.on('error', complete);
|
266
|
+
stream.pipe(bb);
|
238
267
|
});
|
239
268
|
}
|
240
269
|
buffer() {
|
package/package.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@whatwg-node/node-fetch",
|
3
|
-
"version": "0.7.
|
3
|
+
"version": "0.7.18-alpha-20250414141945-85ba4bb116008ce30707b20368f44d791a52afaa",
|
4
4
|
"description": "Fetch API implementation for Node",
|
5
5
|
"sideEffects": false,
|
6
6
|
"dependencies": {
|
7
|
+
"@fastify/busboy": "^3.1.1",
|
7
8
|
"@whatwg-node/disposablestack": "^0.0.6",
|
8
|
-
"@whatwg-node/promise-helpers": "
|
9
|
-
"busboy": "^1.6.0",
|
9
|
+
"@whatwg-node/promise-helpers": "1.3.1-alpha-20250414141945-85ba4bb116008ce30707b20368f44d791a52afaa",
|
10
10
|
"tslib": "^2.6.3"
|
11
11
|
},
|
12
12
|
"repository": {
|