@whatwg-node/node-fetch 0.7.22-alpha-20250526145249-5592a2aa5cd5a8603f5016376c1e6ef0f84f7aab → 0.7.22-alpha-20250527001401-318441d4ecce8b4db24c1d2d9a90cfb84928b021
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 +53 -98
- package/cjs/fetchNodeHttp.js +6 -8
- package/esm/Body.js +56 -101
- package/esm/fetchNodeHttp.js +6 -8
- package/package.json +1 -1
package/cjs/Body.js
CHANGED
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PonyfillBody = void 0;
|
4
4
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
5
5
|
const node_buffer_1 = require("node:buffer");
|
6
|
-
const node_http_1 = require("node:http");
|
7
6
|
const node_stream_1 = require("node:stream");
|
7
|
+
const promises_1 = require("node:stream/promises");
|
8
8
|
const busboy_1 = require("@fastify/busboy");
|
9
9
|
const promise_helpers_1 = require("@whatwg-node/promise-helpers");
|
10
10
|
const Blob_js_1 = require("./Blob.js");
|
@@ -33,7 +33,7 @@ class PonyfillBody {
|
|
33
33
|
this.bodyInit = bodyInit;
|
34
34
|
this.options = options;
|
35
35
|
this._signal = options.signal || null;
|
36
|
-
const { bodyFactory, contentType, contentLength, bodyType, buffer } = processBodyInit(bodyInit
|
36
|
+
const { bodyFactory, contentType, contentLength, bodyType, buffer } = processBodyInit(bodyInit);
|
37
37
|
this._bodyFactory = bodyFactory;
|
38
38
|
this.contentType = contentType;
|
39
39
|
this.contentLength = contentLength;
|
@@ -133,6 +133,11 @@ class PonyfillBody {
|
|
133
133
|
this._chunks = [];
|
134
134
|
return this._chunks;
|
135
135
|
}
|
136
|
+
if (_body.readable.destroyed) {
|
137
|
+
// If the stream is already destroyed, we can resolve immediately
|
138
|
+
this._chunks = [];
|
139
|
+
return this._chunks;
|
140
|
+
}
|
136
141
|
const chunks = [];
|
137
142
|
const deferred = (0, promise_helpers_1.createDeferredPromise)();
|
138
143
|
_body.readable.on('data', function nextChunk(chunk) {
|
@@ -204,93 +209,57 @@ class PonyfillBody {
|
|
204
209
|
...this.options.formDataLimits,
|
205
210
|
...opts?.formDataLimits,
|
206
211
|
};
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
212
|
+
const stream = this.body?.readable;
|
213
|
+
if (!stream) {
|
214
|
+
return (0, promise_helpers_1.fakeRejectPromise)(new Error('No stream available'));
|
215
|
+
}
|
216
|
+
const bb = new busboy_1.Busboy({
|
217
|
+
headers: {
|
218
|
+
'content-length': typeof this.contentLength === 'number'
|
219
|
+
? this.contentLength.toString()
|
220
|
+
: this.contentLength || '',
|
221
|
+
'content-type': this.contentType || '',
|
222
|
+
},
|
223
|
+
limits: formDataLimits,
|
224
|
+
defCharset: 'utf-8',
|
225
|
+
});
|
226
|
+
bb.on('field', (name, value, fieldnameTruncated, valueTruncated) => {
|
227
|
+
if (fieldnameTruncated) {
|
228
|
+
throw new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`);
|
211
229
|
}
|
212
|
-
|
213
|
-
|
214
|
-
let currFile = null;
|
215
|
-
const bb = new busboy_1.Busboy({
|
216
|
-
headers: {
|
217
|
-
'content-length': typeof this.contentLength === 'number'
|
218
|
-
? this.contentLength.toString()
|
219
|
-
: this.contentLength || '',
|
220
|
-
'content-type': this.contentType || '',
|
221
|
-
},
|
222
|
-
limits: formDataLimits,
|
223
|
-
defCharset: 'utf-8',
|
224
|
-
});
|
225
|
-
if (this._signal) {
|
226
|
-
(0, node_stream_1.addAbortSignal)(this._signal, bb);
|
230
|
+
if (valueTruncated) {
|
231
|
+
throw new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`);
|
227
232
|
}
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
bb.destroy();
|
235
|
-
if (currFile) {
|
236
|
-
currFile.destroy();
|
237
|
-
currFile = null;
|
238
|
-
}
|
239
|
-
if (err) {
|
240
|
-
reject(err);
|
241
|
-
}
|
242
|
-
else {
|
243
|
-
// no error occured, this is a successful end/complete/finish
|
244
|
-
resolve(this._formData);
|
245
|
-
}
|
246
|
-
};
|
247
|
-
// we dont need to listen to the stream close event because bb will close or error when necessary
|
248
|
-
// stream.on('close', complete);
|
249
|
-
// stream can be aborted, for example
|
250
|
-
stream.on('error', complete);
|
251
|
-
bb.on('field', (name, value, fieldnameTruncated, valueTruncated) => {
|
252
|
-
if (fieldnameTruncated) {
|
253
|
-
return complete(new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`));
|
254
|
-
}
|
255
|
-
if (valueTruncated) {
|
256
|
-
return complete(new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`));
|
257
|
-
}
|
258
|
-
this._formData.set(name, value);
|
259
|
-
});
|
260
|
-
bb.on('file', (name, fileStream, filename, _transferEncoding, mimeType) => {
|
261
|
-
currFile = fileStream;
|
262
|
-
const chunks = [];
|
263
|
-
fileStream.on('data', chunk => {
|
264
|
-
chunks.push(chunk);
|
265
|
-
});
|
266
|
-
fileStream.on('error', complete);
|
267
|
-
fileStream.on('limit', () => {
|
268
|
-
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
269
|
-
});
|
270
|
-
fileStream.on('close', () => {
|
271
|
-
if (fileStream.truncated) {
|
272
|
-
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
273
|
-
}
|
274
|
-
currFile = null;
|
275
|
-
const file = new File_js_1.PonyfillFile(chunks, filename, { type: mimeType });
|
276
|
-
this._formData.set(name, file);
|
277
|
-
});
|
278
|
-
});
|
279
|
-
bb.on('fieldsLimit', () => {
|
280
|
-
complete(new Error(`Fields limit exceeded: ${formDataLimits?.fields}`));
|
233
|
+
this._formData.set(name, value);
|
234
|
+
});
|
235
|
+
bb.on('file', (name, fileStream, filename, _transferEncoding, mimeType) => {
|
236
|
+
const chunks = [];
|
237
|
+
fileStream.on('data', chunk => {
|
238
|
+
chunks.push(chunk);
|
281
239
|
});
|
282
|
-
|
283
|
-
|
240
|
+
fileStream.on('limit', () => {
|
241
|
+
throw new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`);
|
284
242
|
});
|
285
|
-
|
286
|
-
|
243
|
+
fileStream.on('close', () => {
|
244
|
+
if (fileStream.truncated) {
|
245
|
+
throw new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`);
|
246
|
+
}
|
247
|
+
const file = new File_js_1.PonyfillFile(chunks, filename, { type: mimeType });
|
248
|
+
this._formData.set(name, file);
|
287
249
|
});
|
288
|
-
bb.on('end', complete);
|
289
|
-
bb.on('finish', complete);
|
290
|
-
bb.on('close', complete);
|
291
|
-
bb.on('error', complete);
|
292
|
-
stream.pipe(bb);
|
293
250
|
});
|
251
|
+
bb.on('fieldsLimit', () => {
|
252
|
+
throw new Error(`Fields limit exceeded: ${formDataLimits?.fields}`);
|
253
|
+
});
|
254
|
+
bb.on('filesLimit', () => {
|
255
|
+
throw new Error(`Files limit exceeded: ${formDataLimits?.files}`);
|
256
|
+
});
|
257
|
+
bb.on('partsLimit', () => {
|
258
|
+
throw new Error(`Parts limit exceeded: ${formDataLimits?.parts}`);
|
259
|
+
});
|
260
|
+
return (0, promises_1.pipeline)(stream, bb, {
|
261
|
+
signal: this._signal || undefined,
|
262
|
+
}).then(() => this._formData);
|
294
263
|
}
|
295
264
|
buffer() {
|
296
265
|
if (this._buffer) {
|
@@ -379,7 +348,7 @@ class PonyfillBody {
|
|
379
348
|
}
|
380
349
|
}
|
381
350
|
exports.PonyfillBody = PonyfillBody;
|
382
|
-
function processBodyInit(bodyInit
|
351
|
+
function processBodyInit(bodyInit) {
|
383
352
|
if (bodyInit == null) {
|
384
353
|
return {
|
385
354
|
bodyFactory: () => null,
|
@@ -462,20 +431,6 @@ function processBodyInit(bodyInit, signal) {
|
|
462
431
|
},
|
463
432
|
};
|
464
433
|
}
|
465
|
-
if (bodyInit instanceof node_http_1.IncomingMessage) {
|
466
|
-
const passThrough = (0, utils_js_1.wrapIncomingMessageWithPassthrough)({
|
467
|
-
incomingMessage: bodyInit,
|
468
|
-
signal,
|
469
|
-
});
|
470
|
-
return {
|
471
|
-
bodyType: BodyInitType.Readable,
|
472
|
-
contentType: null,
|
473
|
-
contentLength: null,
|
474
|
-
bodyFactory() {
|
475
|
-
return new ReadableStream_js_1.PonyfillReadableStream(passThrough);
|
476
|
-
},
|
477
|
-
};
|
478
|
-
}
|
479
434
|
if (bodyInit instanceof node_stream_1.Readable) {
|
480
435
|
return {
|
481
436
|
bodyType: BodyInitType.Readable,
|
package/cjs/fetchNodeHttp.js
CHANGED
@@ -95,14 +95,12 @@ function fetchNodeHttp(fetchRequest) {
|
|
95
95
|
return;
|
96
96
|
}
|
97
97
|
}
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
});
|
105
|
-
}
|
98
|
+
outputStream = (0, utils_js_1.wrapIncomingMessageWithPassthrough)({
|
99
|
+
incomingMessage: nodeResponse,
|
100
|
+
passThrough: outputStream,
|
101
|
+
signal,
|
102
|
+
onError: reject,
|
103
|
+
});
|
106
104
|
const statusCode = nodeResponse.statusCode || 200;
|
107
105
|
let statusText = nodeResponse.statusMessage || node_http_1.STATUS_CODES[statusCode];
|
108
106
|
if (statusText == null) {
|
package/esm/Body.js
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
2
2
|
import { Buffer } from 'node:buffer';
|
3
|
-
import {
|
4
|
-
import {
|
3
|
+
import { Readable } from 'node:stream';
|
4
|
+
import { pipeline } from 'node:stream/promises';
|
5
5
|
import { Busboy } from '@fastify/busboy';
|
6
|
-
import { createDeferredPromise } from '@whatwg-node/promise-helpers';
|
6
|
+
import { createDeferredPromise, fakeRejectPromise, } from '@whatwg-node/promise-helpers';
|
7
7
|
import { hasArrayBufferMethod, hasBufferMethod, hasBytesMethod, PonyfillBlob } from './Blob.js';
|
8
8
|
import { PonyfillFile } from './File.js';
|
9
9
|
import { getStreamFromFormData, PonyfillFormData } from './FormData.js';
|
10
10
|
import { PonyfillReadableStream } from './ReadableStream.js';
|
11
|
-
import { fakePromise, isArrayBufferView
|
11
|
+
import { fakePromise, isArrayBufferView } from './utils.js';
|
12
12
|
var BodyInitType;
|
13
13
|
(function (BodyInitType) {
|
14
14
|
BodyInitType["ReadableStream"] = "ReadableStream";
|
@@ -30,7 +30,7 @@ export class PonyfillBody {
|
|
30
30
|
this.bodyInit = bodyInit;
|
31
31
|
this.options = options;
|
32
32
|
this._signal = options.signal || null;
|
33
|
-
const { bodyFactory, contentType, contentLength, bodyType, buffer } = processBodyInit(bodyInit
|
33
|
+
const { bodyFactory, contentType, contentLength, bodyType, buffer } = processBodyInit(bodyInit);
|
34
34
|
this._bodyFactory = bodyFactory;
|
35
35
|
this.contentType = contentType;
|
36
36
|
this.contentLength = contentLength;
|
@@ -130,6 +130,11 @@ export class PonyfillBody {
|
|
130
130
|
this._chunks = [];
|
131
131
|
return this._chunks;
|
132
132
|
}
|
133
|
+
if (_body.readable.destroyed) {
|
134
|
+
// If the stream is already destroyed, we can resolve immediately
|
135
|
+
this._chunks = [];
|
136
|
+
return this._chunks;
|
137
|
+
}
|
133
138
|
const chunks = [];
|
134
139
|
const deferred = createDeferredPromise();
|
135
140
|
_body.readable.on('data', function nextChunk(chunk) {
|
@@ -201,93 +206,57 @@ export class PonyfillBody {
|
|
201
206
|
...this.options.formDataLimits,
|
202
207
|
...opts?.formDataLimits,
|
203
208
|
};
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
209
|
+
const stream = this.body?.readable;
|
210
|
+
if (!stream) {
|
211
|
+
return fakeRejectPromise(new Error('No stream available'));
|
212
|
+
}
|
213
|
+
const bb = new Busboy({
|
214
|
+
headers: {
|
215
|
+
'content-length': typeof this.contentLength === 'number'
|
216
|
+
? this.contentLength.toString()
|
217
|
+
: this.contentLength || '',
|
218
|
+
'content-type': this.contentType || '',
|
219
|
+
},
|
220
|
+
limits: formDataLimits,
|
221
|
+
defCharset: 'utf-8',
|
222
|
+
});
|
223
|
+
bb.on('field', (name, value, fieldnameTruncated, valueTruncated) => {
|
224
|
+
if (fieldnameTruncated) {
|
225
|
+
throw new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`);
|
208
226
|
}
|
209
|
-
|
210
|
-
|
211
|
-
let currFile = null;
|
212
|
-
const bb = new Busboy({
|
213
|
-
headers: {
|
214
|
-
'content-length': typeof this.contentLength === 'number'
|
215
|
-
? this.contentLength.toString()
|
216
|
-
: this.contentLength || '',
|
217
|
-
'content-type': this.contentType || '',
|
218
|
-
},
|
219
|
-
limits: formDataLimits,
|
220
|
-
defCharset: 'utf-8',
|
221
|
-
});
|
222
|
-
if (this._signal) {
|
223
|
-
addAbortSignal(this._signal, bb);
|
227
|
+
if (valueTruncated) {
|
228
|
+
throw new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`);
|
224
229
|
}
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
bb.destroy();
|
232
|
-
if (currFile) {
|
233
|
-
currFile.destroy();
|
234
|
-
currFile = null;
|
235
|
-
}
|
236
|
-
if (err) {
|
237
|
-
reject(err);
|
238
|
-
}
|
239
|
-
else {
|
240
|
-
// no error occured, this is a successful end/complete/finish
|
241
|
-
resolve(this._formData);
|
242
|
-
}
|
243
|
-
};
|
244
|
-
// we dont need to listen to the stream close event because bb will close or error when necessary
|
245
|
-
// stream.on('close', complete);
|
246
|
-
// stream can be aborted, for example
|
247
|
-
stream.on('error', complete);
|
248
|
-
bb.on('field', (name, value, fieldnameTruncated, valueTruncated) => {
|
249
|
-
if (fieldnameTruncated) {
|
250
|
-
return complete(new Error(`Field name size exceeded: ${formDataLimits?.fieldNameSize} bytes`));
|
251
|
-
}
|
252
|
-
if (valueTruncated) {
|
253
|
-
return complete(new Error(`Field value size exceeded: ${formDataLimits?.fieldSize} bytes`));
|
254
|
-
}
|
255
|
-
this._formData.set(name, value);
|
256
|
-
});
|
257
|
-
bb.on('file', (name, fileStream, filename, _transferEncoding, mimeType) => {
|
258
|
-
currFile = fileStream;
|
259
|
-
const chunks = [];
|
260
|
-
fileStream.on('data', chunk => {
|
261
|
-
chunks.push(chunk);
|
262
|
-
});
|
263
|
-
fileStream.on('error', complete);
|
264
|
-
fileStream.on('limit', () => {
|
265
|
-
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
266
|
-
});
|
267
|
-
fileStream.on('close', () => {
|
268
|
-
if (fileStream.truncated) {
|
269
|
-
complete(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
|
270
|
-
}
|
271
|
-
currFile = null;
|
272
|
-
const file = new PonyfillFile(chunks, filename, { type: mimeType });
|
273
|
-
this._formData.set(name, file);
|
274
|
-
});
|
275
|
-
});
|
276
|
-
bb.on('fieldsLimit', () => {
|
277
|
-
complete(new Error(`Fields limit exceeded: ${formDataLimits?.fields}`));
|
230
|
+
this._formData.set(name, value);
|
231
|
+
});
|
232
|
+
bb.on('file', (name, fileStream, filename, _transferEncoding, mimeType) => {
|
233
|
+
const chunks = [];
|
234
|
+
fileStream.on('data', chunk => {
|
235
|
+
chunks.push(chunk);
|
278
236
|
});
|
279
|
-
|
280
|
-
|
237
|
+
fileStream.on('limit', () => {
|
238
|
+
throw new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`);
|
281
239
|
});
|
282
|
-
|
283
|
-
|
240
|
+
fileStream.on('close', () => {
|
241
|
+
if (fileStream.truncated) {
|
242
|
+
throw new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`);
|
243
|
+
}
|
244
|
+
const file = new PonyfillFile(chunks, filename, { type: mimeType });
|
245
|
+
this._formData.set(name, file);
|
284
246
|
});
|
285
|
-
bb.on('end', complete);
|
286
|
-
bb.on('finish', complete);
|
287
|
-
bb.on('close', complete);
|
288
|
-
bb.on('error', complete);
|
289
|
-
stream.pipe(bb);
|
290
247
|
});
|
248
|
+
bb.on('fieldsLimit', () => {
|
249
|
+
throw new Error(`Fields limit exceeded: ${formDataLimits?.fields}`);
|
250
|
+
});
|
251
|
+
bb.on('filesLimit', () => {
|
252
|
+
throw new Error(`Files limit exceeded: ${formDataLimits?.files}`);
|
253
|
+
});
|
254
|
+
bb.on('partsLimit', () => {
|
255
|
+
throw new Error(`Parts limit exceeded: ${formDataLimits?.parts}`);
|
256
|
+
});
|
257
|
+
return pipeline(stream, bb, {
|
258
|
+
signal: this._signal || undefined,
|
259
|
+
}).then(() => this._formData);
|
291
260
|
}
|
292
261
|
buffer() {
|
293
262
|
if (this._buffer) {
|
@@ -375,7 +344,7 @@ export class PonyfillBody {
|
|
375
344
|
});
|
376
345
|
}
|
377
346
|
}
|
378
|
-
function processBodyInit(bodyInit
|
347
|
+
function processBodyInit(bodyInit) {
|
379
348
|
if (bodyInit == null) {
|
380
349
|
return {
|
381
350
|
bodyFactory: () => null,
|
@@ -458,20 +427,6 @@ function processBodyInit(bodyInit, signal) {
|
|
458
427
|
},
|
459
428
|
};
|
460
429
|
}
|
461
|
-
if (bodyInit instanceof IncomingMessage) {
|
462
|
-
const passThrough = wrapIncomingMessageWithPassthrough({
|
463
|
-
incomingMessage: bodyInit,
|
464
|
-
signal,
|
465
|
-
});
|
466
|
-
return {
|
467
|
-
bodyType: BodyInitType.Readable,
|
468
|
-
contentType: null,
|
469
|
-
contentLength: null,
|
470
|
-
bodyFactory() {
|
471
|
-
return new PonyfillReadableStream(passThrough);
|
472
|
-
},
|
473
|
-
};
|
474
|
-
}
|
475
430
|
if (bodyInit instanceof Readable) {
|
476
431
|
return {
|
477
432
|
bodyType: BodyInitType.Readable,
|
package/esm/fetchNodeHttp.js
CHANGED
@@ -92,14 +92,12 @@ export function fetchNodeHttp(fetchRequest) {
|
|
92
92
|
return;
|
93
93
|
}
|
94
94
|
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
});
|
102
|
-
}
|
95
|
+
outputStream = wrapIncomingMessageWithPassthrough({
|
96
|
+
incomingMessage: nodeResponse,
|
97
|
+
passThrough: outputStream,
|
98
|
+
signal,
|
99
|
+
onError: reject,
|
100
|
+
});
|
103
101
|
const statusCode = nodeResponse.statusCode || 200;
|
104
102
|
let statusText = nodeResponse.statusMessage || STATUS_CODES[statusCode];
|
105
103
|
if (statusText == null) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@whatwg-node/node-fetch",
|
3
|
-
"version": "0.7.22-alpha-
|
3
|
+
"version": "0.7.22-alpha-20250527001401-318441d4ecce8b4db24c1d2d9a90cfb84928b021",
|
4
4
|
"description": "Fetch API implementation for Node",
|
5
5
|
"sideEffects": false,
|
6
6
|
"dependencies": {
|