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