@whatwg-node/node-fetch 0.0.1-alpha-20221005123855-1e2f172

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/index.js ADDED
@@ -0,0 +1,624 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const http = require('http');
6
+ const https = require('https');
7
+ const buffer = require('buffer');
8
+ const stream = require('stream');
9
+
10
+ class PonyfillAbortError extends Error {
11
+ constructor() {
12
+ super('The operation was aborted.');
13
+ this.name = 'AbortError';
14
+ }
15
+ }
16
+
17
+ class PonyfillAbortSignal extends EventTarget {
18
+ constructor() {
19
+ super(...arguments);
20
+ this.aborted = false;
21
+ this._onabort = null;
22
+ }
23
+ throwIfAborted() {
24
+ throw new PonyfillAbortError();
25
+ }
26
+ get onabort() {
27
+ return this._onabort;
28
+ }
29
+ set onabort(value) {
30
+ if (this._onabort) {
31
+ this.removeEventListener('abort', this._onabort);
32
+ }
33
+ this.addEventListener('abort', value);
34
+ }
35
+ }
36
+
37
+ class PonyfillAbortController {
38
+ constructor() {
39
+ this.signal = new PonyfillAbortSignal();
40
+ }
41
+ abort(reason) {
42
+ this.signal.dispatchEvent(Object.assign(new Event('abort'), { reason }));
43
+ }
44
+ }
45
+
46
+ const PonyfillBlob = buffer.Blob;
47
+
48
+ class PonyfillFile extends PonyfillBlob {
49
+ constructor(fileBits, name, options) {
50
+ super(fileBits, options);
51
+ this.name = name;
52
+ this.webkitRelativePath = '';
53
+ this.lastModified = (options === null || options === void 0 ? void 0 : options.lastModified) || Date.now();
54
+ }
55
+ }
56
+
57
+ class PonyfillFormData {
58
+ constructor() {
59
+ this.map = new Map();
60
+ }
61
+ append(name, value, fileName) {
62
+ let values = this.map.get(name);
63
+ if (!values) {
64
+ values = [];
65
+ this.map.set(name, values);
66
+ }
67
+ const entry = value instanceof PonyfillBlob ? this.getNormalizedFile(name, value, fileName) : value;
68
+ values.push(entry);
69
+ }
70
+ delete(name) {
71
+ this.map.delete(name);
72
+ }
73
+ get(name) {
74
+ const values = this.map.get(name);
75
+ return values ? values[0] : null;
76
+ }
77
+ getAll(name) {
78
+ return this.map.get(name) || [];
79
+ }
80
+ has(name) {
81
+ return this.map.has(name);
82
+ }
83
+ set(name, value, fileName) {
84
+ const entry = value instanceof PonyfillBlob ? this.getNormalizedFile(name, value, fileName) : value;
85
+ this.map.set(name, [entry]);
86
+ }
87
+ getNormalizedFile(name, blob, fileName) {
88
+ if (blob instanceof PonyfillFile) {
89
+ if (fileName == null) {
90
+ return new PonyfillFile([blob], name, { type: blob.type, lastModified: blob.lastModified });
91
+ }
92
+ return blob;
93
+ }
94
+ return new PonyfillFile([blob], fileName || name, { type: blob.type });
95
+ }
96
+ forEach(callback) {
97
+ for (const [key, values] of this.map) {
98
+ for (const value of values) {
99
+ callback(value, key, this);
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ function createController(desiredSize, readable) {
106
+ return {
107
+ desiredSize,
108
+ enqueue(chunk) {
109
+ readable.push(chunk);
110
+ },
111
+ close() {
112
+ readable.push(null);
113
+ },
114
+ error(error) {
115
+ readable.destroy(error);
116
+ }
117
+ };
118
+ }
119
+ class PonyfillReadableStream {
120
+ constructor(underlyingSource) {
121
+ this.locked = false;
122
+ let started = false;
123
+ if (underlyingSource instanceof PonyfillReadableStream) {
124
+ this.readable = underlyingSource.readable;
125
+ }
126
+ else if (underlyingSource && 'read' in underlyingSource) {
127
+ this.readable = underlyingSource;
128
+ }
129
+ else if (underlyingSource && 'getReader' in underlyingSource) {
130
+ const reader = underlyingSource.getReader();
131
+ this.readable = new stream.Readable({
132
+ read() {
133
+ reader.read().then(({ value, done }) => {
134
+ if (done) {
135
+ this.push(null);
136
+ }
137
+ else {
138
+ this.push(value);
139
+ }
140
+ }).catch(err => {
141
+ this.destroy(err);
142
+ });
143
+ },
144
+ destroy(err, callback) {
145
+ reader.cancel(err).then(() => callback(err), callback);
146
+ }
147
+ });
148
+ }
149
+ else {
150
+ this.readable = new stream.Readable({
151
+ read(desiredSize) {
152
+ var _a, _b;
153
+ if (!started) {
154
+ started = true;
155
+ (_a = underlyingSource === null || underlyingSource === void 0 ? void 0 : underlyingSource.start) === null || _a === void 0 ? void 0 : _a.call(underlyingSource, createController(desiredSize, this));
156
+ }
157
+ (_b = underlyingSource === null || underlyingSource === void 0 ? void 0 : underlyingSource.pull) === null || _b === void 0 ? void 0 : _b.call(underlyingSource, createController(desiredSize, this));
158
+ },
159
+ async destroy(err, callback) {
160
+ var _a;
161
+ try {
162
+ await ((_a = underlyingSource === null || underlyingSource === void 0 ? void 0 : underlyingSource.cancel) === null || _a === void 0 ? void 0 : _a.call(underlyingSource, err));
163
+ callback(null);
164
+ }
165
+ catch (err) {
166
+ callback(err);
167
+ }
168
+ }
169
+ });
170
+ }
171
+ }
172
+ cancel(reason) {
173
+ this.readable.destroy(reason);
174
+ return Promise.resolve();
175
+ }
176
+ getReader() {
177
+ const iterator = this.readable[Symbol.asyncIterator]();
178
+ return {
179
+ read() {
180
+ return iterator.next();
181
+ },
182
+ releaseLock: () => {
183
+ var _a;
184
+ (_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator);
185
+ this.locked = false;
186
+ },
187
+ cancel: async (reason) => {
188
+ var _a;
189
+ await ((_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator, reason));
190
+ this.locked = false;
191
+ },
192
+ closed: new Promise((resolve, reject) => {
193
+ this.readable.once('end', resolve);
194
+ this.readable.once('error', reject);
195
+ }),
196
+ };
197
+ }
198
+ [Symbol.asyncIterator]() {
199
+ return this.readable[Symbol.asyncIterator]();
200
+ }
201
+ tee() {
202
+ throw new Error('Not implemented');
203
+ }
204
+ async pipeTo(destination) {
205
+ const writer = destination.getWriter();
206
+ await writer.ready;
207
+ for await (const chunk of this.readable) {
208
+ await writer.write(chunk);
209
+ }
210
+ await writer.ready;
211
+ return writer.close();
212
+ }
213
+ pipeThrough({ writable, readable }) {
214
+ this.pipeTo(writable);
215
+ return readable;
216
+ }
217
+ }
218
+
219
+ var BodyInitType;
220
+ (function (BodyInitType) {
221
+ BodyInitType["ReadableStream"] = "ReadableStream";
222
+ BodyInitType["Blob"] = "Blob";
223
+ BodyInitType["FormData"] = "FormData";
224
+ BodyInitType["ArrayBuffer"] = "ArrayBuffer";
225
+ BodyInitType["String"] = "String";
226
+ BodyInitType["Readable"] = "Readable";
227
+ })(BodyInitType || (BodyInitType = {}));
228
+ class BodyPonyfill {
229
+ constructor(bodyInit) {
230
+ this.bodyInit = bodyInit;
231
+ this.bodyUsed = false;
232
+ this.contentType = null;
233
+ this.contentLength = null;
234
+ this._bodyProcessed = false;
235
+ this._processedBody = null;
236
+ }
237
+ get body() {
238
+ if (!this._bodyProcessed) {
239
+ this._processedBody = this.processBody();
240
+ this._bodyProcessed = true;
241
+ }
242
+ return this._processedBody;
243
+ }
244
+ processBody() {
245
+ if (this.bodyInit == null) {
246
+ return null;
247
+ }
248
+ if (typeof this.bodyInit === 'string') {
249
+ this.bodyType = BodyInitType.String;
250
+ const buffer = Buffer.from(this.bodyInit);
251
+ this.contentType = 'text/plain;charset=UTF-8';
252
+ this.contentLength = buffer.length;
253
+ return new PonyfillReadableStream(stream.Readable.from(buffer));
254
+ }
255
+ else if (this.bodyInit instanceof PonyfillReadableStream) {
256
+ this.bodyType = BodyInitType.ReadableStream;
257
+ return this.bodyInit;
258
+ }
259
+ else if (this.bodyInit instanceof PonyfillBlob) {
260
+ this.bodyType = BodyInitType.Blob;
261
+ const blobStream = this.bodyInit.stream();
262
+ this.contentType = this.bodyInit.type;
263
+ this.contentLength = this.bodyInit.size;
264
+ return new PonyfillReadableStream(blobStream);
265
+ }
266
+ else if (this.bodyInit instanceof PonyfillFormData) {
267
+ this.bodyType = BodyInitType.FormData;
268
+ const boundary = Math.random().toString(36).substr(2);
269
+ const formData = this.bodyInit;
270
+ this.contentType = `multipart/form-data; boundary=${boundary}`;
271
+ return new PonyfillReadableStream({
272
+ start: async (controller) => {
273
+ controller.enqueue(Buffer.from(`--${boundary}\r\n`));
274
+ const entries = [];
275
+ formData.forEach((value, key) => {
276
+ entries.push([key, value]);
277
+ });
278
+ for (const i in entries) {
279
+ const [key, value] = entries[i];
280
+ if (value instanceof PonyfillBlob) {
281
+ let filenamePart = '';
282
+ if (value.name) {
283
+ filenamePart = `; filename="${value.name}"`;
284
+ }
285
+ controller.enqueue(Buffer.from(`Content-Disposition: form-data; name="${key}"${filenamePart}\r\n`));
286
+ controller.enqueue(Buffer.from(`Content-Type: ${value.type || 'application/octet-stream'}\r\n\r\n`));
287
+ controller.enqueue(Buffer.from(await value.arrayBuffer()));
288
+ }
289
+ else {
290
+ controller.enqueue(Buffer.from(`Content-Disposition: form-data; name="${key}"\r\n\r\n`));
291
+ controller.enqueue(Buffer.from(value));
292
+ }
293
+ if (Number(i) === (entries.length - 1)) {
294
+ controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
295
+ }
296
+ else {
297
+ controller.enqueue(Buffer.from(`\r\n--${boundary}\r\n`));
298
+ }
299
+ }
300
+ controller.close();
301
+ }
302
+ });
303
+ }
304
+ else if ('buffer' in this.bodyInit) {
305
+ this.contentLength = this.bodyInit.byteLength;
306
+ return new PonyfillReadableStream(stream.Readable.from(this.bodyInit));
307
+ }
308
+ else if (this.bodyInit instanceof ArrayBuffer) {
309
+ this.bodyType = BodyInitType.ArrayBuffer;
310
+ this.contentLength = this.bodyInit.byteLength;
311
+ return new PonyfillReadableStream(stream.Readable.from(Buffer.from(this.bodyInit)));
312
+ }
313
+ else if (this.bodyInit instanceof stream.Readable) {
314
+ this.bodyType = BodyInitType.Readable;
315
+ return new PonyfillReadableStream(this.bodyInit);
316
+ }
317
+ else {
318
+ throw new Error('Unknown body type');
319
+ }
320
+ }
321
+ async arrayBuffer() {
322
+ if (this.bodyType === BodyInitType.ArrayBuffer) {
323
+ return this.bodyInit;
324
+ }
325
+ const blob = await this.blob();
326
+ return blob.arrayBuffer();
327
+ }
328
+ async blob() {
329
+ if (this.bodyType === BodyInitType.Blob) {
330
+ return this.bodyInit;
331
+ }
332
+ const chunks = [];
333
+ if (this.body) {
334
+ for await (const chunk of this.body.readable) {
335
+ chunks.push(chunk);
336
+ }
337
+ }
338
+ return new PonyfillBlob(chunks);
339
+ }
340
+ async formData() {
341
+ if (this.bodyType === BodyInitType.FormData) {
342
+ return this.bodyInit;
343
+ }
344
+ throw new Error('Not implemented');
345
+ }
346
+ async json() {
347
+ const text = await this.text();
348
+ return JSON.parse(text);
349
+ }
350
+ async text() {
351
+ if (this.bodyType === BodyInitType.String) {
352
+ return this.bodyInit;
353
+ }
354
+ const blob = await this.blob();
355
+ return blob.text();
356
+ }
357
+ readable() {
358
+ if (this.bodyType === BodyInitType.Readable) {
359
+ return this.bodyInit;
360
+ }
361
+ if (this.body != null) {
362
+ return this.body.readable;
363
+ }
364
+ return null;
365
+ }
366
+ }
367
+
368
+ class PonyfillHeaders {
369
+ constructor(headersInit) {
370
+ this.map = new Map();
371
+ if (headersInit != null) {
372
+ if (Array.isArray(headersInit)) {
373
+ for (const [key, value] of headersInit) {
374
+ if (Array.isArray(value)) {
375
+ for (const v of value) {
376
+ this.append(key, v);
377
+ }
378
+ }
379
+ else {
380
+ this.map.set(key, value);
381
+ }
382
+ }
383
+ }
384
+ else if ('get' in headersInit) {
385
+ headersInit.forEach((value, key) => {
386
+ this.set(key, value);
387
+ });
388
+ }
389
+ else {
390
+ for (const key in headersInit) {
391
+ const value = headersInit[key];
392
+ if (Array.isArray(value)) {
393
+ for (const v of value) {
394
+ this.append(key, v);
395
+ }
396
+ }
397
+ else if (value != null) {
398
+ this.set(key, value);
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
404
+ append(name, value) {
405
+ const key = name.toLowerCase();
406
+ if (this.map.has(key)) {
407
+ value = this.map.get(key) + ', ' + value;
408
+ }
409
+ else {
410
+ this.map.set(key, value);
411
+ }
412
+ }
413
+ get(name) {
414
+ const key = name.toLowerCase();
415
+ return this.map.get(key) || null;
416
+ }
417
+ has(name) {
418
+ const key = name.toLowerCase();
419
+ return this.map.has(key);
420
+ }
421
+ set(name, value) {
422
+ const key = name.toLowerCase();
423
+ this.map.set(key, value);
424
+ }
425
+ delete(name) {
426
+ const key = name.toLowerCase();
427
+ this.map.delete(key);
428
+ }
429
+ forEach(callback) {
430
+ this.map.forEach((value, key) => {
431
+ callback(value, key, this);
432
+ });
433
+ }
434
+ }
435
+
436
+ function isRequest(input) {
437
+ return input[Symbol.toStringTag] === 'Request';
438
+ }
439
+ class PonyfillRequest extends BodyPonyfill {
440
+ constructor(input, options) {
441
+ let url;
442
+ let bodyInit = null;
443
+ let requestInit;
444
+ if (typeof input === 'string') {
445
+ url = input;
446
+ }
447
+ else if (input instanceof URL) {
448
+ url = input.toString();
449
+ }
450
+ else if (isRequest(input)) {
451
+ url = input.url;
452
+ bodyInit = input.body;
453
+ requestInit = input;
454
+ }
455
+ if (options != null) {
456
+ bodyInit = options.body || null;
457
+ requestInit = options;
458
+ }
459
+ super(bodyInit);
460
+ this.postProcessedBody = false;
461
+ this.destination = '';
462
+ this.priority = 'auto';
463
+ this.cache = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.cache) || 'default';
464
+ this.credentials = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.credentials) || 'same-origin';
465
+ this.headers = new PonyfillHeaders(requestInit === null || requestInit === void 0 ? void 0 : requestInit.headers);
466
+ this.integrity = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.integrity) || '';
467
+ this.keepalive = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.keepalive) || true;
468
+ this.method = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.method) || 'GET';
469
+ this.mode = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.mode) || 'cors';
470
+ this.redirect = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.redirect) || 'follow';
471
+ this.referrer = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrer) || 'about:client';
472
+ this.referrerPolicy = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.referrerPolicy) || 'no-referrer';
473
+ this.signal = (requestInit === null || requestInit === void 0 ? void 0 : requestInit.signal) || new PonyfillAbortController().signal;
474
+ this.url = url || '';
475
+ if (this.keepalive) {
476
+ if (!this.headers.has('connection')) {
477
+ this.headers.set('connection', 'keep-alive');
478
+ }
479
+ }
480
+ }
481
+ get body() {
482
+ const actualBody = super.body;
483
+ if (!this.postProcessedBody) {
484
+ this.postProcessBody();
485
+ }
486
+ return actualBody;
487
+ }
488
+ postProcessBody() {
489
+ if (!this.headers.has('content-type')) {
490
+ if (this.contentType) {
491
+ this.headers.set('content-type', this.contentType);
492
+ }
493
+ }
494
+ if (!this.headers.has('content-length')) {
495
+ if (this.contentLength) {
496
+ this.headers.set('content-length', this.contentLength.toString());
497
+ }
498
+ }
499
+ }
500
+ clone() {
501
+ return new Request(this);
502
+ }
503
+ }
504
+
505
+ class PonyfillResponse extends BodyPonyfill {
506
+ constructor(body, init) {
507
+ super(body || null);
508
+ this.headers = new PonyfillHeaders();
509
+ this.status = 200;
510
+ this.statusText = 'OK';
511
+ this.url = '';
512
+ this.redirected = false;
513
+ this.type = 'default';
514
+ if (init) {
515
+ this.headers = new PonyfillHeaders(init.headers);
516
+ this.status = init.status || 200;
517
+ this.statusText = init.statusText || 'OK';
518
+ this.url = init.url || '';
519
+ this.redirected = init.redirected || false;
520
+ }
521
+ }
522
+ get ok() {
523
+ return this.status >= 200 && this.status < 300;
524
+ }
525
+ clone() {
526
+ return new PonyfillResponse(this.body, this);
527
+ }
528
+ static error() {
529
+ const response = new PonyfillResponse(null, {
530
+ status: 500,
531
+ statusText: 'Internal Server Error'
532
+ });
533
+ return response;
534
+ }
535
+ static redirect(url, status = 301) {
536
+ if (status < 300 || status > 399) {
537
+ throw new RangeError('Invalid status code');
538
+ }
539
+ return new PonyfillResponse(null, {
540
+ headers: {
541
+ location: url
542
+ },
543
+ status
544
+ });
545
+ }
546
+ }
547
+
548
+ function getHeadersObj(headers) {
549
+ if (headers == null || !('forEach' in headers)) {
550
+ return headers;
551
+ }
552
+ const obj = {};
553
+ headers.forEach((value, key) => {
554
+ obj[key] = value;
555
+ });
556
+ return obj;
557
+ }
558
+
559
+ const fetchPonyfill = (info, init) => {
560
+ if (typeof info === 'string' || info instanceof URL) {
561
+ return fetchPonyfill(new PonyfillRequest(info, init));
562
+ }
563
+ const fetchRequest = info;
564
+ return new Promise((resolve, reject) => {
565
+ try {
566
+ const requestFn = fetchRequest.url.startsWith('https') ? https.request : http.request;
567
+ const nodeReadable = fetchRequest.readable();
568
+ const nodeHeaders = getHeadersObj(fetchRequest.headers);
569
+ const abortListener = function abortListener() {
570
+ reject(new PonyfillAbortError());
571
+ };
572
+ fetchRequest.signal.addEventListener('abort', abortListener);
573
+ const nodeRequest = requestFn(fetchRequest.url, {
574
+ method: fetchRequest.method,
575
+ headers: nodeHeaders,
576
+ signal: fetchRequest.signal,
577
+ }, nodeResponse => {
578
+ if (nodeResponse.headers.location) {
579
+ if (fetchRequest.redirect === 'error') {
580
+ reject(new Error('Redirects are not allowed'));
581
+ nodeResponse.resume();
582
+ return;
583
+ }
584
+ if (fetchRequest.redirect === 'follow') {
585
+ resolve(fetchPonyfill(new URL(nodeResponse.headers.location, info.url), info).then(resp => {
586
+ resp.redirected = true;
587
+ return resp;
588
+ }));
589
+ nodeResponse.resume();
590
+ return;
591
+ }
592
+ }
593
+ const responseHeaders = nodeResponse.headers;
594
+ resolve(new PonyfillResponse(nodeResponse, {
595
+ status: nodeResponse.statusCode,
596
+ statusText: nodeResponse.statusMessage,
597
+ headers: responseHeaders,
598
+ url: info.url,
599
+ }));
600
+ });
601
+ if (nodeReadable) {
602
+ nodeReadable.pipe(nodeRequest);
603
+ }
604
+ else {
605
+ nodeRequest.end();
606
+ }
607
+ }
608
+ catch (e) {
609
+ reject(e);
610
+ }
611
+ });
612
+ };
613
+
614
+ exports.AbortController = PonyfillAbortController;
615
+ exports.AbortError = PonyfillAbortError;
616
+ exports.AbortSignal = PonyfillAbortSignal;
617
+ exports.Blob = PonyfillBlob;
618
+ exports.File = PonyfillFile;
619
+ exports.FormData = PonyfillFormData;
620
+ exports.Headers = PonyfillHeaders;
621
+ exports.ReadableStream = PonyfillReadableStream;
622
+ exports.Request = PonyfillRequest;
623
+ exports.Response = PonyfillResponse;
624
+ exports.fetch = fetchPonyfill;