@whatwg-node/node-fetch 0.3.0 → 0.4.0-alpha-20230215085115-d099e0b

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 (73) hide show
  1. package/cjs/AbortController.js +14 -0
  2. package/cjs/AbortError.js +20 -0
  3. package/cjs/AbortSignal.js +37 -0
  4. package/cjs/Blob.js +119 -0
  5. package/cjs/Body.js +372 -0
  6. package/cjs/File.js +13 -0
  7. package/cjs/FormData.js +121 -0
  8. package/cjs/Headers.js +121 -0
  9. package/cjs/ReadableStream.js +172 -0
  10. package/cjs/Request.js +69 -0
  11. package/cjs/Response.js +75 -0
  12. package/cjs/TextEncoderDecoder.js +39 -0
  13. package/cjs/URL.js +55 -0
  14. package/cjs/URLSearchParams.js +103 -0
  15. package/cjs/fetch.js +127 -0
  16. package/cjs/index.js +35 -0
  17. package/cjs/package.json +1 -0
  18. package/cjs/utils.js +18 -0
  19. package/esm/AbortController.js +10 -0
  20. package/esm/AbortError.js +16 -0
  21. package/esm/AbortSignal.js +33 -0
  22. package/esm/Blob.js +115 -0
  23. package/esm/Body.js +367 -0
  24. package/esm/File.js +9 -0
  25. package/esm/FormData.js +116 -0
  26. package/esm/Headers.js +117 -0
  27. package/esm/ReadableStream.js +168 -0
  28. package/esm/Request.js +65 -0
  29. package/esm/Response.js +71 -0
  30. package/esm/TextEncoderDecoder.js +33 -0
  31. package/esm/URL.js +50 -0
  32. package/esm/URLSearchParams.js +98 -0
  33. package/esm/fetch.js +123 -0
  34. package/esm/index.js +15 -0
  35. package/esm/utils.js +13 -0
  36. package/package.json +19 -12
  37. package/typings/AbortController.d.cts +5 -0
  38. package/{AbortController.d.ts → typings/AbortController.d.ts} +1 -1
  39. package/{AbortError.d.ts → typings/AbortError.d.cts} +0 -0
  40. package/typings/AbortError.d.ts +4 -0
  41. package/{AbortSignal.d.ts → typings/AbortSignal.d.cts} +0 -0
  42. package/typings/AbortSignal.d.ts +11 -0
  43. package/{Blob.d.ts → typings/Blob.d.cts} +0 -0
  44. package/typings/Blob.d.ts +18 -0
  45. package/typings/Body.d.cts +41 -0
  46. package/{Body.d.ts → typings/Body.d.ts} +3 -3
  47. package/typings/File.d.cts +7 -0
  48. package/{File.d.ts → typings/File.d.ts} +1 -1
  49. package/typings/FormData.d.cts +14 -0
  50. package/{FormData.d.ts → typings/FormData.d.ts} +2 -2
  51. package/{Headers.d.ts → typings/Headers.d.cts} +0 -0
  52. package/typings/Headers.d.ts +19 -0
  53. package/{ReadableStream.d.ts → typings/ReadableStream.d.cts} +0 -0
  54. package/typings/ReadableStream.d.ts +20 -0
  55. package/typings/Request.d.cts +24 -0
  56. package/{Request.d.ts → typings/Request.d.ts} +2 -2
  57. package/typings/Response.d.cts +22 -0
  58. package/{Response.d.ts → typings/Response.d.ts} +2 -2
  59. package/{TextEncoderDecoder.d.ts → typings/TextEncoderDecoder.d.cts} +0 -0
  60. package/typings/TextEncoderDecoder.d.ts +15 -0
  61. package/typings/URL.d.cts +14 -0
  62. package/{URL.d.ts → typings/URL.d.ts} +1 -1
  63. package/{URLSearchParams.d.ts → typings/URLSearchParams.d.cts} +0 -0
  64. package/typings/URLSearchParams.d.ts +17 -0
  65. package/typings/fetch.d.cts +3 -0
  66. package/{fetch.d.ts → typings/fetch.d.ts} +2 -2
  67. package/typings/index.d.cts +15 -0
  68. package/typings/index.d.ts +15 -0
  69. package/{utils.d.ts → typings/utils.d.cts} +0 -0
  70. package/typings/utils.d.ts +2 -0
  71. package/index.d.ts +0 -15
  72. package/index.js +0 -1417
  73. package/index.mjs +0 -1395
