Comparing version 6.7.1 to 7.0.0
256
index.js
@@ -14,9 +14,14 @@ 'use strict'; | ||
const lowercaseKeys = require('lowercase-keys'); | ||
const isRedirect = require('is-redirect'); | ||
const unzipResponse = require('unzip-response'); | ||
const createErrorClass = require('create-error-class'); | ||
const decompressResponse = require('decompress-response'); | ||
const isRetryAllowed = require('is-retry-allowed'); | ||
const Buffer = require('safe-buffer').Buffer; | ||
const isURL = require('isurl'); | ||
const isPlainObj = require('is-plain-obj'); | ||
const PCancelable = require('p-cancelable'); | ||
const pTimeout = require('p-timeout'); | ||
const pkg = require('./package'); | ||
const getMethodRedirectCodes = new Set([300, 301, 302, 303, 304, 305, 307, 308]); | ||
const allMethodRedirectCodes = new Set([300, 303, 307, 308]); | ||
function requestAsEventEmitter(opts) { | ||
@@ -27,3 +32,3 @@ opts = opts || {}; | ||
const requestUrl = opts.href || urlLib.resolve(urlLib.format(opts), opts.path); | ||
let redirectCount = 0; | ||
const redirects = []; | ||
let retryCount = 0; | ||
@@ -33,12 +38,35 @@ let redirectUrl; | ||
const get = opts => { | ||
const fn = opts.protocol === 'https:' ? https : http; | ||
if (opts.protocol !== 'http:' && opts.protocol !== 'https:') { | ||
ee.emit('error', new got.UnsupportedProtocolError(opts)); | ||
return; | ||
} | ||
let fn = opts.protocol === 'https:' ? https : http; | ||
if (opts.useElectronNet && process.versions.electron) { | ||
const electron = require('electron'); | ||
fn = electron.net || electron.remote.net; | ||
} | ||
const req = fn.request(opts, res => { | ||
const statusCode = res.statusCode; | ||
if (isRedirect(statusCode) && opts.followRedirect && 'location' in res.headers && (opts.method === 'GET' || opts.method === 'HEAD')) { | ||
res.url = redirectUrl || requestUrl; | ||
res.requestUrl = requestUrl; | ||
const followRedirect = opts.followRedirect && 'location' in res.headers; | ||
const redirectGet = followRedirect && getMethodRedirectCodes.has(statusCode); | ||
const redirectAll = followRedirect && allMethodRedirectCodes.has(statusCode); | ||
if (redirectAll || (redirectGet && (opts.method === 'GET' || opts.method === 'HEAD'))) { | ||
res.resume(); | ||
if (++redirectCount > 10) { | ||
ee.emit('error', new got.MaxRedirectsError(statusCode, opts), null, res); | ||
if (statusCode === 303) { | ||
// Server responded with "see other", indicating that the resource exists at another location, | ||
// and the client should request it from that location via GET or HEAD. | ||
opts.method = 'GET'; | ||
} | ||
if (redirects.length >= 10) { | ||
ee.emit('error', new got.MaxRedirectsError(statusCode, redirects, opts), null, res); | ||
return; | ||
@@ -50,2 +78,5 @@ } | ||
redirectUrl = urlLib.resolve(urlLib.format(opts), bufferString); | ||
redirects.push(redirectUrl); | ||
const redirectOpts = Object.assign({}, opts, urlLib.parse(redirectUrl)); | ||
@@ -61,6 +92,7 @@ | ||
setImmediate(() => { | ||
const response = typeof unzipResponse === 'function' && req.method !== 'HEAD' ? unzipResponse(res) : res; | ||
response.url = redirectUrl || requestUrl; | ||
response.requestUrl = requestUrl; | ||
const response = typeof decompressResponse === 'function' && | ||
req.method !== 'HEAD' ? decompressResponse(res) : res; | ||
response.redirectUrls = redirects; | ||
ee.emit('response', response); | ||
@@ -90,3 +122,5 @@ }); | ||
get(opts); | ||
setImmediate(() => { | ||
get(opts); | ||
}); | ||
return ee; | ||
@@ -96,6 +130,23 @@ } | ||
function asPromise(opts) { | ||
return new Promise((resolve, reject) => { | ||
const timeoutFn = requestPromise => opts.gotTimeout && opts.gotTimeout.request ? | ||
pTimeout(requestPromise, opts.gotTimeout.request, new got.RequestError({message: 'Request timed out', code: 'ETIMEDOUT'}, opts)) : | ||
requestPromise; | ||
return timeoutFn(new PCancelable((onCancel, resolve, reject) => { | ||
const ee = requestAsEventEmitter(opts); | ||
let cancelOnRequest = false; | ||
onCancel(() => { | ||
cancelOnRequest = true; | ||
}); | ||
ee.on('request', req => { | ||
if (cancelOnRequest) { | ||
req.abort(); | ||
} | ||
onCancel(() => { | ||
req.abort(); | ||
}); | ||
if (isStream(opts.body)) { | ||
@@ -125,8 +176,10 @@ opts.body.pipe(req); | ||
} catch (e) { | ||
throw new got.ParseError(e, statusCode, opts, data); | ||
if (statusCode >= 200 && statusCode < 300) { | ||
throw new got.ParseError(e, statusCode, opts, data); | ||
} | ||
} | ||
} | ||
if (statusCode < 200 || statusCode > limitStatusCode) { | ||
throw new got.HTTPError(statusCode, opts); | ||
if (statusCode !== 304 && (statusCode < 200 || statusCode > limitStatusCode)) { | ||
throw new got.HTTPError(statusCode, res.headers, opts); | ||
} | ||
@@ -143,3 +196,3 @@ | ||
ee.on('error', reject); | ||
}); | ||
})); | ||
} | ||
@@ -151,3 +204,10 @@ | ||
const proxy = duplexer3(input, output); | ||
let timeout; | ||
if (opts.gotTimeout && opts.gotTimeout.request) { | ||
timeout = setTimeout(() => { | ||
proxy.emit('error', new got.RequestError({message: 'Request timed out', code: 'ETIMEDOUT'}, opts)); | ||
}, opts.gotTimeout.request); | ||
} | ||
if (opts.json) { | ||
@@ -187,2 +247,4 @@ throw new Error('got can not be used as stream when options.json is used'); | ||
ee.on('response', res => { | ||
clearTimeout(timeout); | ||
const statusCode = res.statusCode; | ||
@@ -192,4 +254,4 @@ | ||
if (statusCode < 200 || statusCode > 299) { | ||
proxy.emit('error', new got.HTTPError(statusCode, opts), null, res); | ||
if (statusCode !== 304 && (statusCode < 200 || statusCode > 299)) { | ||
proxy.emit('error', new got.HTTPError(statusCode, res.headers, opts), null, res); | ||
return; | ||
@@ -209,3 +271,3 @@ } | ||
if (typeof url !== 'string' && typeof url !== 'object') { | ||
throw new Error(`Parameter \`url\` must be a string or object, not ${typeof url}`); | ||
throw new TypeError(`Parameter \`url\` must be a string or object, not ${typeof url}`); | ||
} | ||
@@ -222,9 +284,20 @@ | ||
if (isURL.lenient(url)) { | ||
url = urlParseLax(url.href); | ||
if (url.auth) { | ||
throw new Error('Basic authentication must be done with auth option'); | ||
} | ||
} | ||
opts = Object.assign( | ||
{ | ||
protocol: 'http:', | ||
path: '', | ||
retries: 5 | ||
retries: 2, | ||
useElectronNet: true | ||
}, | ||
url, | ||
{ | ||
protocol: url.protocol || 'http:' // Override both null/undefined with default protocol | ||
}, | ||
opts | ||
@@ -253,27 +326,34 @@ ); | ||
let body = opts.body; | ||
const body = opts.body; | ||
if (body !== null && body !== undefined) { | ||
const headers = opts.headers; | ||
if (!isStream(body) && typeof body !== 'string' && !Buffer.isBuffer(body) && !(opts.form || opts.json)) { | ||
throw new TypeError('options.body must be a ReadableStream, string, Buffer or plain Object'); | ||
} | ||
if (body) { | ||
if (typeof body !== 'string' && !(body !== null && typeof body === 'object')) { | ||
throw new Error('options.body must be a ReadableStream, string, Buffer or plain Object'); | ||
if ((opts.form || opts.json) && !isPlainObj(body)) { | ||
throw new TypeError('options.body must be a plain Object when options.form or options.json is used'); | ||
} | ||
opts.method = opts.method || 'POST'; | ||
if (isStream(body) && typeof body.getBoundary === 'function') { | ||
// Special case for https://github.com/form-data/form-data | ||
opts.headers['content-type'] = opts.headers['content-type'] || `multipart/form-data; boundary=${body.getBoundary()}`; | ||
} else if (body !== null && typeof body === 'object' && !Buffer.isBuffer(body) && !isStream(body)) { | ||
opts.headers['content-type'] = opts.headers['content-type'] || 'application/x-www-form-urlencoded'; | ||
body = opts.body = querystring.stringify(body); | ||
headers['content-type'] = headers['content-type'] || `multipart/form-data; boundary=${body.getBoundary()}`; | ||
} else if (opts.form && isPlainObj(body)) { | ||
headers['content-type'] = headers['content-type'] || 'application/x-www-form-urlencoded'; | ||
opts.body = querystring.stringify(body); | ||
} else if (opts.json && isPlainObj(body)) { | ||
headers['content-type'] = headers['content-type'] || 'application/json'; | ||
opts.body = JSON.stringify(body); | ||
} | ||
if (opts.headers['content-length'] === undefined && opts.headers['transfer-encoding'] === undefined && !isStream(body)) { | ||
const length = typeof body === 'string' ? Buffer.byteLength(body) : body.length; | ||
opts.headers['content-length'] = length; | ||
if (headers['content-length'] === undefined && headers['transfer-encoding'] === undefined && !isStream(body)) { | ||
const length = typeof opts.body === 'string' ? Buffer.byteLength(opts.body) : opts.body.length; | ||
headers['content-length'] = length; | ||
} | ||
opts.method = (opts.method || 'POST').toUpperCase(); | ||
} else { | ||
opts.method = (opts.method || 'GET').toUpperCase(); | ||
} | ||
opts.method = (opts.method || 'GET').toUpperCase(); | ||
if (opts.hostname === 'unix') { | ||
@@ -308,3 +388,7 @@ const matches = /(.+):(.+)/.exec(opts.path); | ||
if (opts.timeout) { | ||
opts.gotTimeout = opts.timeout; | ||
if (typeof opts.timeout === 'number') { | ||
opts.gotTimeout = {request: opts.timeout}; | ||
} else { | ||
opts.gotTimeout = opts.timeout; | ||
} | ||
delete opts.timeout; | ||
@@ -343,39 +427,73 @@ } | ||
function stdError(error, opts) { | ||
if (error.code !== undefined) { | ||
this.code = error.code; | ||
class StdError extends Error { | ||
constructor(message, error, opts) { | ||
super(message); | ||
this.name = 'StdError'; | ||
if (error.code !== undefined) { | ||
this.code = error.code; | ||
} | ||
Object.assign(this, { | ||
host: opts.host, | ||
hostname: opts.hostname, | ||
method: opts.method, | ||
path: opts.path, | ||
protocol: opts.protocol, | ||
url: opts.href | ||
}); | ||
} | ||
Object.assign(this, { | ||
message: error.message, | ||
host: opts.host, | ||
hostname: opts.hostname, | ||
method: opts.method, | ||
path: opts.path | ||
}); | ||
} | ||
got.RequestError = createErrorClass('RequestError', stdError); | ||
got.ReadError = createErrorClass('ReadError', stdError); | ||
got.ParseError = createErrorClass('ParseError', function (e, statusCode, opts, data) { | ||
stdError.call(this, e, opts); | ||
this.statusCode = statusCode; | ||
this.statusMessage = http.STATUS_CODES[this.statusCode]; | ||
this.message = `${e.message} in "${urlLib.format(opts)}": \n${data.slice(0, 77)}...`; | ||
}); | ||
got.RequestError = class extends StdError { | ||
constructor(error, opts) { | ||
super(error.message, error, opts); | ||
this.name = 'RequestError'; | ||
} | ||
}; | ||
got.HTTPError = createErrorClass('HTTPError', function (statusCode, opts) { | ||
stdError.call(this, {}, opts); | ||
this.statusCode = statusCode; | ||
this.statusMessage = http.STATUS_CODES[this.statusCode]; | ||
this.message = `Response code ${this.statusCode} (${this.statusMessage})`; | ||
}); | ||
got.ReadError = class extends StdError { | ||
constructor(error, opts) { | ||
super(error.message, error, opts); | ||
this.name = 'ReadError'; | ||
} | ||
}; | ||
got.MaxRedirectsError = createErrorClass('MaxRedirectsError', function (statusCode, opts) { | ||
stdError.call(this, {}, opts); | ||
this.statusCode = statusCode; | ||
this.statusMessage = http.STATUS_CODES[this.statusCode]; | ||
this.message = 'Redirected 10 times. Aborting.'; | ||
}); | ||
got.ParseError = class extends StdError { | ||
constructor(error, statusCode, opts, data) { | ||
super(`${error.message} in "${urlLib.format(opts)}": \n${data.slice(0, 77)}...`, error, opts); | ||
this.name = 'ParseError'; | ||
this.statusCode = statusCode; | ||
this.statusMessage = http.STATUS_CODES[this.statusCode]; | ||
} | ||
}; | ||
got.HTTPError = class extends StdError { | ||
constructor(statusCode, headers, opts) { | ||
const statusMessage = http.STATUS_CODES[statusCode]; | ||
super(`Response code ${statusCode} (${statusMessage})`, {}, opts); | ||
this.name = 'HTTPError'; | ||
this.statusCode = statusCode; | ||
this.statusMessage = statusMessage; | ||
this.headers = headers; | ||
} | ||
}; | ||
got.MaxRedirectsError = class extends StdError { | ||
constructor(statusCode, redirectUrls, opts) { | ||
super('Redirected 10 times. Aborting.', {}, opts); | ||
this.name = 'MaxRedirectsError'; | ||
this.statusCode = statusCode; | ||
this.statusMessage = http.STATUS_CODES[this.statusCode]; | ||
this.redirectUrls = redirectUrls; | ||
} | ||
}; | ||
got.UnsupportedProtocolError = class extends StdError { | ||
constructor(opts) { | ||
super(`Unsupported protocol "${opts.protocol}"`, {}, opts); | ||
this.name = 'UnsupportedProtocolError'; | ||
} | ||
}; | ||
module.exports = got; |
{ | ||
"name": "got", | ||
"version": "6.7.1", | ||
"version": "7.0.0", | ||
"description": "Simplified HTTP requests", | ||
@@ -17,2 +17,7 @@ "license": "MIT", | ||
"url": "github.com/floatdrop" | ||
}, | ||
{ | ||
"name": "Alexander Tesfamichael", | ||
"email": "alex.tesfamichael@gmail.com", | ||
"url": "alextes.me" | ||
} | ||
@@ -23,5 +28,2 @@ ], | ||
}, | ||
"browser": { | ||
"unzip-response": false | ||
}, | ||
"scripts": { | ||
@@ -47,22 +49,27 @@ "test": "xo && nyc ava", | ||
"wget", | ||
"fetch" | ||
"fetch", | ||
"net", | ||
"network", | ||
"electron" | ||
], | ||
"dependencies": { | ||
"create-error-class": "^3.0.0", | ||
"decompress-response": "^3.2.0", | ||
"duplexer3": "^0.1.4", | ||
"get-stream": "^3.0.0", | ||
"is-redirect": "^1.0.0", | ||
"is-plain-obj": "^1.1.0", | ||
"is-retry-allowed": "^1.0.0", | ||
"is-stream": "^1.0.0", | ||
"isurl": "^1.0.0-alpha5", | ||
"lowercase-keys": "^1.0.0", | ||
"p-cancelable": "^0.2.0", | ||
"p-timeout": "^1.1.1", | ||
"safe-buffer": "^5.0.1", | ||
"timed-out": "^4.0.0", | ||
"unzip-response": "^2.0.1", | ||
"url-parse-lax": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.17.0", | ||
"ava": "^0.19.1", | ||
"coveralls": "^2.11.4", | ||
"form-data": "^2.1.1", | ||
"get-port": "^2.0.0", | ||
"get-port": "^3.0.0", | ||
"into-stream": "^3.0.0", | ||
@@ -73,10 +80,12 @@ "nyc": "^10.0.0", | ||
"tempfile": "^1.1.1", | ||
"xo": "*" | ||
"tempy": "^0.1.0", | ||
"universal-url": "^1.0.0-alpha", | ||
"xo": "^0.18.0" | ||
}, | ||
"xo": { | ||
"esnext": true | ||
}, | ||
"ava": { | ||
"concurrency": 4 | ||
}, | ||
"browser": { | ||
"decompress-response": false | ||
} | ||
} |
115
readme.md
@@ -15,7 +15,9 @@ <h1 align="center"> | ||
It supports following redirects, promises, streams, retries, automagically handling gzip/deflate and some convenience options. | ||
It supports following redirects, promises, streams, retries, automagically handling gzip/deflate, canceling of requests, and some convenience options. | ||
Created because [`request`](https://github.com/request/request) is bloated *(several megabytes!)*. | ||
When used with Electron, it takes advantage of [`electron.net`](https://electron.atom.io/docs/api/net/). | ||
## Install | ||
@@ -66,3 +68,3 @@ | ||
The URL to request or a [`http.request` options](https://nodejs.org/api/http.html#http_http_request_options_callback) object. | ||
The URL to request as simple string, a [`http.request` options](https://nodejs.org/api/http.html#http_http_request_options_callback), or a [WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url). | ||
@@ -79,3 +81,3 @@ Properties from `options` will override properties in the parsed `url`. | ||
Type: `string`, `buffer`, `readableStream`, `object` | ||
Type: `string`, `buffer`, `readableStream` | ||
@@ -90,4 +92,2 @@ *This is mutually exclusive with stream mode.* | ||
If `body` is a plain object, it will be stringified with [`querystring.stringify`](https://nodejs.org/api/querystring.html#querystring_querystring_stringify_obj_sep_eq_options) and sent as `application/x-www-form-urlencoded`. | ||
###### encoding | ||
@@ -100,2 +100,13 @@ | ||
###### form | ||
Type: `boolean`<br> | ||
Default: `false` | ||
*This is mutually exclusive with stream mode.* | ||
If set to `true` and `Content-Type` header is not set, it will be set to `application/x-www-form-urlencoded`. | ||
`body` must be a plain object and will be stringified. | ||
###### json | ||
@@ -108,4 +119,8 @@ | ||
Parse response body with `JSON.parse` and set `accept` header to `application/json`. | ||
If set to `true` and `Content-Type` header is not set, it will be set to `application/json`. | ||
Parse response body with `JSON.parse` and set `accept` header to `application/json`. If used in conjunction with the `form` option, the `body` will the stringified as querystring and the response parsed as JSON. | ||
`body` must be a plain object and will be stringified. | ||
###### query | ||
@@ -121,5 +136,5 @@ | ||
Milliseconds to wait for a server to send response headers before aborting request with `ETIMEDOUT` error. | ||
Milliseconds to wait for the server to end the response before aborting request with `ETIMEDOUT` error. | ||
Option accepts `object` with separate `connect` and `socket` fields for connection and socket inactivity timeouts. | ||
This also accepts an object with separate `connect`, `socket`, and `request` fields for connection, socket, and entire request timeouts. | ||
@@ -129,3 +144,3 @@ ###### retries | ||
Type: `number`, `function`<br> | ||
Default: `5` | ||
Default: `2` | ||
@@ -145,3 +160,13 @@ Number of request retries when network errors happens. Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 0). | ||
Note that if a `303` is sent by the server in response to any request type (`POST`, `DELETE`, etc.), got will automatically | ||
request the resource pointed to in the location header via `GET`. This is in accordance with [the spec](https://tools.ietf.org/html/rfc7231#section-6.4.4). | ||
###### useElectronNet | ||
Type: `boolean`<br> | ||
Default: `true` | ||
When used in Electron, Got will automatically use [`electron.net`](https://electron.atom.io/docs/api/net/) instead of the Node.js `http` module. It should be fully compatible, but you can turn it off here if you encounter a problem. Please open an issue if you do! | ||
#### Streams | ||
@@ -188,3 +213,3 @@ | ||
Each error contains (if available) `statusCode`, `statusMessage`, `host`, `hostname`, `method` and `path` properties to make debugging easier. | ||
Each error contains (if available) `statusCode`, `statusMessage`, `host`, `hostname`, `method`, `path`, `protocol` and `url` properties to make debugging easier. | ||
@@ -203,13 +228,22 @@ In Promise mode, the `response` is attached to the error. | ||
When `json` option is enabled and `JSON.parse` fails. | ||
When `json` option is enabled, server response code is 2xx, and `JSON.parse` fails. | ||
#### got.HTTPError | ||
When server response code is not 2xx. Contains `statusCode` and `statusMessage`. | ||
When server response code is not 2xx. Includes `statusCode`, `statusMessage`, and `redirectUrls` properties. | ||
#### got.MaxRedirectsError | ||
When server redirects you more than 10 times. | ||
When server redirects you more than 10 times. Includes a `redirectUrls` property, which is an array of the URLs Got was redirected to before giving up. | ||
#### got.UnsupportedProtocolError | ||
When given an unsupported protocol. | ||
## Aborting the request | ||
The promise returned by Got has a `.cancel()` function which, when called, aborts the request. | ||
## Proxies | ||
@@ -314,5 +348,46 @@ | ||
## AWS | ||
## Tip | ||
Requests to AWS services need to have their headers signed. This can be accomplished by using the [`aws4`](https://www.npmjs.com/package/aws4) package. This is an example for querying an ["Elasticsearch Service"](https://aws.amazon.com/elasticsearch-service/) host with a signed request. | ||
```js | ||
const url = require('url'); | ||
const AWS = require('aws-sdk'); | ||
const aws4 = require('aws4'); | ||
const got = require('got'); | ||
const config = require('./config'); | ||
// Reads keys from the environment or `~/.aws/credentials`. Could be a plain object. | ||
const awsConfig = new AWS.Config({ region: config.region }); | ||
function request(uri, options) { | ||
const awsOpts = { | ||
region: awsConfig.region, | ||
headers: { | ||
accept: 'application/json', | ||
'content-type': 'application/json' | ||
}, | ||
method: 'GET', | ||
json: true | ||
}; | ||
// We need to parse the URL before passing it to `got` so `aws4` can sign the request | ||
const opts = Object.assign(url.parse(uri), awsOpts, options); | ||
aws4.sign(opts, awsConfig.credentials); | ||
return got(opts); | ||
} | ||
request(`https://${config.host}/production/users/1`); | ||
request(`https://${config.host}/production/`, { | ||
// All usual `got` options | ||
}); | ||
``` | ||
## Tips | ||
### User Agent | ||
It's a good idea to set the `'user-agent'` header so the provider can more easily see how their resource is used. By default, it's the URL to this repo. | ||
@@ -331,3 +406,7 @@ | ||
### 304 Responses | ||
Bear in mind, if you send an `if-modified-since` header and receive a `304 Not Modified` response, the body will be empty. It's your responsibility to cache and retrieve the body contents. | ||
## Related | ||
@@ -341,5 +420,5 @@ | ||
[![Sindre Sorhus](https://avatars.githubusercontent.com/u/170270?v=3&s=100)](https://sindresorhus.com) | [![Vsevolod Strukchinsky](https://avatars.githubusercontent.com/u/365089?v=3&s=100)](https://github.com/floatdrop) | ||
---|--- | ||
[Sindre Sorhus](https://sindresorhus.com) | [Vsevolod Strukchinsky](https://github.com/floatdrop) | ||
[![Sindre Sorhus](https://avatars.githubusercontent.com/u/170270?v=3&s=100)](https://sindresorhus.com) | [![Vsevolod Strukchinsky](https://avatars.githubusercontent.com/u/365089?v=3&s=100)](https://github.com/floatdrop) | [![Alexander Tesfamichael](https://avatars.githubusercontent.com/u/2011351?v=3&s=100)](https://alextes.me) | ||
---|---|--- | ||
[Sindre Sorhus](https://sindresorhus.com) | [Vsevolod Strukchinsky](https://github.com/floatdrop) | [Alexander Tesfamichael](https://alextes.me) | ||
@@ -349,2 +428,2 @@ | ||
MIT © [Sindre Sorhus](https://sindresorhus.com) | ||
MIT |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27593
383
415
13
12
+ Addeddecompress-response@^3.2.0
+ Addedis-plain-obj@^1.1.0
+ Addedisurl@^1.0.0-alpha5
+ Addedp-cancelable@^0.2.0
+ Addedp-timeout@^1.1.1
+ Addeddecompress-response@3.3.0(transitive)
+ Addedhas-symbol-support-x@1.4.2(transitive)
+ Addedhas-to-string-tag-x@1.4.1(transitive)
+ Addedis-object@1.0.2(transitive)
+ Addedis-plain-obj@1.1.0(transitive)
+ Addedisurl@1.0.0(transitive)
+ Addedmimic-response@1.0.1(transitive)
+ Addedp-cancelable@0.2.0(transitive)
+ Addedp-finally@1.0.0(transitive)
+ Addedp-timeout@1.2.1(transitive)
- Removedcreate-error-class@^3.0.0
- Removedis-redirect@^1.0.0
- Removedunzip-response@^2.0.1
- Removedcapture-stack-trace@1.0.2(transitive)
- Removedcreate-error-class@3.0.2(transitive)
- Removedis-redirect@1.0.0(transitive)
- Removedunzip-response@2.0.1(transitive)