@whatwg-node/node-fetch 0.5.0-alpha-20230710180612-32e574f → 0.5.0-alpha-20231025080723-49677d8

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/esm/Body.js CHANGED
@@ -4,17 +4,15 @@ import { PonyfillBlob } from './Blob.js';
4
4
  import { PonyfillFile } from './File.js';
5
5
  import { getStreamFromFormData, PonyfillFormData } from './FormData.js';
6
6
  import { PonyfillReadableStream } from './ReadableStream.js';
7
- import { uint8ArrayToArrayBuffer } from './utils.js';
7
+ import { fakePromise, isArrayBufferView } from './utils.js';
8
8
  var BodyInitType;
9
9
  (function (BodyInitType) {
10
10
  BodyInitType["ReadableStream"] = "ReadableStream";
11
11
  BodyInitType["Blob"] = "Blob";
12
12
  BodyInitType["FormData"] = "FormData";
13
- BodyInitType["ArrayBuffer"] = "ArrayBuffer";
14
13
  BodyInitType["String"] = "String";
15
14
  BodyInitType["Readable"] = "Readable";
16
15
  BodyInitType["Buffer"] = "Buffer";
17
- BodyInitType["Uint8Array"] = "Uint8Array";
18
16
  })(BodyInitType || (BodyInitType = {}));
