@whatwg-node/node-fetch 0.0.2 → 0.0.3-alpha-20230205160101-d3a1033

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.
Files changed (4) hide show
  1. package/Body.d.ts +5 -1
  2. package/index.js +199 -93
  3. package/index.mjs +199 -93
  4. package/package.json +1 -1
package/Body.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Readable } from 'stream';
3
4
  import { PonyfillBlob } from './Blob';
4
5
  import { PonyfillFormData } from './FormData';
@@ -20,17 +21,20 @@ export declare class PonyfillBody<TJSON = any> implements Body {
20
21
  private bodyInit;
21
22
  private options;
22
23
  bodyUsed: boolean;
23
- private _body;
24
24
  contentType: string | null;
25
25
  contentLength: number | null;
26
26
  constructor(bodyInit: BodyPonyfillInit | null, options?: PonyfillBodyOptions);
27
27
  private bodyType?;
28
+ private _bodyFactory;
29
+ private _generatedBody;
30
+ private generateBody;
28
31
  get body(): PonyfillReadableStream<Uint8Array> | null;
29
32
  arrayBuffer(): Promise<ArrayBuffer>;
30
33
  blob(): Promise<PonyfillBlob>;
31
34
  formData(opts?: {
32
35
  formDataLimits: FormDataLimits;
33
36
  }): Promise<PonyfillFormData>;
37
+ buffer(): Promise<Buffer>;
34
38
  json(): Promise<TJSON>;
35
39
  text(): Promise<string>;
36
40
  }
package/index.js CHANGED
@@ -9,9 +9,9 @@ const http = require('http');
9
9
  const https = require('https');
10
10
  const stream = require('stream');
11
11
  const url = require('url');
12
+ const buffer = require('buffer');
12
13
  const events = require('@whatwg-node/events');
13
14
  const busboy = _interopDefault(require('busboy'));
14
- const buffer = require('buffer');
15
15
 
16
16
  // Will be removed after v14 reaches EOL
17
17
  class PonyfillAbortError extends Error {
@@ -30,48 +30,6 @@ class PonyfillAbortError extends Error {
30
30
  }
31
31
  }
32
32
 
