aboutsummaryrefslogtreecommitdiff
path: root/node_modules/whatwg-fetch
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
commitde98e0b232509d5f40c135d540a70e415272ff85 (patch)
treea79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/whatwg-fetch
parente0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff)
downloadwallet-core-de98e0b232509d5f40c135d540a70e415272ff85.tar.xz
node_modules
Diffstat (limited to 'node_modules/whatwg-fetch')
-rw-r--r--node_modules/whatwg-fetch/LICENSE20
-rw-r--r--node_modules/whatwg-fetch/README.md282
-rw-r--r--node_modules/whatwg-fetch/fetch.js461
-rw-r--r--node_modules/whatwg-fetch/package.json23
4 files changed, 786 insertions, 0 deletions
diff --git a/node_modules/whatwg-fetch/LICENSE b/node_modules/whatwg-fetch/LICENSE
new file mode 100644
index 000000000..0e319d55d
--- /dev/null
+++ b/node_modules/whatwg-fetch/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014-2016 GitHub, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/whatwg-fetch/README.md b/node_modules/whatwg-fetch/README.md
new file mode 100644
index 000000000..328cb490e
--- /dev/null
+++ b/node_modules/whatwg-fetch/README.md
@@ -0,0 +1,282 @@
+# window.fetch polyfill
+
+The `fetch()` function is a Promise-based mechanism for programmatically making
+web requests in the browser. This project is a polyfill that implements a subset
+of the standard [Fetch specification][], enough to make `fetch` a viable
+replacement for most uses of XMLHttpRequest in traditional web applications.
+
+This project adheres to the [Open Code of Conduct][]. By participating, you are
+expected to uphold this code.
+
+## Table of Contents
+
+* [Read this first](#read-this-first)
+* [Installation](#installation)
+* [Usage](#usage)
+ * [HTML](#html)
+ * [JSON](#json)
+ * [Response metadata](#response-metadata)
+ * [Post form](#post-form)
+ * [Post JSON](#post-json)
+ * [File upload](#file-upload)
+ * [Caveats](#caveats)
+ * [Handling HTTP error statuses](#handling-http-error-statuses)
+ * [Sending cookies](#sending-cookies)
+ * [Receiving cookies](#receiving-cookies)
+ * [Obtaining the Response URL](#obtaining-the-response-url)
+* [Browser Support](#browser-support)
+
+## Read this first
+
+* If you believe you found a bug with how `fetch` behaves in Chrome or Firefox,
+ please **avoid opening an issue in this repository**. This project is a
+ _polyfill_, and since Chrome and Firefox both implement the `window.fetch`
+ function natively, no code from this project actually takes any effect in
+ these browsers. See [Browser support](#browser-support) for detailed
+ information.
+
+* If you have trouble **making a request to another domain** (a different
+ subdomain or port number also constitutes as another domain), please
+ familiarize yourself with all the intricacies and limitations of [CORS][]
+ requests. Because CORS requires participation of the server by implementing
+ specific HTTP response headers, it is often nontrivial to set up or debug.
+ CORS is exclusively handled by the browser's internal mechanisms which this
+ polyfill cannot influence.
+
+* If you have trouble **maintaining the user's session** or [CSRF][] protection
+ through `fetch` requests, please ensure that you've read and understood the
+ [Sending cookies](#sending-cookies) section.
+
+* If this polyfill **doesn't work under Node.js environments**, that is expected,
+ because this project is meant for web browsers only. You should ensure that your
+ application doesn't try to package and run this on the server.
+
+* If you have an idea for a new feature of `fetch`, please understand that we
+ are only ever going to add features and APIs that are a part of the
+ [Fetch specification][]. You should **submit your feature requests** to the
+ [repository of the specification](https://github.com/whatwg/fetch/issues)
+ itself, rather than this repository.
+
+## Installation
+
+* `npm install whatwg-fetch --save`; or
+
+* `bower install fetch`.
+
+You will also need a Promise polyfill for [older browsers](http://caniuse.com/#feat=promises).
+We recommend [taylorhakes/promise-polyfill](https://github.com/taylorhakes/promise-polyfill)
+for its small size and Promises/A+ compatibility.
+
+For use with webpack, add this package in the `entry` configuration option
+before your application entry point:
+
+```javascript
+entry: ['whatwg-fetch', ...]
+```
+
+For Babel and ES2015+, make sure to import the file:
+
+```javascript
+import 'whatwg-fetch'
+```
+
+## Usage
+
+For a more comprehensive API reference that this polyfill supports, refer to
+https://github.github.io/fetch/.
+
+### HTML
+
+```javascript
+fetch('/users.html')
+ .then(function(response) {
+ return response.text()
+ }).then(function(body) {
+ document.body.innerHTML = body
+ })
+```
+
+### JSON
+
+```javascript
+fetch('/users.json')
+ .then(function(response) {
+ return response.json()
+ }).then(function(json) {
+ console.log('parsed json', json)
+ }).catch(function(ex) {
+ console.log('parsing failed', ex)
+ })
+```
+
+### Response metadata
+
+```javascript
+fetch('/users.json').then(function(response) {
+ console.log(response.headers.get('Content-Type'))
+ console.log(response.headers.get('Date'))
+ console.log(response.status)
+ console.log(response.statusText)
+})
+```
+
+### Post form
+
+```javascript
+var form = document.querySelector('form')
+
+fetch('/users', {
+ method: 'POST',
+ body: new FormData(form)
+})
+```
+
+### Post JSON
+
+```javascript
+fetch('/users', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ name: 'Hubot',
+ login: 'hubot',
+ })
+})
+```
+
+### File upload
+
+```javascript
+var input = document.querySelector('input[type="file"]')
+
+var data = new FormData()
+data.append('file', input.files[0])
+data.append('user', 'hubot')
+
+fetch('/avatars', {
+ method: 'POST',
+ body: data
+})
+```
+
+### Caveats
+
+The `fetch` specification differs from `jQuery.ajax()` in mainly two ways that
+bear keeping in mind:
+
+* The Promise returned from `fetch()` **won't reject on HTTP error status**
+ even if the response is an HTTP 404 or 500. Instead, it will resolve normally,
+ and it will only reject on network failure or if anything prevented the
+ request from completing.
+
+* By default, `fetch` **won't send or receive any cookies** from the server,
+ resulting in unauthenticated requests if the site relies on maintaining a user
+ session. See [Sending cookies](#sending-cookies) for how to opt into cookie
+ handling.
+
+#### Handling HTTP error statuses
+
+To have `fetch` Promise reject on HTTP error statuses, i.e. on any non-2xx
+status, define a custom response handler:
+
+```javascript
+function checkStatus(response) {
+ if (response.status >= 200 && response.status < 300) {
+ return response
+ } else {
+ var error = new Error(response.statusText)
+ error.response = response
+ throw error
+ }
+}
+
+function parseJSON(response) {
+ return response.json()
+}
+
+fetch('/users')
+ .then(checkStatus)
+ .then(parseJSON)
+ .then(function(data) {
+ console.log('request succeeded with JSON response', data)
+ }).catch(function(error) {
+ console.log('request failed', error)
+ })
+```
+
+#### Sending cookies
+
+To automatically send cookies for the current domain, the `credentials` option
+must be provided:
+
+```javascript
+fetch('/users', {
+ credentials: 'same-origin'
+})
+```
+
+The "same-origin" value makes `fetch` behave similarly to XMLHttpRequest with
+regards to cookies. Otherwise, cookies won't get sent, resulting in these
+requests not preserving the authentication session.
+
+For [CORS][] requests, use the "include" value to allow sending credentials to
+other domains:
+
+```javascript
+fetch('https://example.com:1234/users', {
+ credentials: 'include'
+})
+```
+
+#### Receiving cookies
+
+As with XMLHttpRequest, the `Set-Cookie` response header returned from the
+server is a [forbidden header name][] and therefore can't be programmatically
+read with `response.headers.get()`. Instead, it's the browser's responsibility
+to handle new cookies being set (if applicable to the current URL). Unless they
+are HTTP-only, new cookies will be available through `document.cookie`.
+
+Bear in mind that the default behavior of `fetch` is to ignore the `Set-Cookie`
+header completely. To opt into accepting cookies from the server, you must use
+the `credentials` option.
+
+#### Obtaining the Response URL
+
+Due to limitations of XMLHttpRequest, the `response.url` value might not be
+reliable after HTTP redirects on older browsers.
+
+The solution is to configure the server to set the response HTTP header
+`X-Request-URL` to the current URL after any redirect that might have happened.
+It should be safe to set it unconditionally.
+
+``` ruby
+# Ruby on Rails controller example
+response.headers['X-Request-URL'] = request.url
+```
+
+This server workaround is necessary if you need reliable `response.url` in
+Firefox < 32, Chrome < 37, Safari, or IE.
+
+## Browser Support
+
+- Chrome
+- Firefox
+- Safari 6.1+
+- Internet Explorer 10+
+
+Note: modern browsers such as Chrome, Firefox, and Microsoft Edge contain native
+implementations of `window.fetch`, therefore the code from this polyfill doesn't
+have any effect on those browsers. If you believe you've encountered an error
+with how `window.fetch` is implemented in any of these browsers, you should file
+an issue with that browser vendor instead of this project.
+
+
+ [fetch specification]: https://fetch.spec.whatwg.org
+ [open code of conduct]: http://todogroup.org/opencodeofconduct/#fetch/opensource@github.com
+ [cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
+ "Cross-origin resource sharing"
+ [csrf]: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
+ "Cross-site request forgery"
+ [forbidden header name]: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
diff --git a/node_modules/whatwg-fetch/fetch.js b/node_modules/whatwg-fetch/fetch.js
new file mode 100644
index 000000000..6bac6b394
--- /dev/null
+++ b/node_modules/whatwg-fetch/fetch.js
@@ -0,0 +1,461 @@
+(function(self) {
+ 'use strict';
+
+ if (self.fetch) {
+ return
+ }
+
+ var support = {
+ searchParams: 'URLSearchParams' in self,
+ iterable: 'Symbol' in self && 'iterator' in Symbol,
+ blob: 'FileReader' in self && 'Blob' in self && (function() {
+ try {
+ new Blob()
+ return true
+ } catch(e) {
+ return false
+ }
+ })(),
+ formData: 'FormData' in self,
+ arrayBuffer: 'ArrayBuffer' in self
+ }
+
+ if (support.arrayBuffer) {
+ var viewClasses = [
+ '[object Int8Array]',
+ '[object Uint8Array]',
+ '[object Uint8ClampedArray]',
+ '[object Int16Array]',
+ '[object Uint16Array]',
+ '[object Int32Array]',
+ '[object Uint32Array]',
+ '[object Float32Array]',
+ '[object Float64Array]'
+ ]
+
+ var isDataView = function(obj) {
+ return obj && DataView.prototype.isPrototypeOf(obj)
+ }
+
+ var isArrayBufferView = ArrayBuffer.isView || function(obj) {
+ return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
+ }
+ }
+
+ function normalizeName(name) {
+ if (typeof name !== 'string') {
+ name = String(name)
+ }
+ if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
+ throw new TypeError('Invalid character in header field name')
+ }
+ return name.toLowerCase()
+ }
+
+ function normalizeValue(value) {
+ if (typeof value !== 'string') {
+ value = String(value)
+ }
+ return value
+ }
+
+ // Build a destructive iterator for the value list
+ function iteratorFor(items) {
+ var iterator = {
+ next: function() {
+ var value = items.shift()
+ return {done: value === undefined, value: value}
+ }
+ }
+
+ if (support.iterable) {
+ iterator[Symbol.iterator] = function() {
+ return iterator
+ }
+ }
+
+ return iterator
+ }
+
+ function Headers(headers) {
+ this.map = {}
+
+ if (headers instanceof Headers) {
+ headers.forEach(function(value, name) {
+ this.append(name, value)
+ }, this)
+ } else if (Array.isArray(headers)) {
+ headers.forEach(function(header) {
+ this.append(header[0], header[1])
+ }, this)
+ } else if (headers) {
+ Object.getOwnPropertyNames(headers).forEach(function(name) {
+ this.append(name, headers[name])
+ }, this)
+ }
+ }
+
+ Headers.prototype.append = function(name, value) {
+ name = normalizeName(name)
+ value = normalizeValue(value)
+ var oldValue = this.map[name]
+ this.map[name] = oldValue ? oldValue+','+value : value
+ }
+
+ Headers.prototype['delete'] = function(name) {
+ delete this.map[normalizeName(name)]
+ }
+
+ Headers.prototype.get = function(name) {
+ name = normalizeName(name)
+ return this.has(name) ? this.map[name] : null
+ }
+
+ Headers.prototype.has = function(name) {
+ return this.map.hasOwnProperty(normalizeName(name))
+ }
+
+ Headers.prototype.set = function(name, value) {
+ this.map[normalizeName(name)] = normalizeValue(value)
+ }
+
+ Headers.prototype.forEach = function(callback, thisArg) {
+ for (var name in this.map) {
+ if (this.map.hasOwnProperty(name)) {
+ callback.call(thisArg, this.map[name], name, this)
+ }
+ }
+ }
+
+ Headers.prototype.keys = function() {
+ var items = []
+ this.forEach(function(value, name) { items.push(name) })
+ return iteratorFor(items)
+ }
+
+ Headers.prototype.values = function() {
+ var items = []
+ this.forEach(function(value) { items.push(value) })
+ return iteratorFor(items)
+ }
+
+ Headers.prototype.entries = function() {
+ var items = []
+ this.forEach(function(value, name) { items.push([name, value]) })
+ return iteratorFor(items)
+ }
+
+ if (support.iterable) {
+ Headers.prototype[Symbol.iterator] = Headers.prototype.entries
+ }
+
+ function consumed(body) {
+ if (body.bodyUsed) {
+ return Promise.reject(new TypeError('Already read'))
+ }
+ body.bodyUsed = true
+ }
+
+ function fileReaderReady(reader) {
+ return new Promise(function(resolve, reject) {
+ reader.onload = function() {
+ resolve(reader.result)
+ }
+ reader.onerror = function() {
+ reject(reader.error)
+ }
+ })
+ }
+
+ function readBlobAsArrayBuffer(blob) {
+ var reader = new FileReader()
+ var promise = fileReaderReady(reader)
+ reader.readAsArrayBuffer(blob)
+ return promise
+ }
+
+ function readBlobAsText(blob) {
+ var reader = new FileReader()
+ var promise = fileReaderReady(reader)
+ reader.readAsText(blob)
+ return promise
+ }
+
+ function readArrayBufferAsText(buf) {
+ var view = new Uint8Array(buf)
+ var chars = new Array(view.length)
+
+ for (var i = 0; i < view.length; i++) {
+ chars[i] = String.fromCharCode(view[i])
+ }
+ return chars.join('')
+ }
+
+ function bufferClone(buf) {
+ if (buf.slice) {
+ return buf.slice(0)
+ } else {
+ var view = new Uint8Array(buf.byteLength)
+ view.set(new Uint8Array(buf))
+ return view.buffer
+ }
+ }
+
+ function Body() {
+ this.bodyUsed = false
+
+ this._initBody = function(body) {
+ this._bodyInit = body
+ if (!body) {
+ this._bodyText = ''
+ } else if (typeof body === 'string') {
+ this._bodyText = body
+ } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
+ this._bodyBlob = body
+ } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
+ this._bodyFormData = body
+ } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
+ this._bodyText = body.toString()
+ } else if (support.arrayBuffer && support.blob && isDataView(body)) {
+ this._bodyArrayBuffer = bufferClone(body.buffer)
+ // IE 10-11 can't handle a DataView body.
+ this._bodyInit = new Blob([this._bodyArrayBuffer])
+ } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
+ this._bodyArrayBuffer = bufferClone(body)
+ } else {
+ throw new Error('unsupported BodyInit type')
+ }
+
+ if (!this.headers.get('content-type')) {
+ if (typeof body === 'string') {
+ this.headers.set('content-type', 'text/plain;charset=UTF-8')
+ } else if (this._bodyBlob && this._bodyBlob.type) {
+ this.headers.set('content-type', this._bodyBlob.type)
+ } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
+ this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
+ }
+ }
+ }
+
+ if (support.blob) {
+ this.blob = function() {
+ var rejected = consumed(this)
+ if (rejected) {
+ return rejected
+ }
+
+ if (this._bodyBlob) {
+ return Promise.resolve(this._bodyBlob)
+ } else if (this._bodyArrayBuffer) {
+ return Promise.resolve(new Blob([this._bodyArrayBuffer]))
+ } else if (this._bodyFormData) {
+ throw new Error('could not read FormData body as blob')
+ } else {
+ return Promise.resolve(new Blob([this._bodyText]))
+ }
+ }
+
+ this.arrayBuffer = function() {
+ if (this._bodyArrayBuffer) {
+ return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
+ } else {
+ return this.blob().then(readBlobAsArrayBuffer)
+ }
+ }
+ }
+
+ this.text = function() {
+ var rejected = consumed(this)
+ if (rejected) {
+ return rejected
+ }
+
+ if (this._bodyBlob) {
+ return readBlobAsText(this._bodyBlob)
+ } else if (this._bodyArrayBuffer) {
+ return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
+ } else if (this._bodyFormData) {
+ throw new Error('could not read FormData body as text')
+ } else {
+ return Promise.resolve(this._bodyText)
+ }
+ }
+
+ if (support.formData) {
+ this.formData = function() {
+ return this.text().then(decode)
+ }
+ }
+
+ this.json = function() {
+ return this.text().then(JSON.parse)
+ }
+
+ return this
+ }
+
+ // HTTP methods whose capitalization should be normalized
+ var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
+
+ function normalizeMethod(method) {
+ var upcased = method.toUpperCase()
+ return (methods.indexOf(upcased) > -1) ? upcased : method
+ }
+
+ function Request(input, options) {
+ options = options || {}
+ var body = options.body
+
+ if (input instanceof Request) {
+ if (input.bodyUsed) {
+ throw new TypeError('Already read')
+ }
+ this.url = input.url
+ this.credentials = input.credentials
+ if (!options.headers) {
+ this.headers = new Headers(input.headers)
+ }
+ this.method = input.method
+ this.mode = input.mode
+ if (!body && input._bodyInit != null) {
+ body = input._bodyInit
+ input.bodyUsed = true
+ }
+ } else {
+ this.url = String(input)
+ }
+
+ this.credentials = options.credentials || this.credentials || 'omit'
+ if (options.headers || !this.headers) {
+ this.headers = new Headers(options.headers)
+ }
+ this.method = normalizeMethod(options.method || this.method || 'GET')
+ this.mode = options.mode || this.mode || null
+ this.referrer = null
+
+ if ((this.method === 'GET' || this.method === 'HEAD') && body) {
+ throw new TypeError('Body not allowed for GET or HEAD requests')
+ }
+ this._initBody(body)
+ }
+
+ Request.prototype.clone = function() {
+ return new Request(this, { body: this._bodyInit })
+ }
+
+ function decode(body) {
+ var form = new FormData()
+ body.trim().split('&').forEach(function(bytes) {
+ if (bytes) {
+ var split = bytes.split('=')
+ var name = split.shift().replace(/\+/g, ' ')
+ var value = split.join('=').replace(/\+/g, ' ')
+ form.append(decodeURIComponent(name), decodeURIComponent(value))
+ }
+ })
+ return form
+ }
+
+ function parseHeaders(rawHeaders) {
+ var headers = new Headers()
+ rawHeaders.split(/\r?\n/).forEach(function(line) {
+ var parts = line.split(':')
+ var key = parts.shift().trim()
+ if (key) {
+ var value = parts.join(':').trim()
+ headers.append(key, value)
+ }
+ })
+ return headers
+ }
+
+ Body.call(Request.prototype)
+
+ function Response(bodyInit, options) {
+ if (!options) {
+ options = {}
+ }
+
+ this.type = 'default'
+ this.status = 'status' in options ? options.status : 200
+ this.ok = this.status >= 200 && this.status < 300
+ this.statusText = 'statusText' in options ? options.statusText : 'OK'
+ this.headers = new Headers(options.headers)
+ this.url = options.url || ''
+ this._initBody(bodyInit)
+ }
+
+ Body.call(Response.prototype)
+
+ Response.prototype.clone = function() {
+ return new Response(this._bodyInit, {
+ status: this.status,
+ statusText: this.statusText,
+ headers: new Headers(this.headers),
+ url: this.url
+ })
+ }
+
+ Response.error = function() {
+ var response = new Response(null, {status: 0, statusText: ''})
+ response.type = 'error'
+ return response
+ }
+
+ var redirectStatuses = [301, 302, 303, 307, 308]
+
+ Response.redirect = function(url, status) {
+ if (redirectStatuses.indexOf(status) === -1) {
+ throw new RangeError('Invalid status code')
+ }
+
+ return new Response(null, {status: status, headers: {location: url}})
+ }
+
+ self.Headers = Headers
+ self.Request = Request
+ self.Response = Response
+
+ self.fetch = function(input, init) {
+ return new Promise(function(resolve, reject) {
+ var request = new Request(input, init)
+ var xhr = new XMLHttpRequest()
+
+ xhr.onload = function() {
+ var options = {
+ status: xhr.status,
+ statusText: xhr.statusText,
+ headers: parseHeaders(xhr.getAllResponseHeaders() || '')
+ }
+ options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
+ var body = 'response' in xhr ? xhr.response : xhr.responseText
+ resolve(new Response(body, options))
+ }
+
+ xhr.onerror = function() {
+ reject(new TypeError('Network request failed'))
+ }
+
+ xhr.ontimeout = function() {
+ reject(new TypeError('Network request failed'))
+ }
+
+ xhr.open(request.method, request.url, true)
+
+ if (request.credentials === 'include') {
+ xhr.withCredentials = true
+ }
+
+ if ('responseType' in xhr && support.blob) {
+ xhr.responseType = 'blob'
+ }
+
+ request.headers.forEach(function(value, name) {
+ xhr.setRequestHeader(name, value)
+ })
+
+ xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
+ })
+ }
+ self.fetch.polyfill = true
+})(typeof self !== 'undefined' ? self : this);
diff --git a/node_modules/whatwg-fetch/package.json b/node_modules/whatwg-fetch/package.json
new file mode 100644
index 000000000..e6d80cc9f
--- /dev/null
+++ b/node_modules/whatwg-fetch/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "whatwg-fetch",
+ "description": "A window.fetch polyfill.",
+ "version": "2.0.3",
+ "main": "fetch.js",
+ "repository": "github/fetch",
+ "license": "MIT",
+ "devDependencies": {
+ "chai": "1.10.0",
+ "jshint": "2.8.0",
+ "mocha": "2.1.0",
+ "mocha-phantomjs-core": "2.0.1",
+ "promise-polyfill": "6.0.2",
+ "url-search-params": "0.6.1"
+ },
+ "files": [
+ "LICENSE",
+ "fetch.js"
+ ],
+ "scripts": {
+ "test": "make"
+ }
+}