19
17
  export class PonyfillBody {
20
18
  constructor(bodyInit, options = {}) {
@@ -25,11 +23,12 @@ export class PonyfillBody {
25
23
  this.contentLength = null;
26
24
  this._bodyFactory = () => null;
27
25
  this._generatedBody = null;
28
- const { bodyFactory, contentType, contentLength, bodyType } = processBodyInit(bodyInit);
26
+ const { bodyFactory, contentType, contentLength, bodyType, buffer } = processBodyInit(bodyInit);
29
27
  this._bodyFactory = bodyFactory;
30
28
  this.contentType = contentType;
31
29
  this.contentLength = contentLength;
32
30
  this.bodyType = bodyType;
31
+ this._buffer = buffer;
33
32
  }
34
33
  generateBody() {
35
34
  if (this._generatedBody) {
@@ -65,68 +64,50 @@ export class PonyfillBody {
65
64
  }
66
65
  return null;
67
66
  }
68
- async arrayBuffer() {
69
- if (this.bodyType === BodyInitType.ArrayBuffer) {
70
- return this.bodyInit;
71
- }
72
- if (this.bodyType === BodyInitType.Uint8Array || this.bodyType === BodyInitType.Buffer) {
73
- const typedBodyInit = this.bodyInit;
74
- return uint8ArrayToArrayBuffer(typedBodyInit);
75
- }
76
- if (this.bodyType === BodyInitType.String) {
77
- const buffer = Buffer.from(this.bodyInit);
78
- return uint8ArrayToArrayBuffer(buffer);
79
- }
80
- if (this.bodyType === BodyInitType.Blob) {
81
- const blob = this.bodyInit;
82
- const arrayBuffer = await blob.arrayBuffer();
83
- return arrayBuffer;
84
- }
85
- const blob = await this.blob();
86
- return blob.arrayBuffer();
87
- }
88
- async _collectChunksFromReadable() {
89
- const chunks = [];
67
+ _collectChunksFromReadable() {
90
68
  const _body = this.generateBody();
91
- if (_body) {
92
- for await (const chunk of _body.readable) {
93
- chunks.push(chunk);
94
- }
69
+ if (!_body) {
70
+ return fakePromise([]);
95
71
  }
96
- return chunks;
72
+ const chunks = [];
73
+ _body.readable.on('data', chunk => {
74
+ chunks.push(chunk);
75
+ });
76
+ return new Promise((resolve, reject) => {
77
+ _body.readable.once('end', () => {
78
+ resolve(chunks);
79
+ });
80
+ _body.readable.once('error', e => {
81
+ reject(e);
82
+ });
83
+ });
97
84
  }
98
- async blob() {
85
+ blob() {
99
86
  if (this.bodyType === BodyInitType.Blob) {
100
- return this.bodyInit;
87
+ return fakePromise(this.bodyInit);
101
88
  }
102
- if (this.bodyType === BodyInitType.String ||
103
- this.bodyType === BodyInitType.Buffer ||
104
- this.bodyType === BodyInitType.Uint8Array) {
105
- const bodyInitTyped = this.bodyInit;
106
- return new PonyfillBlob([bodyInitTyped], {
89
+ if (this._buffer) {
90
+ const blob = new PonyfillBlob([this._buffer], {
107
91
  type: this.contentType || '',
92
+ size: this.contentLength,
108
93
  });
94
+ return fakePromise(blob);
109
95
  }
110
- if (this.bodyType === BodyInitType.ArrayBuffer) {
111
- const bodyInitTyped = this.bodyInit;
112
- const buf = Buffer.from(bodyInitTyped, undefined, bodyInitTyped.byteLength);
113
- return new PonyfillBlob([buf], {
96
+ return this._collectChunksFromReadable().then(chunks => {
97
+ return new PonyfillBlob(chunks, {
114
98
  type: this.contentType || '',
99
+ size: this.contentLength,
115
100
  });
116
- }
117
- const chunks = await this._collectChunksFromReadable();
118
- return new PonyfillBlob(chunks, {
119
- type: this.contentType || '',
120
101
  });
121
102
  }
122
103
  formData(opts) {
123
104
  if (this.bodyType === BodyInitType.FormData) {
124
- return Promise.resolve(this.bodyInit);
105
+ return fakePromise(this.bodyInit);
125
106
  }
126
107
  const formData = new PonyfillFormData();
127
108
  const _body = this.generateBody();
128
109
  if (_body == null) {
129
- return Promise.resolve(formData);
110
+ return fakePromise(formData);
130
111
  }
131
112
  const formDataLimits = {
132
113
  ...this.options.formDataLimits,
@@ -158,7 +139,7 @@ export class PonyfillBody {
158
139
  reject(new Error(`File size limit exceeded: ${formDataLimits?.fileSize} bytes`));
159
140
  });
160
141
  fileStream.on('data', chunk => {
161
- chunks.push(Buffer.from(chunk));
142
+ chunks.push(chunk);
162
143
  });
163
144
  fileStream.on('close', () => {
164
145
  if (fileStream.truncated) {
@@ -183,39 +164,36 @@ export class PonyfillBody {
183
164
  _body?.readable.pipe(bb);
184
165
  });
185
166
  }
186
- async buffer() {
187
- if (this.bodyType === BodyInitType.Buffer) {
188
- return this.bodyInit;
189
- }
190
- if (this.bodyType === BodyInitType.String) {
191
- return Buffer.from(this.bodyInit);
192
- }
193
- if (this.bodyType === BodyInitType.Uint8Array || this.bodyType === BodyInitType.ArrayBuffer) {
194
- const bodyInitTyped = this.bodyInit;
195
- const buffer = Buffer.from(bodyInitTyped, 'byteOffset' in bodyInitTyped ? bodyInitTyped.byteOffset : undefined, bodyInitTyped.byteLength);
196
- return buffer;
167
+ arrayBuffer() {
168
+ if (this._buffer) {
169
+ return fakePromise(this._buffer);
197
170
  }
198
171
  if (this.bodyType === BodyInitType.Blob) {
199
172
  if (this.bodyInit instanceof PonyfillBlob) {
200
- return this.bodyInit.buffer();
173
+ return this.bodyInit.arrayBuffer();
201
174
  }
202
175
  const bodyInitTyped = this.bodyInit;
203
- const buffer = Buffer.from(await bodyInitTyped.arrayBuffer(), undefined, bodyInitTyped.size);
204
- return buffer;
176
+ return bodyInitTyped
177
+ .arrayBuffer()
178
+ .then(arrayBuffer => Buffer.from(arrayBuffer, undefined, bodyInitTyped.size));
205
179
  }
206
- const chunks = await this._collectChunksFromReadable();
207
- return Buffer.concat(chunks);
180
+ return this._collectChunksFromReadable().then(function concatCollectedChunksFromReadable(chunks) {
181
+ if (chunks.length === 1) {
182
+ return chunks[0];
183
+ }
184
+ return Buffer.concat(chunks);
185
+ });
208
186
  }
209
- async json() {
210
- const text = await this.text();
211
- return JSON.parse(text);
187
+ json() {
188
+ return this.text().then(function parseTextAsJson(text) {
189
+ return JSON.parse(text);
190
+ });
212
191
  }
213
- async text() {
192
+ text() {
214
193
  if (this.bodyType === BodyInitType.String) {
215
- return this.bodyInit;
194
+ return fakePromise(this.bodyInit);
216
195
  }
217
- const buffer = await this.buffer();
218
- return buffer.toString('utf-8');
196
+ return this.arrayBuffer().then(buffer => buffer.toString('utf-8'));
219
197
  }
220
198
  }
221
199
  function processBodyInit(bodyInit) {
@@ -233,18 +211,19 @@ function processBodyInit(bodyInit) {
233
211
  bodyType: BodyInitType.String,
234
212
  contentType: 'text/plain;charset=UTF-8',
235
213
  contentLength,
214
+ buffer,
236
215
  bodyFactory() {
237
216
  const readable = Readable.from(buffer);
238
217
  return new PonyfillReadableStream(readable);
239
218
  },
240
219
  };
241
220
  }
242
- if (bodyInit instanceof Buffer) {
243
- const contentLength = bodyInit.byteLength;
221
+ if (Buffer.isBuffer(bodyInit)) {
244
222
  return {
245
223
  bodyType: BodyInitType.Buffer,
246
- contentLength,
247
224
  contentType: null,
225
+ contentLength: bodyInit.length,
226
+ buffer: bodyInit,
248
227
  bodyFactory() {
249
228
  const readable = Readable.from(bodyInit);
250
229
  const body = new PonyfillReadableStream(readable);
@@ -252,6 +231,20 @@ function processBodyInit(bodyInit) {
252
231
  },
253
232
  };
254
233
  }
234
+ if (isArrayBufferView(bodyInit)) {
235
+ const buffer = Buffer.from(bodyInit.buffer, bodyInit.byteOffset, bodyInit.byteLength);
236
+ return {
237
+ bodyType: BodyInitType.Buffer,
238
+ contentLength: bodyInit.byteLength,
239
+ contentType: null,
240
+ buffer,
241
+ bodyFactory() {
242
+ const readable = Readable.from(buffer);
243
+ const body = new PonyfillReadableStream(readable);
244
+ return body;
245
+ },
246
+ };
247
+ }
255
248
  if (bodyInit instanceof PonyfillReadableStream) {
256
249
  return {
257
250
  bodyType: BodyInitType.ReadableStream,
@@ -260,7 +253,7 @@ function processBodyInit(bodyInit) {
260
253
  contentLength: null,
261
254
  };
262
255
  }
263
- if (bodyInit instanceof PonyfillBlob) {
256
+ if (isBlob(bodyInit)) {
264
257
  return {
265
258
  bodyType: BodyInitType.Blob,
266
259
  contentType: bodyInit.type,
@@ -270,40 +263,15 @@ function processBodyInit(bodyInit) {
270
263
  },
271
264
  };
272
265
  }
273
- if (bodyInit instanceof Uint8Array) {
274
- const contentLength = bodyInit.byteLength;
275
- return {
276
- bodyType: BodyInitType.Uint8Array,
277
- contentLength,
278
- contentType: null,
279
- bodyFactory() {
280
- const readable = Readable.from(bodyInit);
281
- const body = new PonyfillReadableStream(readable);
282
- return body;
283
- },
284
- };
285
- }
286
- if ('buffer' in bodyInit) {
287
- const contentLength = bodyInit.byteLength;
288
- return {
289
- contentLength,
290
- contentType: null,
291
- bodyFactory() {
292
- const buffer = Buffer.from(bodyInit);
293
- const readable = Readable.from(buffer);
294
- const body = new PonyfillReadableStream(readable);
295
- return body;
296
- },
297
- };
298
- }
299
266
  if (bodyInit instanceof ArrayBuffer) {
300
267
  const contentLength = bodyInit.byteLength;
268
+ const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
301
269
  return {
302
- bodyType: BodyInitType.ArrayBuffer,
270
+ bodyType: BodyInitType.Buffer,
303
271
  contentType: null,
304
272
  contentLength,
273
+ buffer,
305
274
  bodyFactory() {
306
- const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
307
275
  const readable = Readable.from(buffer);
308
276
  const body = new PonyfillReadableStream(readable);
309
277
  return body;
@@ -321,18 +289,7 @@ function processBodyInit(bodyInit) {
321
289
  },
322
290
  };
323
291
  }
324
- if ('stream' in bodyInit) {
325
- return {
326
- contentType: bodyInit.type,
327
- contentLength: bodyInit.size,
328
- bodyFactory() {
329
- const bodyStream = bodyInit.stream();
330
- const body = new PonyfillReadableStream(bodyStream);
331
- return body;
332
- },
333
- };
334
- }
335
- if ('sort' in bodyInit) {
292
+ if (isURLSearchParams(bodyInit)) {
336
293
  const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
337
294
  return {
338
295
  bodyType: BodyInitType.String,
@@ -344,10 +301,11 @@ function processBodyInit(bodyInit) {
344
301
  },
345
302
  };
346
303
  }
347
- if ('forEach' in bodyInit) {
304
+ if (isFormData(bodyInit)) {
348
305
  const boundary = Math.random().toString(36).substr(2);
349
306
  const contentType = `multipart/form-data; boundary=${boundary}`;
350
307
  return {
308
+ bodyType: BodyInitType.FormData,
351
309
  contentType,
352
310
  contentLength: null,
353
311
  bodyFactory() {
@@ -367,3 +325,12 @@ function processBodyInit(bodyInit) {
367
325
  }
368
326
  throw new Error('Unknown body type');
369
327
  }
328
+ function isFormData(value) {
329
+ return value?.forEach != null;
330
+ }
331
+ function isBlob(value) {
332
+ return value?.stream != null;
333
+ }
334
+ function isURLSearchParams(value) {
335
+ return value?.sort != null;
336
+ }
package/esm/FormData.js CHANGED
@@ -1,4 +1,3 @@
1
- import { PonyfillFile } from './File.js';
2
1
  import { PonyfillReadableStream } from './ReadableStream.js';
3
2
  export class PonyfillFormData {
4
3
  constructor() {
@@ -113,17 +112,9 @@ export function getStreamFromFormData(formData, boundary = '---') {
113
112
  });
114
113
  }
115
114
  function getNormalizedFile(name, blob, fileName) {
116
- if (blob instanceof PonyfillFile) {
117
- if (fileName != null) {
118
- return new PonyfillFile([blob], fileName, {
119
- type: blob.type,
120
- lastModified: blob.lastModified,
121
- });
122
- }
123
- return blob;
124
- }
125
- return new PonyfillFile([blob], fileName || name, { type: blob.type });
115
+ blob.name = fileName || blob.name || name;
116
+ return blob;
126
117
  }
127
118
  function isBlob(value) {
128
- return value != null && typeof value === 'object' && typeof value.arrayBuffer === 'function';
119
+ return value?.arrayBuffer != null;
129
120
  }
package/esm/Headers.js CHANGED
@@ -20,7 +20,7 @@ export class PonyfillHeaders {
20
20
  }
21
21
  const normalized = key.toLowerCase();
22
22
  if (Array.isArray(this.headersInit)) {
23
- return this.headersInit.find(header => header[0] === normalized)?.[1] || null;
23
+ return this.headersInit.find(header => header[0].toLowerCase() === normalized)?.[1] || null;
24
24
  }
25
25
  else if (isHeadersLike(this.headersInit)) {
26
26
  return this.headersInit.get(normalized);
@@ -33,23 +33,29 @@ function createController(desiredSize, readable) {
33
33
  _flush() {
34
34
  flushed = true;
35
35
  if (chunks.length > 0) {
36
- const concatenated = Buffer.concat(chunks);
36
+ const concatenated = chunks.length > 1 ? Buffer.concat(chunks) : chunks[0];
37
37
  readable.push(concatenated);
38
38
  chunks = [];
39
39
  }
40
40
  },
41
41
  };
42
42
  }
43
+ function isNodeReadable(obj) {
44
+ return obj?.read != null;
45
+ }
46
+ function isReadableStream(obj) {
47
+ return obj?.getReader != null;
48
+ }
43
49
  export class PonyfillReadableStream {
44
50
  constructor(underlyingSource) {
45
51
  this.locked = false;
46
52
  if (underlyingSource instanceof PonyfillReadableStream) {
47
53
  this.readable = underlyingSource.readable;
48
54
  }
49
- else if (underlyingSource && 'read' in underlyingSource) {
55
+ else if (isNodeReadable(underlyingSource)) {
50
56
  this.readable = underlyingSource;
51
57
  }
52
- else if (underlyingSource && 'getReader' in underlyingSource) {
58
+ else if (isReadableStream(underlyingSource)) {
53
59
  let reader;
54
60
  let started = false;
55
61
  this.readable = new Readable({
@@ -159,6 +165,6 @@ export class PonyfillReadableStream {
159
165
  return readable;
160
166
  }
161
167
  static [Symbol.hasInstance](instance) {
162
- return instance != null && typeof instance === 'object' && 'getReader' in instance;
168
+ return isReadableStream(instance);
163
169
  }
164
170
  }
package/esm/Request.js CHANGED
@@ -3,6 +3,9 @@ import { isHeadersLike, PonyfillHeaders } from './Headers.js';
3
3
  function isRequest(input) {
4
4
  return input[Symbol.toStringTag] === 'Request';
5
5
  }
6
+ function isURL(obj) {
7
+ return obj?.href != null;
8
+ }
6
9
  export class PonyfillRequest extends PonyfillBody {
7
10
  constructor(input, options) {
8
11
  let url;
@@ -11,7 +14,7 @@ export class PonyfillRequest extends PonyfillBody {
11
14
  if (typeof input === 'string') {
12
15
  url = input;
13
16
  }
14
- else if ('href' in input) {
17
+ else if (isURL(input)) {
15
18
  url = input.toString();
16
19
  }
17
20
  else if (isRequest(input)) {
@@ -1,3 +1,4 @@
1
+ import { isArrayBufferView } from './utils.js';
1
2
  export class PonyfillTextEncoder {
2
3
  constructor(encoding = 'utf-8') {
3
4
  this.encoding = encoding;
@@ -25,6 +26,12 @@ export class PonyfillTextDecoder {
25
26
  }
26
27
  }
27
28
  decode(input) {
29
+ if (Buffer.isBuffer(input)) {
30
+ return input.toString(this.encoding);
31
+ }
32
+ if (isArrayBufferView(input)) {
33
+ return Buffer.from(input.buffer, input.byteOffset, input.byteLength).toString(this.encoding);
34
+ }
28
35
  return Buffer.from(input).toString(this.encoding);
29
36
  }
30
37
  }
@@ -1,4 +1,7 @@
1
1
  import FastQuerystring from 'fast-querystring';
2
+ function isURLSearchParams(value) {
3
+ return value?.entries != null;
4
+ }
2
5
  export class PonyfillURLSearchParams {
3
6
  constructor(init) {
4
7
  if (init) {
@@ -11,7 +14,7 @@ export class PonyfillURLSearchParams {
11
14
  this.params[key] = value;
12
15
  }
13
16
  }
14
- else if ('entries' in init) {
17
+ else if (isURLSearchParams(init)) {
15
18
  this.params = {};
16
19
  for (const [key, value] of init.entries()) {
17
20
  this.params[key] = value;
package/esm/fetch.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createReadStream } from 'fs';
2
2
  import { fileURLToPath } from 'url';
3
- import { PonyfillBlob } from './Blob.js';
4
3
  import { fetchCurl } from './fetchCurl.js';
5
4
  import { fetchNodeHttp } from './fetchNodeHttp.js';
6
5
  import { PonyfillRequest } from './Request.js';
7
6
  import { PonyfillResponse } from './Response.js';
7
+ import { fakePromise } from './utils.js';
8
8
  const BASE64_SUFFIX = ';base64';
9
9
  function getResponseForFile(url) {
10
10
  const path = fileURLToPath(url);
@@ -12,15 +12,17 @@ function getResponseForFile(url) {
12
12
  return new PonyfillResponse(readable);
13
13
  }
14
14
  function getResponseForDataUri(url) {
15
- const [mimeType = 'text/plain', ...datas] = url.split(',');
15
+ const [mimeType = 'text/plain', ...datas] = url.substring(5).split(',');
16
16
  const data = decodeURIComponent(datas.join(','));
17
17
  if (mimeType.endsWith(BASE64_SUFFIX)) {
18
18
  const buffer = Buffer.from(data, 'base64url');
19
19
  const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
20
- const file = new PonyfillBlob([buffer], { type: realMimeType });
21
- return new PonyfillResponse(file, {
20
+ return new PonyfillResponse(buffer, {
22
21
  status: 200,
23
22
  statusText: 'OK',
23
+ headers: {
24
+ 'content-type': realMimeType,
25
+ },
24
26
  });
25
27
  }
26
28
  return new PonyfillResponse(data, {
@@ -31,19 +33,22 @@ function getResponseForDataUri(url) {
31
33
  },
32
34
  });
33
35
  }
34
- export async function fetchPonyfill(info, init) {
35
- if (typeof info === 'string' || 'href' in info) {
36
+ function isURL(obj) {
37
+ return obj != null && obj.href != null;
38
+ }
39
+ export function fetchPonyfill(info, init) {
40
+ if (typeof info === 'string' || isURL(info)) {
36
41
  const ponyfillRequest = new PonyfillRequest(info, init);
37
42
  return fetchPonyfill(ponyfillRequest);
38
43
  }
39
44
  const fetchRequest = info;
40
45
  if (fetchRequest.url.startsWith('data:')) {
41
46
  const response = getResponseForDataUri(fetchRequest.url);
42
- return Promise.resolve(response);
47
+ return fakePromise(response);
43
48
  }
44
49
  if (fetchRequest.url.startsWith('file:')) {
45
50
  const response = getResponseForFile(fetchRequest.url);
46
- return Promise.resolve(response);
51
+ return fakePromise(response);
47
52
  }
48
53
  if (globalThis.libcurl) {
49
54
  return fetchCurl(fetchRequest);