1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (factory((global.WHATWGFetch = {})));
5}(this, (function (exports) { 'use strict';
6
7 /* eslint-disable no-prototype-builtins */
8 var g =
9 (typeof globalThis !== 'undefined' && globalThis) ||
10 (typeof self !== 'undefined' && self) ||
11 // eslint-disable-next-line no-undef
12 (typeof global !== 'undefined' && global) ||
13 {};
14
15 var support = {
16 searchParams: 'URLSearchParams' in g,
17 iterable: 'Symbol' in g && 'iterator' in Symbol,
18 blob:
19 'FileReader' in g &&
20 'Blob' in g &&
21 (function() {
22 try {
23 new Blob();
24 return true
25 } catch (e) {
26 return false
27 }
28 })(),
29 formData: 'FormData' in g,
30 arrayBuffer: 'ArrayBuffer' in g
31 };
32
33 function isDataView(obj) {
34 return obj && DataView.prototype.isPrototypeOf(obj)
35 }
36
37 if (support.arrayBuffer) {
38 var viewClasses = [
39 '[object Int8Array]',
40 '[object Uint8Array]',
41 '[object Uint8ClampedArray]',
42 '[object Int16Array]',
43 '[object Uint16Array]',
44 '[object Int32Array]',
45 '[object Uint32Array]',
46 '[object Float32Array]',
47 '[object Float64Array]'
48 ];
49
50 var isArrayBufferView =
51 ArrayBuffer.isView ||
52 function(obj) {
53 return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
54 };
55 }
56
57 function normalizeName(name) {
58 if (typeof name !== 'string') {
59 name = String(name);
60 }
61 if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') {
62 throw new TypeError('Invalid character in header field name: "' + name + '"')
63 }
64 return name.toLowerCase()
65 }
66
67 function normalizeValue(value) {
68 if (typeof value !== 'string') {
69 value = String(value);
70 }
71 return value
72 }
73
74 // Build a destructive iterator for the value list
75 function iteratorFor(items) {
76 var iterator = {
77 next: function() {
78 var value = items.shift();
79 return {done: value === undefined, value: value}
80 }
81 };
82
83 if (support.iterable) {
84 iterator[Symbol.iterator] = function() {
85 return iterator
86 };
87 }
88
89 return iterator
90 }
91
92 function Headers(headers) {
93 this.map = {};
94
95 if (headers instanceof Headers) {
96 headers.forEach(function(value, name) {
97 this.append(name, value);
98 }, this);
99 } else if (Array.isArray(headers)) {
100 headers.forEach(function(header) {
101 if (header.length != 2) {
102 throw new TypeError('Headers constructor: expected name/value pair to be length 2, found' + header.length)
103 }
104 this.append(header[0], header[1]);
105 }, this);
106 } else if (headers) {
107 Object.getOwnPropertyNames(headers).forEach(function(name) {
108 this.append(name, headers[name]);
109 }, this);
110 }
111 }
112
113 Headers.prototype.append = function(name, value) {
114 name = normalizeName(name);
115 value = normalizeValue(value);
116 var oldValue = this.map[name];
117 this.map[name] = oldValue ? oldValue + ', ' + value : value;
118 };
119
120 Headers.prototype['delete'] = function(name) {
121 delete this.map[normalizeName(name)];
122 };
123
124 Headers.prototype.get = function(name) {
125 name = normalizeName(name);
126 return this.has(name) ? this.map[name] : null
127 };
128
129 Headers.prototype.has = function(name) {
130 return this.map.hasOwnProperty(normalizeName(name))
131 };
132
133 Headers.prototype.set = function(name, value) {
134 this.map[normalizeName(name)] = normalizeValue(value);
135 };
136
137 Headers.prototype.forEach = function(callback, thisArg) {
138 for (var name in this.map) {
139 if (this.map.hasOwnProperty(name)) {
140 callback.call(thisArg, this.map[name], name, this);
141 }
142 }
143 };
144
145 Headers.prototype.keys = function() {
146 var items = [];
147 this.forEach(function(value, name) {
148 items.push(name);
149 });
150 return iteratorFor(items)
151 };
152
153 Headers.prototype.values = function() {
154 var items = [];
155 this.forEach(function(value) {
156 items.push(value);
157 });
158 return iteratorFor(items)
159 };
160
161 Headers.prototype.entries = function() {
162 var items = [];
163 this.forEach(function(value, name) {
164 items.push([name, value]);
165 });
166 return iteratorFor(items)
167 };
168
169 if (support.iterable) {
170 Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
171 }
172
173 function consumed(body) {
174 if (body._noBody) return
175 if (body.bodyUsed) {
176 return Promise.reject(new TypeError('Already read'))
177 }
178 body.bodyUsed = true;
179 }
180
181 function fileReaderReady(reader) {
182 return new Promise(function(resolve, reject) {
183 reader.onload = function() {
184 resolve(reader.result);
185 };
186 reader.onerror = function() {
187 reject(reader.error);
188 };
189 })
190 }
191
192 function readBlobAsArrayBuffer(blob) {
193 var reader = new FileReader();
194 var promise = fileReaderReady(reader);
195 reader.readAsArrayBuffer(blob);
196 return promise
197 }
198
199 function readBlobAsText(blob) {
200 var reader = new FileReader();
201 var promise = fileReaderReady(reader);
202 var match = /charset=([A-Za-z0-9_-]+)/.exec(blob.type);
203 var encoding = match ? match[1] : 'utf-8';
204 reader.readAsText(blob, encoding);
205 return promise
206 }
207
208 function readArrayBufferAsText(buf) {
209 var view = new Uint8Array(buf);
210 var chars = new Array(view.length);
211
212 for (var i = 0; i < view.length; i++) {
213 chars[i] = String.fromCharCode(view[i]);
214 }
215 return chars.join('')
216 }
217
218 function bufferClone(buf) {
219 if (buf.slice) {
220 return buf.slice(0)
221 } else {
222 var view = new Uint8Array(buf.byteLength);
223 view.set(new Uint8Array(buf));
224 return view.buffer
225 }
226 }
227
228 function Body() {
229 this.bodyUsed = false;
230
231 this._initBody = function(body) {
232 /*
233 fetch-mock wraps the Response object in an ES6 Proxy to
234 provide useful test harness features such as flush. However, on
235 ES5 browsers without fetch or Proxy support pollyfills must be used;
236 the proxy-pollyfill is unable to proxy an attribute unless it exists
237 on the object before the Proxy is created. This change ensures
238 Response.bodyUsed exists on the instance, while maintaining the
239 semantic of setting Request.bodyUsed in the constructor before
240 _initBody is called.
241 */
242 // eslint-disable-next-line no-self-assign
243 this.bodyUsed = this.bodyUsed;
244 this._bodyInit = body;
245 if (!body) {
246 this._noBody = true;
247 this._bodyText = '';
248 } else if (typeof body === 'string') {
249 this._bodyText = body;
250 } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
251 this._bodyBlob = body;
252 } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
253 this._bodyFormData = body;
254 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
255 this._bodyText = body.toString();
256 } else if (support.arrayBuffer && support.blob && isDataView(body)) {
257 this._bodyArrayBuffer = bufferClone(body.buffer);
258 // IE 10-11 can't handle a DataView body.
259 this._bodyInit = new Blob([this._bodyArrayBuffer]);
260 } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
261 this._bodyArrayBuffer = bufferClone(body);
262 } else {
263 this._bodyText = body = Object.prototype.toString.call(body);
264 }
265
266 if (!this.headers.get('content-type')) {
267 if (typeof body === 'string') {
268 this.headers.set('content-type', 'text/plain;charset=UTF-8');
269 } else if (this._bodyBlob && this._bodyBlob.type) {
270 this.headers.set('content-type', this._bodyBlob.type);
271 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
272 this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
273 }
274 }
275 };
276
277 if (support.blob) {
278 this.blob = function() {
279 var rejected = consumed(this);
280 if (rejected) {
281 return rejected
282 }
283
284 if (this._bodyBlob) {
285 return Promise.resolve(this._bodyBlob)
286 } else if (this._bodyArrayBuffer) {
287 return Promise.resolve(new Blob([this._bodyArrayBuffer]))
288 } else if (this._bodyFormData) {
289 throw new Error('could not read FormData body as blob')
290 } else {
291 return Promise.resolve(new Blob([this._bodyText]))
292 }
293 };
294 }
295
296 this.arrayBuffer = function() {
297 if (this._bodyArrayBuffer) {
298 var isConsumed = consumed(this);
299 if (isConsumed) {
300 return isConsumed
301 } else if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
302 return Promise.resolve(
303 this._bodyArrayBuffer.buffer.slice(
304 this._bodyArrayBuffer.byteOffset,
305 this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
306 )
307 )
308 } else {
309 return Promise.resolve(this._bodyArrayBuffer)
310 }
311 } else if (support.blob) {
312 return this.blob().then(readBlobAsArrayBuffer)
313 } else {
314 throw new Error('could not read as ArrayBuffer')
315 }
316 };
317
318 this.text = function() {
319 var rejected = consumed(this);
320 if (rejected) {
321 return rejected
322 }
323
324 if (this._bodyBlob) {
325 return readBlobAsText(this._bodyBlob)
326 } else if (this._bodyArrayBuffer) {
327 return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
328 } else if (this._bodyFormData) {
329 throw new Error('could not read FormData body as text')
330 } else {
331 return Promise.resolve(this._bodyText)
332 }
333 };
334
335 if (support.formData) {
336 this.formData = function() {
337 return this.text().then(decode)
338 };
339 }
340
341 this.json = function() {
342 return this.text().then(JSON.parse)
343 };
344
345 return this
346 }
347
348 // HTTP methods whose capitalization should be normalized
349 var methods = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'];
350
351 function normalizeMethod(method) {
352 var upcased = method.toUpperCase();
353 return methods.indexOf(upcased) > -1 ? upcased : method
354 }
355
356 function Request(input, options) {
357 if (!(this instanceof Request)) {
358 throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
359 }
360
361 options = options || {};
362 var body = options.body;
363
364 if (input instanceof Request) {
365 if (input.bodyUsed) {
366 throw new TypeError('Already read')
367 }
368 this.url = input.url;
369 this.credentials = input.credentials;
370 if (!options.headers) {
371 this.headers = new Headers(input.headers);
372 }
373 this.method = input.method;
374 this.mode = input.mode;
375 this.signal = input.signal;
376 if (!body && input._bodyInit != null) {
377 body = input._bodyInit;
378 input.bodyUsed = true;
379 }
380 } else {
381 this.url = String(input);
382 }
383
384 this.credentials = options.credentials || this.credentials || 'same-origin';
385 if (options.headers || !this.headers) {
386 this.headers = new Headers(options.headers);
387 }
388 this.method = normalizeMethod(options.method || this.method || 'GET');
389 this.mode = options.mode || this.mode || null;
390 this.signal = options.signal || this.signal || (function () {
391 if ('AbortController' in g) {
392 var ctrl = new AbortController();
393 return ctrl.signal;
394 }
395 }());
396 this.referrer = null;
397
398 if ((this.method === 'GET' || this.method === 'HEAD') && body) {
399 throw new TypeError('Body not allowed for GET or HEAD requests')
400 }
401 this._initBody(body);
402
403 if (this.method === 'GET' || this.method === 'HEAD') {
404 if (options.cache === 'no-store' || options.cache === 'no-cache') {
405 // Search for a '_' parameter in the query string
406 var reParamSearch = /([?&])_=[^&]*/;
407 if (reParamSearch.test(this.url)) {
408 // If it already exists then set the value with the current time
409 this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime());
410 } else {
411 // Otherwise add a new '_' parameter to the end with the current time
412 var reQueryString = /\?/;
413 this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime();
414 }
415 }
416 }
417 }
418
419 Request.prototype.clone = function() {
420 return new Request(this, {body: this._bodyInit})
421 };
422
423 function decode(body) {
424 var form = new FormData();
425 body
426 .trim()
427 .split('&')
428 .forEach(function(bytes) {
429 if (bytes) {
430 var split = bytes.split('=');
431 var name = split.shift().replace(/\+/g, ' ');
432 var value = split.join('=').replace(/\+/g, ' ');
433 form.append(decodeURIComponent(name), decodeURIComponent(value));
434 }
435 });
436 return form
437 }
438
439 function parseHeaders(rawHeaders) {
440 var headers = new Headers();
441 // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
442 // https://tools.ietf.org/html/rfc7230#section-3.2
443 var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
444 // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill
445 // https://github.com/github/fetch/issues/748
446 // https://github.com/zloirock/core-js/issues/751
447 preProcessedHeaders
448 .split('\r')
449 .map(function(header) {
450 return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header
451 })
452 .forEach(function(line) {
453 var parts = line.split(':');
454 var key = parts.shift().trim();
455 if (key) {
456 var value = parts.join(':').trim();
457 try {
458 headers.append(key, value);
459 } catch (error) {
460 console.warn('Response ' + error.message);
461 }
462 }
463 });
464 return headers
465 }
466
467 Body.call(Request.prototype);
468
469 function Response(bodyInit, options) {
470 if (!(this instanceof Response)) {
471 throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
472 }
473 if (!options) {
474 options = {};
475 }
476
477 this.type = 'default';
478 this.status = options.status === undefined ? 200 : options.status;
479 if (this.status < 200 || this.status > 599) {
480 throw new RangeError("Failed to construct 'Response': The status provided (0) is outside the range [200, 599].")
481 }
482 this.ok = this.status >= 200 && this.status < 300;
483 this.statusText = options.statusText === undefined ? '' : '' + options.statusText;
484 this.headers = new Headers(options.headers);
485 this.url = options.url || '';
486 this._initBody(bodyInit);
487 }
488
489 Body.call(Response.prototype);
490
491 Response.prototype.clone = function() {
492 return new Response(this._bodyInit, {
493 status: this.status,
494 statusText: this.statusText,
495 headers: new Headers(this.headers),
496 url: this.url
497 })
498 };
499
500 Response.error = function() {
501 var response = new Response(null, {status: 200, statusText: ''});
502 response.ok = false;
503 response.status = 0;
504 response.type = 'error';
505 return response
506 };
507
508 var redirectStatuses = [301, 302, 303, 307, 308];
509
510 Response.redirect = function(url, status) {
511 if (redirectStatuses.indexOf(status) === -1) {
512 throw new RangeError('Invalid status code')
513 }
514
515 return new Response(null, {status: status, headers: {location: url}})
516 };
517
518 exports.DOMException = g.DOMException;
519 try {
520 new exports.DOMException();
521 } catch (err) {
522 exports.DOMException = function(message, name) {
523 this.message = message;
524 this.name = name;
525 var error = Error(message);
526 this.stack = error.stack;
527 };
528 exports.DOMException.prototype = Object.create(Error.prototype);
529 exports.DOMException.prototype.constructor = exports.DOMException;
530 }
531
532 function fetch(input, init) {
533 return new Promise(function(resolve, reject) {
534 var request = new Request(input, init);
535
536 if (request.signal && request.signal.aborted) {
537 return reject(new exports.DOMException('Aborted', 'AbortError'))
538 }
539
540 var xhr = new XMLHttpRequest();
541
542 function abortXhr() {
543 xhr.abort();
544 }
545
546 xhr.onload = function() {
547 var options = {
548 statusText: xhr.statusText,
549 headers: parseHeaders(xhr.getAllResponseHeaders() || '')
550 };
551 // This check if specifically for when a user fetches a file locally from the file system
552 // Only if the status is out of a normal range
553 if (request.url.indexOf('file://') === 0 && (xhr.status < 200 || xhr.status > 599)) {
554 options.status = 200;
555 } else {
556 options.status = xhr.status;
557 }
558 options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
559 var body = 'response' in xhr ? xhr.response : xhr.responseText;
560 setTimeout(function() {
561 resolve(new Response(body, options));
562 }, 0);
563 };
564
565 xhr.onerror = function() {
566 setTimeout(function() {
567 reject(new TypeError('Network request failed'));
568 }, 0);
569 };
570
571 xhr.ontimeout = function() {
572 setTimeout(function() {
573 reject(new TypeError('Network request timed out'));
574 }, 0);
575 };
576
577 xhr.onabort = function() {
578 setTimeout(function() {
579 reject(new exports.DOMException('Aborted', 'AbortError'));
580 }, 0);
581 };
582
583 function fixUrl(url) {
584 try {
585 return url === '' && g.location.href ? g.location.href : url
586 } catch (e) {
587 return url
588 }
589 }
590
591 xhr.open(request.method, fixUrl(request.url), true);
592
593 if (request.credentials === 'include') {
594 xhr.withCredentials = true;
595 } else if (request.credentials === 'omit') {
596 xhr.withCredentials = false;
597 }
598
599 if ('responseType' in xhr) {
600 if (support.blob) {
601 xhr.responseType = 'blob';
602 } else if (
603 support.arrayBuffer
604 ) {
605 xhr.responseType = 'arraybuffer';
606 }
607 }
608
609 if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers || (g.Headers && init.headers instanceof g.Headers))) {
610 var names = [];
611 Object.getOwnPropertyNames(init.headers).forEach(function(name) {
612 names.push(normalizeName(name));
613 xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
614 });
615 request.headers.forEach(function(value, name) {
616 if (names.indexOf(name) === -1) {
617 xhr.setRequestHeader(name, value);
618 }
619 });
620 } else {
621 request.headers.forEach(function(value, name) {
622 xhr.setRequestHeader(name, value);
623 });
624 }
625
626 if (request.signal) {
627 request.signal.addEventListener('abort', abortXhr);
628
629 xhr.onreadystatechange = function() {
630 // DONE (success or failure)
631 if (xhr.readyState === 4) {
632 request.signal.removeEventListener('abort', abortXhr);
633 }
634 };
635 }
636
637 xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
638 })
639 }
640
641 fetch.polyfill = true;
642
643 if (!g.fetch) {
644 g.fetch = fetch;
645 g.Headers = Headers;
646 g.Request = Request;
647 g.Response = Response;
648 }
649
650 exports.Headers = Headers;
651 exports.Request = Request;
652 exports.Response = Response;
653 exports.fetch = fetch;
654
655 Object.defineProperty(exports, '__esModule', { value: true });
656
657})));
658