package/esm/Body.js ADDED
@@ -0,0 +1,367 @@
1
+ import { Readable } from 'stream';
2
+ import busboy from 'busboy';
3
+ import { PonyfillBlob } from './Blob.js';
4
+ import { PonyfillFile } from './File.js';
5
+ import { getStreamFromFormData, PonyfillFormData } from './FormData.js';
6
+ import { PonyfillReadableStream } from './ReadableStream.js';
7
+ import { uint8ArrayToArrayBuffer } from './utils.js';
8
+ var BodyInitType;
9
+ (function (BodyInitType) {
10
+ BodyInitType["ReadableStream"] = "ReadableStream";
11
+ BodyInitType["Blob"] = "Blob";
12
+ BodyInitType["FormData"] = "FormData";
13
+ BodyInitType["ArrayBuffer"] = "ArrayBuffer";
14
+ BodyInitType["String"] = "String";
15
+ BodyInitType["Readable"] = "Readable";
16
+ BodyInitType["Buffer"] = "Buffer";
17
+ BodyInitType["Uint8Array"] = "Uint8Array";
18
+ })(BodyInitType || (BodyInitType = {}));
19
+ export class PonyfillBody {
20
+ constructor(bodyInit, options = {}) {
21
+ this.bodyInit = bodyInit;
22
+ this.options = options;
23
+ this.bodyUsed = false;
24
+ this.contentType = null;
25
+ this.contentLength = null;
26
+ this._bodyFactory = () => null;
27
+ this._generatedBody = null;
28
+ const { bodyFactory, contentType, contentLength, bodyType } = processBodyInit(bodyInit);
29
+ this._bodyFactory = bodyFactory;
30
+ this.contentType = contentType;
31
+ this.contentLength = contentLength;
32
+ this.bodyType = bodyType;
33
+ }
34
+ generateBody() {
35
+ if (this._generatedBody) {
36
+ return this._generatedBody;
37
+ }
38
+ const body = this._bodyFactory();
39
+ this._generatedBody = body;
40
+ return body;
41
+ }
42
+ get body() {
43
+ const _body = this.generateBody();
44
+ if (_body != null) {
45
+ const ponyfillReadableStream = _body;
46
+ const readable = _body.readable;
47
+ return new Proxy(_body.readable, {
48
+ get(_, prop) {
49
+ if (prop in ponyfillReadableStream) {
50
+ const ponyfillReadableStreamProp = ponyfillReadableStream[prop];
51
+ if (typeof ponyfillReadableStreamProp === 'function') {
52
+ return ponyfillReadableStreamProp.bind(ponyfillReadableStream);
53
+ }
54
+ return ponyfillReadableStreamProp;
55
+ }
56
+ if (prop in readable) {
57
+ const readableProp = readable[prop];
58
+ if (typeof readableProp === 'function') {
59
+ return readableProp.bind(readable);
60
+ }
61
+ return readableProp;
62
+ }
63
+ },
64
+ });
65
+ }
66
+ return null;
67
+ }
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 = [];
90
+ const _body = this.generateBody();
91
+ if (_body) {
92
+ for await (const chunk of _body.readable) {
93
+ chunks.push(chunk);
94
+ }
95
+ }
96
+ return chunks;
97
+ }
98
+ async blob() {
99
+ if (this.bodyType === BodyInitType.Blob) {
100
+ return this.bodyInit;
101
+ }
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], {
107
+ type: this.contentType || '',
108
+ });
109
+ }
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], {
114
+ type: this.contentType || '',
115
+ });
116
+ }
117
+ const chunks = await this._collectChunksFromReadable();
118
+ return new PonyfillBlob(chunks, {
119
+ type: this.contentType || '',
120
+ });
121
+ }
122
+ formData(opts) {
123
+ if (this.bodyType === BodyInitType.FormData) {
124
+ return Promise.resolve(this.bodyInit);
125
+ }
126
+ const formData = new PonyfillFormData();
127
+ const _body = this.generateBody();
128
+ if (_body == null) {
129
+ return Promise.resolve(formData);
130
+ }
131
+ const formDataLimits = {
132
+ ...this.options.formDataLimits,
133
+ ...opts === null || opts === void 0 ? void 0 : opts.formDataLimits,
134
+ };
135
+ return new Promise((resolve, reject) => {
136
+ const bb = busboy({
137
+ headers: {
138
+ 'content-type': this.contentType || '',
139
+ },
140
+ limits: formDataLimits,
141
+ defParamCharset: 'utf-8',
142
+ });
143
+ bb.on('field', (name, value, { nameTruncated, valueTruncated }) => {
144
+ if (nameTruncated) {
145
+ reject(new Error(`Field name size exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.fieldNameSize} bytes`));
146
+ }
147
+ if (valueTruncated) {
148
+ reject(new Error(`Field value size exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.fieldSize} bytes`));
149
+ }
150
+ formData.set(name, value);
151
+ });
152
+ bb.on('fieldsLimit', () => {
153
+ reject(new Error(`Fields limit exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.fields}`));
154
+ });
155
+ bb.on('file', (name, fileStream, { filename, mimeType }) => {
156
+ const chunks = [];
157
+ fileStream.on('limit', () => {
158
+ reject(new Error(`File size limit exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.fileSize} bytes`));
159
+ });
160
+ fileStream.on('data', chunk => {
161
+ chunks.push(Buffer.from(chunk));
162
+ });
163
+ fileStream.on('close', () => {
164
+ if (fileStream.truncated) {
165
+ reject(new Error(`File size limit exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.fileSize} bytes`));
166
+ }
167
+ const file = new PonyfillFile(chunks, filename, { type: mimeType });
168
+ formData.set(name, file);
169
+ });
170
+ });
171
+ bb.on('filesLimit', () => {
172
+ reject(new Error(`Files limit exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.files}`));
173
+ });
174
+ bb.on('partsLimit', () => {
175
+ reject(new Error(`Parts limit exceeded: ${formDataLimits === null || formDataLimits === void 0 ? void 0 : formDataLimits.parts}`));
176
+ });
177
+ bb.on('close', () => {
178
+ resolve(formData);
179
+ });
180
+ bb.on('error', err => {
181
+ reject(err);
182
+ });
183
+ _body === null || _body === void 0 ? void 0 : _body.readable.pipe(bb);
184
+ });
185
+ }
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;
197
+ }
198
+ if (this.bodyType === BodyInitType.Blob) {
199
+ if (this.bodyInit instanceof PonyfillBlob) {
200
+ return this.bodyInit.buffer();
201
+ }
202
+ const bodyInitTyped = this.bodyInit;
203
+ const buffer = Buffer.from(await bodyInitTyped.arrayBuffer(), undefined, bodyInitTyped.size);
204
+ return buffer;
205
+ }
206
+ const chunks = await this._collectChunksFromReadable();
207
+ return Buffer.concat(chunks);
208
+ }
209
+ async json() {
210
+ const text = await this.text();
211
+ return JSON.parse(text);
212
+ }
213
+ async text() {
214
+ if (this.bodyType === BodyInitType.String) {
215
+ return this.bodyInit;
216
+ }
217
+ const buffer = await this.buffer();
218
+ return buffer.toString('utf-8');
219
+ }
220
+ }
221
+ function processBodyInit(bodyInit) {
222
+ if (bodyInit == null) {
223
+ return {
224
+ bodyFactory: () => null,
225
+ contentType: null,
226
+ contentLength: null,
227
+ };
228
+ }
229
+ if (typeof bodyInit === 'string') {
230
+ return {
231
+ bodyType: BodyInitType.String,
232
+ contentType: 'text/plain;charset=UTF-8',
233
+ contentLength: Buffer.byteLength(bodyInit),
234
+ bodyFactory() {
235
+ const readable = Readable.from(bodyInit);
236
+ return new PonyfillReadableStream(readable);
237
+ },
238
+ };
239
+ }
240
+ if (bodyInit instanceof PonyfillReadableStream) {
241
+ return {
242
+ bodyType: BodyInitType.ReadableStream,
243
+ bodyFactory: () => bodyInit,
244
+ contentType: null,
245
+ contentLength: null,
246
+ };
247
+ }
248
+ if (bodyInit instanceof PonyfillBlob) {
249
+ return {
250
+ bodyType: BodyInitType.Blob,
251
+ contentType: bodyInit.type,
252
+ contentLength: bodyInit.size,
253
+ bodyFactory() {
254
+ return bodyInit.stream();
255
+ },
256
+ };
257
+ }
258
+ if (bodyInit instanceof Buffer) {
259
+ const contentLength = bodyInit.length;
260
+ return {
261
+ bodyType: BodyInitType.Buffer,
262
+ contentLength,
263
+ contentType: null,
264
+ bodyFactory() {
265
+ const readable = Readable.from(bodyInit);
266
+ const body = new PonyfillReadableStream(readable);
267
+ return body;
268
+ },
269
+ };
270
+ }
271
+ if (bodyInit instanceof Uint8Array) {
272
+ const contentLength = bodyInit.byteLength;
273
+ return {
274
+ bodyType: BodyInitType.Uint8Array,
275
+ contentLength,
276
+ contentType: null,
277
+ bodyFactory() {
278
+ const readable = Readable.from(bodyInit);
279
+ const body = new PonyfillReadableStream(readable);
280
+ return body;
281
+ },
282
+ };
283
+ }
284
+ if ('buffer' in bodyInit) {
285
+ const contentLength = bodyInit.byteLength;
286
+ return {
287
+ contentLength,
288
+ contentType: null,
289
+ bodyFactory() {
290
+ const buffer = Buffer.from(bodyInit);
291
+ const readable = Readable.from(buffer);
292
+ const body = new PonyfillReadableStream(readable);
293
+ return body;
294
+ },
295
+ };
296
+ }
297
+ if (bodyInit instanceof ArrayBuffer) {
298
+ const contentLength = bodyInit.byteLength;
299
+ return {
300
+ bodyType: BodyInitType.ArrayBuffer,
301
+ contentType: null,
302
+ contentLength,
303
+ bodyFactory() {
304
+ const buffer = Buffer.from(bodyInit, undefined, bodyInit.byteLength);
305
+ const readable = Readable.from(buffer);
306
+ const body = new PonyfillReadableStream(readable);
307
+ return body;
308
+ },
309
+ };
310
+ }
311
+ if (bodyInit instanceof Readable) {
312
+ return {
313
+ bodyType: BodyInitType.Readable,
314
+ contentType: null,
315
+ contentLength: null,
316
+ bodyFactory() {
317
+ const body = new PonyfillReadableStream(bodyInit);
318
+ return body;
319
+ },
320
+ };
321
+ }
322
+ if ('stream' in bodyInit) {
323
+ return {
324
+ contentType: bodyInit.type,
325
+ contentLength: bodyInit.size,
326
+ bodyFactory() {
327
+ const bodyStream = bodyInit.stream();
328
+ const body = new PonyfillReadableStream(bodyStream);
329
+ return body;
330
+ },
331
+ };
332
+ }
333
+ if ('sort' in bodyInit) {
334
+ const contentType = 'application/x-www-form-urlencoded;charset=UTF-8';
335
+ return {
336
+ bodyType: BodyInitType.String,
337
+ contentType,
338
+ contentLength: null,
339
+ bodyFactory() {
340
+ const body = new PonyfillReadableStream(Readable.from(bodyInit.toString()));
341
+ return body;
342
+ },
343
+ };
344
+ }
345
+ if ('forEach' in bodyInit) {
346
+ const boundary = Math.random().toString(36).substr(2);
347
+ const contentType = `multipart/form-data; boundary=${boundary}`;
348
+ return {
349
+ contentType,
350
+ contentLength: null,
351
+ bodyFactory() {
352
+ return getStreamFromFormData(bodyInit, boundary);
353
+ },
354
+ };
355
+ }
356
+ if (bodyInit[Symbol.iterator] || bodyInit[Symbol.asyncIterator]) {
357
+ return {
358
+ contentType: null,
359
+ contentLength: null,
360
+ bodyFactory() {
361
+ const readable = Readable.from(bodyInit);
362
+ return new PonyfillReadableStream(readable);
363
+ },
364
+ };
365
+ }
366
+ throw new Error('Unknown body type');
367
+ }
package/esm/File.js ADDED
@@ -0,0 +1,9 @@
1
+ import { PonyfillBlob } from './Blob.js';
2
+ export class PonyfillFile extends PonyfillBlob {
3
+ constructor(fileBits, name, options) {
4
+ super(fileBits, options);
5
+ this.name = name;
6
+ this.webkitRelativePath = '';
7
+ this.lastModified = (options === null || options === void 0 ? void 0 : options.lastModified) || Date.now();
8
+ }
9
+ }
@@ -0,0 +1,116 @@
1
+ import { PonyfillFile } from './File.js';
2
+ import { PonyfillReadableStream } from './ReadableStream.js';
3
+ export class PonyfillFormData {
4
+ constructor() {
5
+ this.map = new Map();
6
+ }
7
+ append(name, value, fileName) {
8
+ let values = this.map.get(name);
9
+ if (!values) {
10
+ values = [];
11
+ this.map.set(name, values);
12
+ }
13
+ const entry = isBlob(value)
14
+ ? getNormalizedFile(name, value, fileName)
15
+ : value;
16
+ values.push(entry);
17
+ }
18
+ delete(name) {
19
+ this.map.delete(name);
20
+ }
21
+ get(name) {
22
+ const values = this.map.get(name);
23
+ return values ? values[0] : null;
24
+ }
25
+ getAll(name) {
26
+ return this.map.get(name) || [];
27
+ }
28
+ has(name) {
29
+ return this.map.has(name);
30
+ }
31
+ set(name, value, fileName) {
32
+ const entry = isBlob(value)
33
+ ? getNormalizedFile(name, value, fileName)
34
+ : value;
35
+ this.map.set(name, [entry]);
36
+ }
37
+ *[Symbol.iterator]() {
38
+ for (const [key, values] of this.map) {
39
+ for (const value of values) {
40
+ yield [key, value];
41
+ }
42
+ }
43
+ }
44
+ forEach(callback) {
45
+ for (const [key, value] of this) {
46
+ callback(value, key, this);
47
+ }
48
+ }
49
+ }
50
+ export function getStreamFromFormData(formData, boundary = '---') {
51
+ const entries = [];
52
+ let sentInitialHeader = false;
53
+ return new PonyfillReadableStream({
54
+ start: controller => {
55
+ formData.forEach((value, key) => {
56
+ if (!sentInitialHeader) {
57
+ controller.enqueue(Buffer.from(`--${boundary}\r\n`));
58
+ sentInitialHeader = true;
59
+ }
60
+ entries.push([key, value]);
61
+ });
62
+ if (!sentInitialHeader) {
63
+ controller.enqueue(Buffer.from(`--${boundary}--\r\n`));
64
+ controller.close();
65
+ }
66
+ },
67
+ pull: async (controller) => {
68
+ const entry = entries.shift();
69
+ if (entry) {
70
+ const [key, value] = entry;
71
+ if (typeof value === 'string') {
72
+ controller.enqueue(Buffer.from(`Content-Disposition: form-data; name="${key}"\r\n\r\n`));
73
+ controller.enqueue(Buffer.from(value));
74
+ }
75
+ else {
76
+ let filenamePart = '';
77
+ if (value.name) {
78
+ filenamePart = `; filename="${value.name}"`;
79
+ }
80
+ controller.enqueue(Buffer.from(`Content-Disposition: form-data; name="${key}"${filenamePart}\r\n`));
81
+ controller.enqueue(Buffer.from(`Content-Type: ${value.type || 'application/octet-stream'}\r\n\r\n`));
82
+ const entryStream = value.stream();
83
+ for await (const chunk of entryStream) {
84
+ controller.enqueue(chunk);
85
+ }
86
+ }
87
+ if (entries.length === 0) {
88
+ controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
89
+ controller.close();
90
+ }
91
+ else {
92
+ controller.enqueue(Buffer.from(`\r\n--${boundary}\r\n`));
93
+ }
94
+ }
95
+ else {
96
+ controller.enqueue(Buffer.from(`\r\n--${boundary}--\r\n`));
97
+ controller.close();
98
+ }
99
+ },
100
+ });
101
+ }
102
+ function getNormalizedFile(name, blob, fileName) {
103
+ if (blob instanceof PonyfillFile) {
104
+ if (fileName != null) {
105
+ return new PonyfillFile([blob], fileName, {
106
+ type: blob.type,
107
+ lastModified: blob.lastModified,
108
+ });
109
+ }
110
+ return blob;
111
+ }
112
+ return new PonyfillFile([blob], fileName || name, { type: blob.type });
113
+ }
114
+ function isBlob(value) {
115
+ return value != null && typeof value === 'object' && typeof value.arrayBuffer === 'function';
116
+ }
package/esm/Headers.js ADDED
@@ -0,0 +1,117 @@
1
+ function isHeadersLike(headers) {
2
+ return headers && typeof headers.get === 'function';
3
+ }
4
+ export class PonyfillHeaders {
5
+ constructor(headersInit) {
6
+ this.headersInit = headersInit;
7
+ this.map = new Map();
8
+ this.mapIsBuilt = false;
9
+ this.objectNormalizedKeysOfHeadersInit = [];
10
+ this.objectOriginalKeysOfHeadersInit = [];
11
+ }
12
+ // perf: we don't need to build `this.map` for Requests, as we can access the headers directly
13
+ _get(key) {
14
+ // If the map is built, reuse it
15
+ if (this.mapIsBuilt) {
16
+ return this.map.get(key.toLowerCase()) || null;
17
+ }
18
+ // If the map is not built, try to get the value from the this.headersInit
19
+ if (this.headersInit == null) {
20
+ return null;
21
+ }
22
+ const normalized = key.toLowerCase();
23
+ if (Array.isArray(this.headersInit)) {
24
+ return this.headersInit.find(header => header[0] === normalized);
25
+ }
26
+ else if (isHeadersLike(this.headersInit)) {
27
+ return this.headersInit.get(normalized);
28
+ }
29
+ else {
30
+ const initValue = this.headersInit[key] || this.headersInit[normalized];
31
+ if (initValue != null) {
32
+ return initValue;
33
+ }
34
+ if (!this.objectNormalizedKeysOfHeadersInit.length) {
35
+ Object.keys(this.headersInit).forEach(k => {
36
+ this.objectOriginalKeysOfHeadersInit.push(k);
37
+ this.objectNormalizedKeysOfHeadersInit.push(k.toLowerCase());
38
+ });
39
+ }
40
+ const index = this.objectNormalizedKeysOfHeadersInit.indexOf(normalized);
41
+ if (index === -1) {
42
+ return null;
43
+ }
44
+ const originalKey = this.objectOriginalKeysOfHeadersInit[index];
45
+ return this.headersInit[originalKey];
46
+ }
47
+ }
48
+ // perf: Build the map of headers lazily, only when we need to access all headers or write to it.
49
+ // I could do a getter here, but I'm too lazy to type `getter`.
50
+ getMap() {
51
+ if (this.mapIsBuilt) {
52
+ return this.map;
53
+ }
54
+ if (this.headersInit != null) {
55
+ if (Array.isArray(this.headersInit)) {
56
+ this.map = new Map(this.headersInit);
57
+ }
58
+ else if (isHeadersLike(this.headersInit)) {
59
+ this.headersInit.forEach((value, key) => {
60
+ this.map.set(key, value);
61
+ });
62
+ }
63
+ else {
64
+ for (const initKey in this.headersInit) {
65
+ const initValue = this.headersInit[initKey];
66
+ if (initValue != null) {
67
+ const normalizedValue = Array.isArray(initValue) ? initValue.join(', ') : initValue;
68
+ const normalizedKey = initKey.toLowerCase();
69
+ this.map.set(normalizedKey, normalizedValue);
70
+ }
71
+ }
72
+ }
73
+ }
74
+ this.mapIsBuilt = true;
75
+ return this.map;
76
+ }
77
+ append(name, value) {
78
+ const key = name.toLowerCase();
79
+ const existingValue = this.getMap().get(key);
80
+ const finalValue = existingValue ? `${existingValue}, ${value}` : value;
81
+ this.getMap().set(key, finalValue);
82
+ }
83
+ get(name) {
84
+ const key = name.toLowerCase();
85
+ const value = this._get(key);
86
+ if (value == null) {
87
+ return null;
88
+ }
89
+ if (Array.isArray(value)) {
90
+ return value.join(', ');
91
+ }
92
+ return value;
93
+ }
94
+ has(name) {
95
+ const key = name.toLowerCase();
96
+ return !!this._get(key); // we might need to check if header exists and not just check if it's not nullable
97
+ }
98
+ set(name, value) {
99
+ const key = name.toLowerCase();
100
+ this.getMap().set(key, value);
101
+ }
102
+ delete(name) {
103
+ const key = name.toLowerCase();
104
+ this.getMap().delete(key);
105
+ }
106
+ forEach(callback) {
107
+ this.getMap().forEach((value, key) => {
108
+ callback(value, key, this);
109
+ });
110
+ }
111
+ entries() {
112
+ return this.getMap().entries();
113
+ }
114
+ [Symbol.iterator]() {
115
+ return this.getMap().entries();
116
+ }
117
+ }