33
- // Will be removed after v14 reaches EOL
34
- class PonyfillAbortSignal extends events.EventTarget {
35
- constructor() {
36
- super(...arguments);
37
- this.aborted = false;
38
- this._onabort = null;
39
- }
40
- throwIfAborted() {
41
- if (this.aborted) {
42
- throw new PonyfillAbortError();
43
- }
44
- }
45
- get onabort() {
46
- return this._onabort;
47
- }
48
- set onabort(value) {
49
- if (this._onabort) {
50
- this.removeEventListener('abort', this._onabort);
51
- }
52
- this.addEventListener('abort', value);
53
- }
54
- abort(reason) {
55
- const abortEvent = new events.CustomEvent('abort', { detail: reason });
56
- this.dispatchEvent(abortEvent);
57
- }
58
- static timeout(milliseconds) {
59
- const signal = new PonyfillAbortSignal();
60
- setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
61
- return signal;
62
- }
63
- }
64
-
65
- // Will be removed after v14 reaches EOL
66
- class PonyfillAbortController {
67
- constructor() {
68
- this.signal = new PonyfillAbortSignal();
69
- }
70
- abort(reason) {
71
- this.signal.abort(reason);
72
- }
73
- }
74
-
75
33
  function createController(desiredSize, readable) {
76
34
  let chunks = [];
77
35
  return {
@@ -232,6 +190,48 @@ class PonyfillBlob extends buffer.Blob {
232
190
  }
233
191
  }
234
192
 
193
+ // Will be removed after v14 reaches EOL
194
+ class PonyfillAbortSignal extends events.EventTarget {
195
+ constructor() {
196
+ super(...arguments);
197
+ this.aborted = false;
198
+ this._onabort = null;
199
+ }
200
+ throwIfAborted() {
201
+ if (this.aborted) {
202
+ throw new PonyfillAbortError();
203
+ }
204
+ }
205
+ get onabort() {
206
+ return this._onabort;
207
+ }
208
+ set onabort(value) {
209
+ if (this._onabort) {
210
+ this.removeEventListener('abort', this._onabort);
211
+ }
212
+ this.addEventListener('abort', value);
213
+ }
214
+ abort(reason) {
215
+ const abortEvent = new events.CustomEvent('abort', { detail: reason });
216
+ this.dispatchEvent(abortEvent);
217
+ }
218
+ static timeout(milliseconds) {
219
+ const signal = new PonyfillAbortSignal();
220
+ setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
221
+ return signal;
222
+ }
223
+ }
224
+
225
+ // Will be removed after v14 reaches EOL
226
+ class PonyfillAbortController {
227
+ constructor() {
228
+ this.signal = new PonyfillAbortSignal();
229
+ }
230
+ abort(reason) {
231
+ this.signal.abort(reason);
232
+ }
233
+ }
234
+
235
235
  class PonyfillFile extends PonyfillBlob {
236
236
  constructor(fileBits, name, options) {
237
237
  super(fileBits, options);
@@ -353,26 +353,38 @@ var BodyInitType;
353
353
  BodyInitType["ArrayBuffer"] = "ArrayBuffer";
354
354
  BodyInitType["String"] = "String";
355
355
  BodyInitType["Readable"] = "Readable";
356
+ BodyInitType["Buffer"] = "Buffer";
357
+ BodyInitType["Uint8Array"] = "Uint8Array";
356
358
  })(BodyInitType || (BodyInitType = {}));
357
359
  class PonyfillBody {
358
360
  constructor(bodyInit, options = {}) {
359
361
  this.bodyInit = bodyInit;
360
362
  this.options = options;
361
363
  this.bodyUsed = false;
362
- this._body = null;
363
364
  this.contentType = null;
364
365
  this.contentLength = null;
365
- const { body, contentType, contentLength, bodyType } = processBodyInit(bodyInit);
366
- this._body = body;
366
+ this._bodyFactory = () => null;
367
+ this._generatedBody = null;
368
+ const { bodyFactory, contentType, contentLength, bodyType } = processBodyInit(bodyInit);
369
+ this._bodyFactory = bodyFactory;
367
370
  this.contentType = contentType;
368
371
  this.contentLength = contentLength;
369
372
  this.bodyType = bodyType;
370
373
  }
374
+ generateBody() {
375
+ if (this._generatedBody) {
376
+ return this._generatedBody;
377
+ }
378
+ const body = this._bodyFactory();
379
+ this._generatedBody = body;
380
+ return body;
381
+ }
371
382
  get body() {
372
- if (this._body != null) {
373
- const ponyfillReadableStream = this._body;
374
- const readable = this._body.readable;
375
- return new Proxy(this._body.readable, {
383
+ const _body = this.generateBody();
384
+ if (_body != null) {
385
+ const ponyfillReadableStream = _body;
386
+ const readable = _body.readable;
387
+ return new Proxy(_body.readable, {
376
388
  get(_, prop) {
377
389
  if (prop in ponyfillReadableStream) {
378
390
  const ponyfillReadableStreamProp = ponyfillReadableStream[prop];
@@ -397,6 +409,9 @@ class PonyfillBody {
397
409
  if (this.bodyType === BodyInitType.ArrayBuffer) {
398
410
  return this.bodyInit;
399
411
  }
412
+ if (this.bodyType === BodyInitType.Uint8Array || this.bodyType === BodyInitType.Buffer) {
413
+ return this.bodyInit.buffer;
414
+ }
400
415
  const blob = await this.blob();
401
416
  return blob.arrayBuffer();
402
417
  }
@@ -404,20 +419,37 @@ class PonyfillBody {
404
419
  if (this.bodyType === BodyInitType.Blob) {
405
420
  return this.bodyInit;
406
421
  }
422
+ if (this.bodyType === BodyInitType.String || this.bodyType === BodyInitType.Buffer || this.bodyType === BodyInitType.Uint8Array) {
423
+ const bodyInitTyped = this.bodyInit;
424
+ return new PonyfillBlob([bodyInitTyped], {
425
+ type: this.contentType || '',
426
+ });
427
+ }
428
+ if (this.bodyType === BodyInitType.ArrayBuffer) {
429
+ const bodyInitTyped = this.bodyInit;
430
+ const buf = Buffer.from(bodyInitTyped, undefined, bodyInitTyped.byteLength);
431
+ return new PonyfillBlob([buf], {
432
+ type: this.contentType || '',
433
+ });
434
+ }
407
435
  const chunks = [];
408
- if (this._body) {
409
- for await (const chunk of this._body.readable) {
436
+ const _body = this.generateBody();
437
+ if (_body) {
438
+ for await (const chunk of _body.readable) {
410
439
  chunks.push(chunk);
411
440
  }
412
441
  }
413
- return new PonyfillBlob(chunks);
442
+ return new PonyfillBlob(chunks, {
443
+ type: this.contentType || '',
444
+ });
414
445
  }
415
446
  formData(opts) {
416
447
  if (this.bodyType === BodyInitType.FormData) {
417
448
  return Promise.resolve(this.bodyInit);
418
449
  }
419
450
  const formData = new PonyfillFormData();
420
- if (this._body == null) {
451
+ const _body = this.generateBody();
452
+ if (_body == null) {
421
453
  return Promise.resolve(formData);
422
454
  }
423
455
  const formDataLimits = {
@@ -425,7 +457,6 @@ class PonyfillBody {
425
457
  ...opts === null || opts === void 0 ? void 0 : opts.formDataLimits,
426
458
  };
427
459
  return new Promise((resolve, reject) => {
428
- var _a;
429
460
  const bb = busboy({
430
461
  headers: {
431
462
  'content-type': this.contentType || '',
@@ -473,9 +504,22 @@ class PonyfillBody {
473
504
  bb.on('error', err => {
474
505
  reject(err);
475
506
  });
476
- (_a = this._body) === null || _a === void 0 ? void 0 : _a.readable.pipe(bb);
507
+ _body === null || _body === void 0 ? void 0 : _body.readable.pipe(bb);
477
508
  });
478
509
  }
510
+ async buffer() {
511
+ if (this.bodyType === BodyInitType.Buffer) {
512
+ return this.bodyInit;
513
+ }
514
+ if (this.bodyType === BodyInitType.Uint8Array || this.bodyType === BodyInitType.ArrayBuffer) {
515
+ const bodyInitTyped = this.bodyInit;
516
+ const buffer = Buffer.from(bodyInitTyped, 'byteOffset' in bodyInitTyped ? bodyInitTyped.byteOffset : undefined, bodyInitTyped.byteLength);
517
+ return buffer;
518
+ }
519
+ const blob = await this.blob();
520
+ const arrayBuffer = await blob.arrayBuffer();
521
+ return Buffer.from(arrayBuffer, undefined, arrayBuffer.byteLength);
522
+ }
479
523
  async json() {
480
524
  const text = await this.text();
481
525
  return JSON.parse(text);
@@ -484,6 +528,14 @@ class PonyfillBody {
484
528
  if (this.bodyType === BodyInitType.String) {
485
529
  return this.bodyInit;
486
530
  }
531
+ if (this.bodyType === BodyInitType.Buffer) {
532
+ return this.bodyInit.toString('utf-8');
533
+ }
534
+ if (this.bodyType === BodyInitType.ArrayBuffer || this.bodyType === BodyInitType.Uint8Array) {
535
+ const bodyInitTyped = this.bodyInit;
536
+ const buffer = Buffer.from(bodyInitTyped, 'byteOffset' in bodyInitTyped ? bodyInitTyped.byteOffset : undefined, bodyInitTyped.byteLength);
537
+ return buffer.toString('utf-8');
538
+ }
487
539
  const blob = await this.blob();
488
540
  return blob.text();
489
541
  }
@@ -491,114 +543,152 @@ class PonyfillBody {
491
543
  function processBodyInit(bodyInit) {
492
544
  if (bodyInit == null) {
493
545
  return {
494
- body: null,
546
+ bodyFactory: () => null,
495
547
  contentType: null,
496
548
  contentLength: null,
497
549
  };
498
550
  }
499
551
  if (typeof bodyInit === 'string') {
500
- const buffer = Buffer.from(bodyInit);
501
- const readable = stream.Readable.from(buffer);
502
- const body = new PonyfillReadableStream(readable);
503
552
  return {
504
553
  bodyType: BodyInitType.String,
505
554
  contentType: 'text/plain;charset=UTF-8',
506
- contentLength: buffer.length,
507
- body,
555
+ contentLength: bodyInit.length,
556
+ bodyFactory() {
557
+ const buffer = Buffer.from(bodyInit);
558
+ const readable = stream.Readable.from(buffer);
559
+ return new PonyfillReadableStream(readable);
560
+ },
508
561
  };
509
562
  }
510
563
  if (bodyInit instanceof PonyfillReadableStream) {
511
564
  return {
512
565
  bodyType: BodyInitType.ReadableStream,
513
- body: bodyInit,
566
+ bodyFactory: () => bodyInit,
514
567
  contentType: null,
515
568
  contentLength: null,
516
569
  };
517
570
  }
518
571
  if (bodyInit instanceof PonyfillBlob) {
519
- const readable = bodyInit.stream();
520
- const body = new PonyfillReadableStream(readable);
521
572
  return {
522
573
  bodyType: BodyInitType.Blob,
523
574
  contentType: bodyInit.type,
524
575
  contentLength: bodyInit.size,
525
- body,
576
+ bodyFactory() {
577
+ return bodyInit.stream();
578
+ },
526
579
  };
527
580
  }
528
581
  if (bodyInit instanceof PonyfillFormData) {
529
582
  const boundary = Math.random().toString(36).substr(2);
530
583
  const contentType = `multipart/form-data; boundary=${boundary}`;
531
- const body = bodyInit.stream(boundary);
532
584
  return {
533
585
  bodyType: BodyInitType.FormData,
534
586
  contentType,
535
587
  contentLength: null,
536
- body,
588
+ bodyFactory: () => bodyInit.stream(boundary),
589
+ };
590
+ }
591
+ if (bodyInit instanceof Buffer) {
592
+ const contentLength = bodyInit.length;
593
+ return {
594
+ bodyType: BodyInitType.Buffer,
595
+ contentLength,
596
+ contentType: null,
597
+ bodyFactory() {
598
+ const readable = stream.Readable.from(bodyInit);
599
+ const body = new PonyfillReadableStream(readable);
600
+ return body;
601
+ },
602
+ };
603
+ }
604
+ if (bodyInit instanceof Uint8Array) {
605
+ const contentLength = bodyInit.byteLength;
606
+ return {
607
+ bodyType: BodyInitType.Uint8Array,
608
+ contentLength,
609
+ contentType: null,
610
+ bodyFactory() {
611
+ const readable = stream.Readable.from(bodyInit);
612
+ const body = new PonyfillReadableStream(readable);
613
+ return body;
614
+ }
537
615
  };
538
616
  }
539
617
  if ('buffer' in bodyInit) {
540
618
  const contentLength = bodyInit.byteLength;
541
- const buffer = Buffer.from(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength);
542
- const readable = stream.Readable.from(buffer);
543
- const body = new PonyfillReadableStream(readable);
544
619
  return {
545
620
  contentLength,
546
621
  contentType: null,
547
- body,
622
+ bodyFactory() {
623
+ const buffer = Buffer.from(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength);
624
+ const readable = stream.Readable.from(buffer);
625
+ const body = new PonyfillReadableStream(readable);
626
+ return body;
627
+ }
548
628
  };
549
629
  }
550
630
  if (bodyInit instanceof ArrayBuffer) {
551
631
  const contentLength = bodyInit.byteLength;
552
- const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
553
- const readable = stream.Readable.from(buffer);
554
- const body = new PonyfillReadableStream(readable);
555
632
  return {
556
633
  bodyType: BodyInitType.ArrayBuffer,
557
634
  contentType: null,
558
635
  contentLength,
559
- body,
636
+ bodyFactory() {
637
+ const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
638
+ const readable = stream.Readable.from(buffer);
639
+ const body = new PonyfillReadableStream(readable);
640
+ return body;
641
+ }
560
642
  };
561
643
  }
562
644
  if (bodyInit instanceof stream.Readable) {
563
- const body = new PonyfillReadableStream(bodyInit);
564
645
  return {
565
646
  bodyType: BodyInitType.Readable,
566
647
  contentType: null,
567
648
  contentLength: null,
568
- body,
649
+ bodyFactory() {
650
+ const body = new PonyfillReadableStream(bodyInit);
651
+ return body;
652
+ }
569
653
  };
570
654
  }
571
655
  if ('stream' in bodyInit) {
572
- const bodyStream = bodyInit.stream();
573
- const body = new PonyfillReadableStream(bodyStream);
574
656
  return {
575
657
  contentType: bodyInit.type,
576
658
  contentLength: bodyInit.size,
577
- body,
659
+ bodyFactory() {
660
+ const bodyStream = bodyInit.stream();
661
+ const body = new PonyfillReadableStream(bodyStream);
662
+ return body;
663
+ }
578
664
  };
579
665
  }
580
666
  if (bodyInit instanceof URLSearchParams) {
581
667
  const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
582
- const body = new PonyfillReadableStream(stream.Readable.from(bodyInit.toString()));
583
668
  return {
584
669
  bodyType: BodyInitType.String,
585
670
  contentType,
586
671
  contentLength: null,
587
- body,
672
+ bodyFactory() {
673
+ const body = new PonyfillReadableStream(stream.Readable.from(bodyInit.toString()));
674
+ return body;
675
+ }
588
676
  };
589
677
  }
590
678
  if ('forEach' in bodyInit) {
591
- const formData = new PonyfillFormData();
592
- bodyInit.forEach((value, key) => {
593
- formData.append(key, value);
594
- });
595
679
  const boundary = Math.random().toString(36).substr(2);
596
680
  const contentType = `multipart/form-data; boundary=${boundary}`;
597
- const body = formData.stream(boundary);
598
681
  return {
599
682
  contentType,
600
683
  contentLength: null,
601
- body,
684
+ bodyFactory() {
685
+ const formData = new PonyfillFormData();
686
+ bodyInit.forEach((value, key) => {
687
+ formData.append(key, value);
688
+ });
689
+ const body = formData.stream(boundary);
690
+ return body;
691
+ },
602
692
  };
603
693
  }
604
694
  throw new Error('Unknown body type');
@@ -756,6 +846,24 @@ class PonyfillResponse extends PonyfillBody {
756
846
  this.redirected = init.redirected || false;
757
847
  this.type = init.type || 'default';
758
848
  }
849
+ const contentTypeInHeaders = this.headers.get('content-type');
850
+ if (!contentTypeInHeaders) {
851
+ if (this.contentType) {
852
+ this.headers.set('content-type', this.contentType);
853
+ }
854
+ }
855
+ else {
856
+ this.contentType = contentTypeInHeaders;
857
+ }
858
+ const contentLengthInHeaders = this.headers.get('content-length');
859
+ if (!contentLengthInHeaders) {
860
+ if (this.contentLength) {
861
+ this.headers.set('content-length', this.contentLength.toString());
862
+ }
863
+ }
864
+ else {
865
+ this.contentLength = parseInt(contentLengthInHeaders, 10);
866
+ }
759
867
  }
760
868
  get ok() {
761
869
  return this.status >= 200 && this.status < 300;
@@ -832,12 +940,10 @@ function fetchPonyfill(info, init) {
832
940
  if (mimeType.endsWith(BASE64_SUFFIX)) {
833
941
  const buffer = Buffer.from(data, 'base64');
834
942
  const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
835
- const response = new PonyfillResponse(buffer, {
943
+ const file = new PonyfillBlob([buffer], { type: realMimeType });
944
+ const response = new PonyfillResponse(file, {
836
945
  status: 200,
837
946
  statusText: 'OK',
838
- headers: {
839
- 'content-type': realMimeType,
840
- },
841
947
  });
842
948
  resolve(response);
843
949
  return;
package/index.mjs CHANGED
@@ -3,9 +3,9 @@ import { request as request$1 } from 'http';
3
3
  import { request } from 'https';
4
4
  import { Readable } from 'stream';
5
5
  import { fileURLToPath } from 'url';
6
+ import { Blob } from 'buffer';
6
7
  import { EventTarget, CustomEvent } from '@whatwg-node/events';
7
8
  import busboy from 'busboy';
8
- import { Blob } from 'buffer';
9
9
 
10
10
  // Will be removed after v14 reaches EOL
11
11
  class PonyfillAbortError extends Error {
@@ -24,48 +24,6 @@ class PonyfillAbortError extends Error {
24
24
  }
25
25
  }
26
26
 
27
- // Will be removed after v14 reaches EOL
28
- class PonyfillAbortSignal extends EventTarget {
29
- constructor() {
30
- super(...arguments);
31
- this.aborted = false;
32
- this._onabort = null;
33
- }
34
- throwIfAborted() {
35
- if (this.aborted) {
36
- throw new PonyfillAbortError();
37
- }
38
- }
39
- get onabort() {
40
- return this._onabort;
41
- }
42
- set onabort(value) {
43
- if (this._onabort) {
44
- this.removeEventListener('abort', this._onabort);
45
- }
46
- this.addEventListener('abort', value);
47
- }
48
- abort(reason) {
49
- const abortEvent = new CustomEvent('abort', { detail: reason });
50
- this.dispatchEvent(abortEvent);
51
- }
52
- static timeout(milliseconds) {
53
- const signal = new PonyfillAbortSignal();
54
- setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
55
- return signal;
56
- }
57
- }
58
-
59
- // Will be removed after v14 reaches EOL
60
- class PonyfillAbortController {
61
- constructor() {
62
- this.signal = new PonyfillAbortSignal();
63
- }
64
- abort(reason) {
65
- this.signal.abort(reason);
66
- }
67
- }
68
-
69
27
  function createController(desiredSize, readable) {
70
28
  let chunks = [];
71
29
  return {
@@ -226,6 +184,48 @@ class PonyfillBlob extends Blob {
226
184
  }
227
185
  }
228
186
 
187
+ // Will be removed after v14 reaches EOL
188
+ class PonyfillAbortSignal extends EventTarget {
189
+ constructor() {
190
+ super(...arguments);
191
+ this.aborted = false;
192
+ this._onabort = null;
193
+ }
194
+ throwIfAborted() {
195
+ if (this.aborted) {
196
+ throw new PonyfillAbortError();
197
+ }
198
+ }
199
+ get onabort() {
200
+ return this._onabort;
201
+ }
202
+ set onabort(value) {
203
+ if (this._onabort) {
204
+ this.removeEventListener('abort', this._onabort);
205
+ }
206
+ this.addEventListener('abort', value);
207
+ }
208
+ abort(reason) {
209
+ const abortEvent = new CustomEvent('abort', { detail: reason });
210
+ this.dispatchEvent(abortEvent);
211
+ }
212
+ static timeout(milliseconds) {
213
+ const signal = new PonyfillAbortSignal();
214
+ setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
215
+ return signal;
216
+ }
217
+ }
218
+
219
+ // Will be removed after v14 reaches EOL
220
+ class PonyfillAbortController {
221
+ constructor() {
222
+ this.signal = new PonyfillAbortSignal();
223
+ }
224
+ abort(reason) {
225
+ this.signal.abort(reason);
226
+ }
227
+ }
228
+
229
229
  class PonyfillFile extends PonyfillBlob {
230
230
  constructor(fileBits, name, options) {
231
231
  super(fileBits, options);
@@ -347,26 +347,38 @@ var BodyInitType;
347
347
  BodyInitType["ArrayBuffer"] = "ArrayBuffer";
348
348
  BodyInitType["String"] = "String";
349
349
  BodyInitType["Readable"] = "Readable";
350
+ BodyInitType["Buffer"] = "Buffer";
351
+ BodyInitType["Uint8Array"] = "Uint8Array";
350
352
  })(BodyInitType || (BodyInitType = {}));
351
353
  class PonyfillBody {
352
354
  constructor(bodyInit, options = {}) {
353
355
  this.bodyInit = bodyInit;
354
356
  this.options = options;
355
357
  this.bodyUsed = false;
356
- this._body = null;
357
358
  this.contentType = null;
358
359
  this.contentLength = null;
359
- const { body, contentType, contentLength, bodyType } = processBodyInit(bodyInit);
360
- this._body = body;
360
+ this._bodyFactory = () => null;
361
+ this._generatedBody = null;
362
+ const { bodyFactory, contentType, contentLength, bodyType } = processBodyInit(bodyInit);
363
+ this._bodyFactory = bodyFactory;
361
364
  this.contentType = contentType;
362
365
  this.contentLength = contentLength;
363
366
  this.bodyType = bodyType;
364
367
  }
368
+ generateBody() {
369
+ if (this._generatedBody) {
370
+ return this._generatedBody;
371
+ }
372
+ const body = this._bodyFactory();
373
+ this._generatedBody = body;
374
+ return body;
375
+ }
365
376
  get body() {
366
- if (this._body != null) {
367
- const ponyfillReadableStream = this._body;
368
- const readable = this._body.readable;
369
- return new Proxy(this._body.readable, {
377
+ const _body = this.generateBody();
378
+ if (_body != null) {
379
+ const ponyfillReadableStream = _body;
380
+ const readable = _body.readable;
381
+ return new Proxy(_body.readable, {
370
382
  get(_, prop) {
371
383
  if (prop in ponyfillReadableStream) {
372
384
  const ponyfillReadableStreamProp = ponyfillReadableStream[prop];
@@ -391,6 +403,9 @@ class PonyfillBody {
391
403
  if (this.bodyType === BodyInitType.ArrayBuffer) {
392
404
  return this.bodyInit;
393
405
  }
406
+ if (this.bodyType === BodyInitType.Uint8Array || this.bodyType === BodyInitType.Buffer) {
407
+ return this.bodyInit.buffer;
408
+ }
394
409
  const blob = await this.blob();
395
410
  return blob.arrayBuffer();
396
411
  }
@@ -398,20 +413,37 @@ class PonyfillBody {
398
413
  if (this.bodyType === BodyInitType.Blob) {
399
414
  return this.bodyInit;
400
415
  }
416
+ if (this.bodyType === BodyInitType.String || this.bodyType === BodyInitType.Buffer || this.bodyType === BodyInitType.Uint8Array) {
417
+ const bodyInitTyped = this.bodyInit;
418
+ return new PonyfillBlob([bodyInitTyped], {
419
+ type: this.contentType || '',
420
+ });
421
+ }
422
+ if (this.bodyType === BodyInitType.ArrayBuffer) {
423
+ const bodyInitTyped = this.bodyInit;
424
+ const buf = Buffer.from(bodyInitTyped, undefined, bodyInitTyped.byteLength);
425
+ return new PonyfillBlob([buf], {
426
+ type: this.contentType || '',
427
+ });
428
+ }
401
429
  const chunks = [];
402
- if (this._body) {
403
- for await (const chunk of this._body.readable) {
430
+ const _body = this.generateBody();
431
+ if (_body) {
432
+ for await (const chunk of _body.readable) {
404
433
  chunks.push(chunk);
405
434
  }
406
435
  }
407
- return new PonyfillBlob(chunks);
436
+ return new PonyfillBlob(chunks, {
437
+ type: this.contentType || '',
438
+ });
408
439
  }
409
440
  formData(opts) {
410
441
  if (this.bodyType === BodyInitType.FormData) {
411
442
  return Promise.resolve(this.bodyInit);
412
443
  }
413
444
  const formData = new PonyfillFormData();
414
- if (this._body == null) {
445
+ const _body = this.generateBody();
446
+ if (_body == null) {
415
447
  return Promise.resolve(formData);
416
448
  }
417
449
  const formDataLimits = {
@@ -419,7 +451,6 @@ class PonyfillBody {
419
451
  ...opts === null || opts === void 0 ? void 0 : opts.formDataLimits,
420
452
  };
421
453
  return new Promise((resolve, reject) => {
422
- var _a;
423
454
  const bb = busboy({
424
455
  headers: {
425
456
  'content-type': this.contentType || '',
@@ -467,9 +498,22 @@ class PonyfillBody {
467
498
  bb.on('error', err => {
468
499
  reject(err);
469
500
  });
470
- (_a = this._body) === null || _a === void 0 ? void 0 : _a.readable.pipe(bb);
501
+ _body === null || _body === void 0 ? void 0 : _body.readable.pipe(bb);
471
502
  });
472
503
  }
504
+ async buffer() {
505
+ if (this.bodyType === BodyInitType.Buffer) {
506
+ return this.bodyInit;
507
+ }
508
+ if (this.bodyType === BodyInitType.Uint8Array || this.bodyType === BodyInitType.ArrayBuffer) {
509
+ const bodyInitTyped = this.bodyInit;
510
+ const buffer = Buffer.from(bodyInitTyped, 'byteOffset' in bodyInitTyped ? bodyInitTyped.byteOffset : undefined, bodyInitTyped.byteLength);
511
+ return buffer;
512
+ }
513
+ const blob = await this.blob();
514
+ const arrayBuffer = await blob.arrayBuffer();
515
+ return Buffer.from(arrayBuffer, undefined, arrayBuffer.byteLength);
516
+ }
473
517
  async json() {
474
518
  const text = await this.text();
475
519
  return JSON.parse(text);
@@ -478,6 +522,14 @@ class PonyfillBody {
478
522
  if (this.bodyType === BodyInitType.String) {
479
523
  return this.bodyInit;
480
524
  }
525
+ if (this.bodyType === BodyInitType.Buffer) {
526
+ return this.bodyInit.toString('utf-8');
527
+ }
528
+ if (this.bodyType === BodyInitType.ArrayBuffer || this.bodyType === BodyInitType.Uint8Array) {
529
+ const bodyInitTyped = this.bodyInit;
530
+ const buffer = Buffer.from(bodyInitTyped, 'byteOffset' in bodyInitTyped ? bodyInitTyped.byteOffset : undefined, bodyInitTyped.byteLength);
531
+ return buffer.toString('utf-8');
532
+ }
481
533
  const blob = await this.blob();
482
534
  return blob.text();
483
535
  }
@@ -485,114 +537,152 @@ class PonyfillBody {
485
537
  function processBodyInit(bodyInit) {
486
538
  if (bodyInit == null) {
487
539
  return {
488
- body: null,
540
+ bodyFactory: () => null,
489
541
  contentType: null,
490
542
  contentLength: null,
491
543
  };
492
544
  }
493
545
  if (typeof bodyInit === 'string') {
494
- const buffer = Buffer.from(bodyInit);
495
- const readable = Readable.from(buffer);
496
- const body = new PonyfillReadableStream(readable);
497
546
  return {
498
547
  bodyType: BodyInitType.String,
499
548
  contentType: 'text/plain;charset=UTF-8',
500
- contentLength: buffer.length,
501
- body,
549
+ contentLength: bodyInit.length,
550
+ bodyFactory() {
551
+ const buffer = Buffer.from(bodyInit);
552
+ const readable = Readable.from(buffer);
553
+ return new PonyfillReadableStream(readable);
554
+ },
502
555
  };
503
556
  }
504
557
  if (bodyInit instanceof PonyfillReadableStream) {
505
558
  return {
506
559
  bodyType: BodyInitType.ReadableStream,
507
- body: bodyInit,
560
+ bodyFactory: () => bodyInit,
508
561
  contentType: null,
509
562
  contentLength: null,
510
563
  };
511
564
  }
512
565
  if (bodyInit instanceof PonyfillBlob) {
513
- const readable = bodyInit.stream();
514
- const body = new PonyfillReadableStream(readable);
515
566
  return {
516
567
  bodyType: BodyInitType.Blob,
517
568
  contentType: bodyInit.type,
518
569
  contentLength: bodyInit.size,
519
- body,
570
+ bodyFactory() {
571
+ return bodyInit.stream();
572
+ },
520
573
  };
521
574
  }
522
575
  if (bodyInit instanceof PonyfillFormData) {
523
576
  const boundary = Math.random().toString(36).substr(2);
524
577
  const contentType = `multipart/form-data; boundary=${boundary}`;
525
- const body = bodyInit.stream(boundary);
526
578
  return {
527
579
  bodyType: BodyInitType.FormData,
528
580
  contentType,
529
581
  contentLength: null,
530
- body,
582
+ bodyFactory: () => bodyInit.stream(boundary),
583
+ };
584
+ }
585
+ if (bodyInit instanceof Buffer) {
586
+ const contentLength = bodyInit.length;
587
+ return {
588
+ bodyType: BodyInitType.Buffer,
589
+ contentLength,
590
+ contentType: null,
591
+ bodyFactory() {
592
+ const readable = Readable.from(bodyInit);
593
+ const body = new PonyfillReadableStream(readable);
594
+ return body;
595
+ },
596
+ };
597
+ }
598
+ if (bodyInit instanceof Uint8Array) {
599
+ const contentLength = bodyInit.byteLength;
600
+ return {
601
+ bodyType: BodyInitType.Uint8Array,
602
+ contentLength,
603
+ contentType: null,
604
+ bodyFactory() {
605
+ const readable = Readable.from(bodyInit);
606
+ const body = new PonyfillReadableStream(readable);
607
+ return body;
608
+ }
531
609
  };
532
610
  }
533
611
  if ('buffer' in bodyInit) {
534
612
  const contentLength = bodyInit.byteLength;
535
- const buffer = Buffer.from(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength);
536
- const readable = Readable.from(buffer);
537
- const body = new PonyfillReadableStream(readable);
538
613
  return {
539
614
  contentLength,
540
615
  contentType: null,
541
- body,
616
+ bodyFactory() {
617
+ const buffer = Buffer.from(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength);
618
+ const readable = Readable.from(buffer);
619
+ const body = new PonyfillReadableStream(readable);
620
+ return body;
621
+ }
542
622
  };
543
623
  }
544
624
  if (bodyInit instanceof ArrayBuffer) {
545
625
  const contentLength = bodyInit.byteLength;
546
- const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
547
- const readable = Readable.from(buffer);
548
- const body = new PonyfillReadableStream(readable);
549
626
  return {
550
627
  bodyType: BodyInitType.ArrayBuffer,
551
628
  contentType: null,
552
629
  contentLength,
553
- body,
630
+ bodyFactory() {
631
+ const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
632
+ const readable = Readable.from(buffer);
633
+ const body = new PonyfillReadableStream(readable);
634
+ return body;
635
+ }
554
636
  };
555
637
  }
556
638
  if (bodyInit instanceof Readable) {
557
- const body = new PonyfillReadableStream(bodyInit);
558
639
  return {
559
640
  bodyType: BodyInitType.Readable,
560
641
  contentType: null,
561
642
  contentLength: null,
562
- body,
643
+ bodyFactory() {
644
+ const body = new PonyfillReadableStream(bodyInit);
645
+ return body;
646
+ }
563
647
  };
564
648
  }
565
649
  if ('stream' in bodyInit) {
566
- const bodyStream = bodyInit.stream();
567
- const body = new PonyfillReadableStream(bodyStream);
568
650
  return {
569
651
  contentType: bodyInit.type,
570
652
  contentLength: bodyInit.size,
571
- body,
653
+ bodyFactory() {
654
+ const bodyStream = bodyInit.stream();
655
+ const body = new PonyfillReadableStream(bodyStream);
656
+ return body;
657
+ }
572
658
  };
573
659
  }
574
660
  if (bodyInit instanceof URLSearchParams) {
575
661
  const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
576
- const body = new PonyfillReadableStream(Readable.from(bodyInit.toString()));
577
662
  return {
578
663
  bodyType: BodyInitType.String,
579
664
  contentType,
580
665
  contentLength: null,
581
- body,
666
+ bodyFactory() {
667
+ const body = new PonyfillReadableStream(Readable.from(bodyInit.toString()));
668
+ return body;
669
+ }
582
670
  };
583
671
  }
584
672
  if ('forEach' in bodyInit) {
585
- const formData = new PonyfillFormData();
586
- bodyInit.forEach((value, key) => {
587
- formData.append(key, value);
588
- });
589
673
  const boundary = Math.random().toString(36).substr(2);
590
674
  const contentType = `multipart/form-data; boundary=${boundary}`;
591
- const body = formData.stream(boundary);
592
675
  return {
593
676
  contentType,
594
677
  contentLength: null,
595
- body,
678
+ bodyFactory() {
679
+ const formData = new PonyfillFormData();
680
+ bodyInit.forEach((value, key) => {
681
+ formData.append(key, value);
682
+ });
683
+ const body = formData.stream(boundary);
684
+ return body;
685
+ },
596
686
  };
597
687
  }
598
688
  throw new Error('Unknown body type');
@@ -750,6 +840,24 @@ class PonyfillResponse extends PonyfillBody {
750
840
  this.redirected = init.redirected || false;
751
841
  this.type = init.type || 'default';
752
842
  }
843
+ const contentTypeInHeaders = this.headers.get('content-type');
844
+ if (!contentTypeInHeaders) {
845
+ if (this.contentType) {
846
+ this.headers.set('content-type', this.contentType);
847
+ }
848
+ }
849
+ else {
850
+ this.contentType = contentTypeInHeaders;
851
+ }
852
+ const contentLengthInHeaders = this.headers.get('content-length');
853
+ if (!contentLengthInHeaders) {
854
+ if (this.contentLength) {
855
+ this.headers.set('content-length', this.contentLength.toString());
856
+ }
857
+ }
858
+ else {
859
+ this.contentLength = parseInt(contentLengthInHeaders, 10);
860
+ }
753
861
  }
754
862
  get ok() {
755
863
  return this.status >= 200 && this.status < 300;
@@ -826,12 +934,10 @@ function fetchPonyfill(info, init) {
826
934
  if (mimeType.endsWith(BASE64_SUFFIX)) {
827
935
  const buffer = Buffer.from(data, 'base64');
828
936
  const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
829
- const response = new PonyfillResponse(buffer, {
937
+ const file = new PonyfillBlob([buffer], { type: realMimeType });
938
+ const response = new PonyfillResponse(file, {
830
939
  status: 200,
831
940
  statusText: 'OK',
832
- headers: {
833
- 'content-type': realMimeType,
834
- },
835
941
  });
836
942
  resolve(response);
837
943
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/node-fetch",
3
- "version": "0.0.2",
3
+ "version": "0.0.3-alpha-20230205160101-d3a1033",
4
4
  "description": "Fetch API implementation for Node",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {