got 11.5.2 → 11.7.0
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.
- package/dist/source/as-promise/index.d.ts +1 -3
- package/dist/source/as-promise/index.js +44 -125
- package/dist/source/as-promise/normalize-arguments.d.ts +3 -0
- package/dist/source/as-promise/normalize-arguments.js +78 -0
- package/dist/source/as-promise/parse-body.d.ts +3 -0
- package/dist/source/as-promise/parse-body.js +25 -0
- package/dist/source/as-promise/types.d.ts +206 -24
- package/dist/source/as-promise/types.js +18 -7
- package/dist/source/{as-promise → core}/calculate-retry-delay.d.ts +2 -1
- package/dist/source/core/calculate-retry-delay.js +29 -0
- package/dist/source/core/index.d.ts +823 -5
- package/dist/source/core/index.js +250 -58
- package/dist/source/core/utils/is-response-ok.d.ts +2 -0
- package/dist/source/core/utils/is-response-ok.js +8 -0
- package/dist/source/create.js +16 -7
- package/dist/source/index.js +3 -2
- package/dist/source/types.d.ts +240 -1
- package/package.json +20 -16
- package/readme.md +234 -21
- package/dist/source/as-promise/calculate-retry-delay.js +0 -38
- package/dist/source/as-promise/core.d.ts +0 -13
- package/dist/source/as-promise/core.js +0 -127
package/readme.md
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
<br>
|
|
6
6
|
<br>
|
|
7
7
|
<br>
|
|
8
|
-
<p align="center">Huge thanks to <a href="https://moxy.studio"><img src="https://sindresorhus.com/assets/thanks/moxy-logo.svg" width="150"></a> for sponsoring Sindre Sorhus!
|
|
8
|
+
<p align="center">Huge thanks to <a href="https://moxy.studio"><img src="https://sindresorhus.com/assets/thanks/moxy-logo.svg" valign="middle" width="150"></a> for sponsoring Sindre Sorhus!
|
|
9
9
|
</p>
|
|
10
|
+
<p align="center"><sup>(they love Got too!)</sup></p>
|
|
10
11
|
<br>
|
|
11
12
|
<br>
|
|
12
13
|
</div>
|
|
@@ -40,7 +41,7 @@ For browser usage, we recommend [Ky](https://github.com/sindresorhus/ky) by the
|
|
|
40
41
|
- [Errors with metadata](#errors)
|
|
41
42
|
- [JSON mode](#json-mode)
|
|
42
43
|
- [WHATWG URL support](#url)
|
|
43
|
-
- [HTTPS API](#https)
|
|
44
|
+
- [HTTPS API](#advanced-https-api)
|
|
44
45
|
- [Hooks](#hooks)
|
|
45
46
|
- [Instances with custom defaults](#instances)
|
|
46
47
|
- [Types](#types)
|
|
@@ -48,6 +49,7 @@ For browser usage, we recommend [Ky](https://github.com/sindresorhus/ky) by the
|
|
|
48
49
|
- [Plugins](documentation/lets-make-a-plugin.md)
|
|
49
50
|
- [Used by 4K+ packages and 1.8M+ repos](https://github.com/sindresorhus/got/network/dependents)
|
|
50
51
|
- [Actively maintained](https://github.com/sindresorhus/got/graphs/contributors)
|
|
52
|
+
- [Trusted by many companies](#widely-used)
|
|
51
53
|
|
|
52
54
|
## Install
|
|
53
55
|
|
|
@@ -144,7 +146,7 @@ If no protocol is specified, it will throw a `TypeError`.
|
|
|
144
146
|
|
|
145
147
|
**Note:** The query string is **not** parsed as search params. Example:
|
|
146
148
|
|
|
147
|
-
```
|
|
149
|
+
```js
|
|
148
150
|
got('https://example.com/?query=a b'); //=> https://example.com/?query=a%20b
|
|
149
151
|
got('https://example.com/', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b
|
|
150
152
|
|
|
@@ -319,6 +321,8 @@ const body = await got(url).json();
|
|
|
319
321
|
const body = await got(url, {responseType: 'json', resolveBodyOnly: true});
|
|
320
322
|
```
|
|
321
323
|
|
|
324
|
+
**Note:** `buffer` will return the raw body buffer. Modifying it will also alter the result of `promise.text()` and `promise.json()`. Before overwritting the buffer, please copy it first via `Buffer.from(buffer)`. See https://github.com/nodejs/node/issues/27080
|
|
325
|
+
|
|
322
326
|
###### parseJson
|
|
323
327
|
|
|
324
328
|
Type: `(text: string) => unknown`\
|
|
@@ -510,15 +514,15 @@ Default:
|
|
|
510
514
|
|
|
511
515
|
An object representing `limit`, `calculateDelay`, `methods`, `statusCodes`, `maxRetryAfter` and `errorCodes` fields for maximum retry count, retry handler, allowed methods, allowed status codes, maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time and allowed error codes.
|
|
512
516
|
|
|
513
|
-
**Note:** When using streams, this option is ignored. If the connection is reset when downloading, you need to catch the error and clear the file you were writing into to prevent duplicated content.
|
|
514
|
-
|
|
515
517
|
If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`.\
|
|
516
518
|
If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will cancel the request.
|
|
517
519
|
|
|
518
|
-
Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 1).
|
|
520
|
+
Delays between retries counts with function `1000 * Math.pow(2, retry - 1) + Math.random() * 100`, where `retry` is attempt number (starts from 1).
|
|
519
521
|
|
|
520
522
|
The `calculateDelay` property is a `function` that receives an object with `attemptCount`, `retryOptions`, `error` and `computedValue` properties for current retry count, the retry options, error and default computed value. The function must return a delay in milliseconds (or a Promise resolving with it) (`0` return value cancels retry).
|
|
521
523
|
|
|
524
|
+
**Note:** The `calculateDelay` function is responsible for the entire cache mechanism, including the `limit` property. To support it, you need to check whether `computedValue` is different than `0`.
|
|
525
|
+
|
|
522
526
|
By default, it retries *only* on the specified methods, status codes, and on these network errors:
|
|
523
527
|
- `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached.
|
|
524
528
|
- `ECONNRESET`: Connection was forcibly closed by a peer.
|
|
@@ -529,6 +533,36 @@ By default, it retries *only* on the specified methods, status codes, and on the
|
|
|
529
533
|
- `ENETUNREACH`: No internet connection.
|
|
530
534
|
- `EAI_AGAIN`: DNS lookup timed out.
|
|
531
535
|
|
|
536
|
+
<a name="retry-stream"></a>
|
|
537
|
+
|
|
538
|
+
You can retry Got streams too. The implementation looks like this:
|
|
539
|
+
|
|
540
|
+
```js
|
|
541
|
+
const got = require('got');
|
|
542
|
+
const fs = require('fs');
|
|
543
|
+
|
|
544
|
+
let writeStream;
|
|
545
|
+
|
|
546
|
+
const fn = (retryCount = 0) => {
|
|
547
|
+
const stream = got.stream('https://example.com');
|
|
548
|
+
stream.retryCount = retryCount;
|
|
549
|
+
|
|
550
|
+
if (writeStream) {
|
|
551
|
+
writeStream.destroy();
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
writeStream = fs.createWriteStream('example.com');
|
|
555
|
+
|
|
556
|
+
stream.pipe(writeStream);
|
|
557
|
+
|
|
558
|
+
// If you don't attach the listener, it will NOT make a retry.
|
|
559
|
+
// It automatically checks the listener count so it knows whether to retry or not :)
|
|
560
|
+
stream.once('retry', fn);
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
fn();
|
|
564
|
+
```
|
|
565
|
+
|
|
532
566
|
###### followRedirect
|
|
533
567
|
|
|
534
568
|
Type: `boolean`\
|
|
@@ -579,6 +613,13 @@ Default: `false`
|
|
|
579
613
|
|
|
580
614
|
[Cache adapter instance](#cache-adapters) for storing cached response data.
|
|
581
615
|
|
|
616
|
+
###### cacheOptions
|
|
617
|
+
|
|
618
|
+
Type: `object | undefined`\
|
|
619
|
+
Default: `{}`
|
|
620
|
+
|
|
621
|
+
[Cache options](https://github.com/kornelski/http-cache-semantics#constructor-options) used for the specified request.
|
|
622
|
+
|
|
582
623
|
###### dnsCache
|
|
583
624
|
|
|
584
625
|
Type: `CacheableLookup | false`\
|
|
@@ -689,7 +730,7 @@ Called with plain [request options](#options), right before their normalization.
|
|
|
689
730
|
See the [Request migration guide](documentation/migration-guides.md#breaking-changes) for an example.
|
|
690
731
|
|
|
691
732
|
**Note #1:** This hook must be synchronous!\
|
|
692
|
-
**Note #2:** Errors in this hook will be converted into an instances of [`RequestError`](#
|
|
733
|
+
**Note #2:** Errors in this hook will be converted into an instances of [`RequestError`](#gotrequesterror).\
|
|
693
734
|
**Note #3:** The options object may not have a `url` property. To modify it, use a `beforeRequest` hook instead.
|
|
694
735
|
|
|
695
736
|
###### hooks.beforeRequest
|
|
@@ -699,6 +740,24 @@ Default: `[]`
|
|
|
699
740
|
|
|
700
741
|
Called with [normalized](source/core/index.ts) [request options](#options). Got will make no further changes to the request before it is sent. This is especially useful in conjunction with [`got.extend()`](#instances) when you want to create an API client that, for example, uses HMAC-signing.
|
|
701
742
|
|
|
743
|
+
**Note:** Changing `options.json` or `options.form` has no effect on the request, you should change `options.body` instead. If needed, update the `options.headers` accordingly. Example:
|
|
744
|
+
|
|
745
|
+
```js
|
|
746
|
+
const got = require('got');
|
|
747
|
+
|
|
748
|
+
got.post({
|
|
749
|
+
json: {payload: 'old'},
|
|
750
|
+
hooks: {
|
|
751
|
+
beforeRequest: [
|
|
752
|
+
options => {
|
|
753
|
+
options.body = JSON.stringify({payload: 'new'});
|
|
754
|
+
options.headers['content-length'] = options.body.length.toString();
|
|
755
|
+
}
|
|
756
|
+
]
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
```
|
|
760
|
+
|
|
702
761
|
**Tip:** You can override the `request` function by returning a [`ClientRequest`-like](https://nodejs.org/api/http.html#http_class_http_clientrequest) instance or a [`IncomingMessage`-like](https://nodejs.org/api/http.html#http_class_http_incomingmessage) instance. This is very useful when creating a custom cache mechanism.
|
|
703
762
|
|
|
704
763
|
###### hooks.beforeRedirect
|
|
@@ -983,7 +1042,24 @@ Type: `string`
|
|
|
983
1042
|
|
|
984
1043
|
The passphrase to decrypt the `options.https.key` (if different keys have different passphrases refer to `options.https.key` documentation).
|
|
985
1044
|
|
|
986
|
-
#####
|
|
1045
|
+
##### https.pfx
|
|
1046
|
+
|
|
1047
|
+
Type: `string | Buffer | Array<string | Buffer | object>`
|
|
1048
|
+
|
|
1049
|
+
[PFX or PKCS12](https://en.wikipedia.org/wiki/PKCS_12) encoded private key and certificate chain. Using `options.https.pfx` is an alternative to providing `options.https.key` and `options.https.certificate` individually. A PFX is usually encrypted, and if it is, `options.https.passphrase` will be used to decrypt it.
|
|
1050
|
+
|
|
1051
|
+
Multiple PFX's can be be provided as an array of unencrypted buffers or an array of objects like:
|
|
1052
|
+
|
|
1053
|
+
```ts
|
|
1054
|
+
{
|
|
1055
|
+
buffer: string | Buffer,
|
|
1056
|
+
passphrase?: string
|
|
1057
|
+
}
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
This object form can only occur in an array. If the provided buffers are encrypted, `object.passphrase` can be used to decrypt them. If `object.passphrase` is not provided, `options.https.passphrase` will be used for decryption.
|
|
1061
|
+
|
|
1062
|
+
##### Examples for `https.key`, `https.certificate`, `https.passphrase`, and `https.pfx`
|
|
987
1063
|
|
|
988
1064
|
```js
|
|
989
1065
|
// Single key with certificate
|
|
@@ -1030,6 +1106,45 @@ got('https://example.com', {
|
|
|
1030
1106
|
]
|
|
1031
1107
|
}
|
|
1032
1108
|
});
|
|
1109
|
+
|
|
1110
|
+
// Single encrypted PFX with passphrase
|
|
1111
|
+
got('https://example.com', {
|
|
1112
|
+
https: {
|
|
1113
|
+
pfx: fs.readFileSync('./fake.pfx'),
|
|
1114
|
+
passphrase: 'passphrase'
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
// Multiple encrypted PFX's with different passphrases
|
|
1119
|
+
got('https://example.com', {
|
|
1120
|
+
https: {
|
|
1121
|
+
pfx: [
|
|
1122
|
+
{
|
|
1123
|
+
buffer: fs.readFileSync('./key1.pfx'),
|
|
1124
|
+
passphrase: 'passphrase1'
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
buffer: fs.readFileSync('./key2.pfx'),
|
|
1128
|
+
passphrase: 'passphrase2'
|
|
1129
|
+
}
|
|
1130
|
+
]
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
|
|
1134
|
+
// Multiple encrypted PFX's with single passphrase
|
|
1135
|
+
got('https://example.com', {
|
|
1136
|
+
https: {
|
|
1137
|
+
passphrase: 'passphrase',
|
|
1138
|
+
pfx: [
|
|
1139
|
+
{
|
|
1140
|
+
buffer: fs.readFileSync('./key1.pfx')
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
buffer: fs.readFileSync('./key2.pfx')
|
|
1144
|
+
}
|
|
1145
|
+
]
|
|
1146
|
+
}
|
|
1147
|
+
});
|
|
1033
1148
|
```
|
|
1034
1149
|
|
|
1035
1150
|
##### https.rejectUnauthorized
|
|
@@ -1250,6 +1365,13 @@ If the `content-length` header is missing, `total` will be `undefined`.
|
|
|
1250
1365
|
})();
|
|
1251
1366
|
```
|
|
1252
1367
|
|
|
1368
|
+
##### .once('retry', retryCount, error)
|
|
1369
|
+
|
|
1370
|
+
To enable retrying on a Got stream, it is required to have a `retry` handler attached.\
|
|
1371
|
+
When this event is emitted, you should reset the stream you were writing to and prepare the body again.
|
|
1372
|
+
|
|
1373
|
+
See the [`retry`](#retry-stream) option for an example implementation.
|
|
1374
|
+
|
|
1253
1375
|
##### .ip
|
|
1254
1376
|
|
|
1255
1377
|
Type: `string`
|
|
@@ -1276,7 +1398,7 @@ The same as `response.socket`.
|
|
|
1276
1398
|
|
|
1277
1399
|
##### .on('error', error)
|
|
1278
1400
|
|
|
1279
|
-
The emitted `error` is an instance of [`RequestError`](#
|
|
1401
|
+
The emitted `error` is an instance of [`RequestError`](#gotrequesterror).
|
|
1280
1402
|
|
|
1281
1403
|
#### Pagination
|
|
1282
1404
|
|
|
@@ -1574,7 +1696,7 @@ Additionaly, the errors may have `request` (Got Stream) and `response` (Got Resp
|
|
|
1574
1696
|
|
|
1575
1697
|
#### got.RequestError
|
|
1576
1698
|
|
|
1577
|
-
When a request fails. Contains a `code` property with error class code, like `ECONNREFUSED`.
|
|
1699
|
+
When a request fails. Contains a `code` property with error class code, like `ECONNREFUSED`. All the errors below inherit this one.
|
|
1578
1700
|
|
|
1579
1701
|
#### got.CacheError
|
|
1580
1702
|
|
|
@@ -1610,7 +1732,7 @@ When the request is aborted due to a [timeout](#timeout). Includes an `event` an
|
|
|
1610
1732
|
|
|
1611
1733
|
#### got.CancelError
|
|
1612
1734
|
|
|
1613
|
-
When the request is aborted with `.cancel()`.
|
|
1735
|
+
When the request is aborted with `.cancel()`.
|
|
1614
1736
|
|
|
1615
1737
|
## Aborting the request
|
|
1616
1738
|
|
|
@@ -1889,6 +2011,32 @@ nock('https://sindresorhus.com')
|
|
|
1889
2011
|
})();
|
|
1890
2012
|
```
|
|
1891
2013
|
|
|
2014
|
+
Bear in mind, that by default `nock` mocks only one request. Got will [retry](#retry) on failed requests by default, causing a `No match for request ...` error. The solution is to either disable retrying (set `options.retry` to `0`) or call `.persist()` on the mocked request.
|
|
2015
|
+
|
|
2016
|
+
```js
|
|
2017
|
+
const got = require('got');
|
|
2018
|
+
const nock = require('nock');
|
|
2019
|
+
|
|
2020
|
+
const scope = nock('https://sindresorhus.com')
|
|
2021
|
+
.get('/')
|
|
2022
|
+
.reply(500, 'Internal server error')
|
|
2023
|
+
.persist();
|
|
2024
|
+
|
|
2025
|
+
(async () => {
|
|
2026
|
+
try {
|
|
2027
|
+
await got('https://sindresorhus.com')
|
|
2028
|
+
} catch (error) {
|
|
2029
|
+
console.log(error.response.body);
|
|
2030
|
+
//=> 'Internal server error'
|
|
2031
|
+
|
|
2032
|
+
console.log(error.response.retryCount);
|
|
2033
|
+
//=> 2
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
scope.persist(false);
|
|
2037
|
+
})();
|
|
2038
|
+
```
|
|
2039
|
+
|
|
1892
2040
|
For real integration testing we recommend using [`ava`](https://github.com/avajs/ava) with [`create-test-server`](https://github.com/lukechilds/create-test-server). We're using a macro so we don't have to `server.listen()` and `server.close()` every test. Take a look at one of our tests:
|
|
1893
2041
|
|
|
1894
2042
|
```js
|
|
@@ -2046,7 +2194,7 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2046
2194
|
\* It's almost API compatible with the browser `fetch` API.\
|
|
2047
2195
|
\*\* Need to switch the protocol manually. Doesn't accept PUSH streams and doesn't reuse HTTP/2 sessions.\
|
|
2048
2196
|
\*\*\* Currently, only `DownloadProgress` event is supported, `UploadProgress` event is not supported.\
|
|
2049
|
-
:sparkle: Almost-stable feature, but the API may change. Don't
|
|
2197
|
+
:sparkle: Almost-stable feature, but the API may change. Don't hesitate to try it out!\
|
|
2050
2198
|
:grey_question: Feature in early stage of development. Very experimental.
|
|
2051
2199
|
|
|
2052
2200
|
<!-- GITHUB -->
|
|
@@ -2124,12 +2272,12 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2124
2272
|
[ab]: https://badgen.net/travis/axios/axios?label
|
|
2125
2273
|
[sb]: https://badgen.net/travis/visionmedia/superagent?label
|
|
2126
2274
|
|
|
2127
|
-
[g5]: https://travis-ci.
|
|
2128
|
-
[k5]: https://travis-ci.
|
|
2129
|
-
[r5]: https://travis-ci.org/request/request
|
|
2130
|
-
[n5]: https://travis-ci.org/bitinn/node-fetch
|
|
2131
|
-
[a5]: https://travis-ci.org/axios/axios
|
|
2132
|
-
[s5]: https://travis-ci.org/visionmedia/superagent
|
|
2275
|
+
[g5]: https://travis-ci.com/github/sindresorhus/got
|
|
2276
|
+
[k5]: https://travis-ci.com/github/sindresorhus/ky
|
|
2277
|
+
[r5]: https://travis-ci.org/github/request/request
|
|
2278
|
+
[n5]: https://travis-ci.org/github/bitinn/node-fetch
|
|
2279
|
+
[a5]: https://travis-ci.org/github/axios/axios
|
|
2280
|
+
[s5]: https://travis-ci.org/github/visionmedia/superagent
|
|
2133
2281
|
|
|
2134
2282
|
<!-- BUGS -->
|
|
2135
2283
|
[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
|
|
@@ -2236,9 +2384,9 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2236
2384
|
|
|
2237
2385
|
## Maintainers
|
|
2238
2386
|
|
|
2239
|
-
[](https://sindresorhus.com) | [](https://github.com/szmarczak)
|
|
2240
|
-
|
|
2241
|
-
[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak)
|
|
2387
|
+
[](https://sindresorhus.com) | [](https://github.com/szmarczak) | [](https://github.com/Giotino)
|
|
2388
|
+
---|---|---
|
|
2389
|
+
[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak) | [Giovanni Minotti](https://github.com/Giotino)
|
|
2242
2390
|
|
|
2243
2391
|
###### Former
|
|
2244
2392
|
|
|
@@ -2247,6 +2395,71 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2247
2395
|
- [Brandon Smith](https://github.com/brandon93s)
|
|
2248
2396
|
- [Luke Childs](https://github.com/lukechilds)
|
|
2249
2397
|
|
|
2398
|
+
<a name="widely-used"></a>
|
|
2399
|
+
## These amazing companies are using Got
|
|
2400
|
+
|
|
2401
|
+
<a href="https://segment.com"><img width="90" valign="middle" src="https://user-images.githubusercontent.com/697676/47693700-ddb62500-dbb7-11e8-8332-716a91010c2d.png"></a>
|
|
2402
|
+
|
|
2403
|
+
<a href="https://antora.org"><img width="100" valign="middle" src="https://user-images.githubusercontent.com/79351/47706840-d874cc80-dbef-11e8-87c6-5f0c60cbf5dc.png"></a>
|
|
2404
|
+
|
|
2405
|
+
<a href="https://getvoip.com"><img width="150" valign="middle" src="https://user-images.githubusercontent.com/10832620/47869404-429e9480-dddd-11e8-8a7a-ca43d7f06020.png"></a>
|
|
2406
|
+
|
|
2407
|
+
<a href="https://github.com/exoframejs/exoframe"><img width="150" valign="middle" src="https://user-images.githubusercontent.com/365944/47791460-11a95b80-dd1a-11e8-9070-e8f2a215e03a.png"></a>
|
|
2408
|
+
|
|
2409
|
+
<a href="http://karaokes.moe"><img width="140" valign="middle" src="https://camo.githubusercontent.com/6860e5fa4684c14d8e1aa65df0aba4e6808ea1a9/687474703a2f2f6b6172616f6b65732e6d6f652f6173736574732f696d616765732f696e6465782e706e67"></a>
|
|
2410
|
+
|
|
2411
|
+
<a href="https://github.com/renovatebot/renovate"><img width="150" valign="middle" src="https://camo.githubusercontent.com/206d470ac709b9a702a97b0c08d6f389a086793d/68747470733a2f2f72656e6f76617465626f742e636f6d2f696d616765732f6c6f676f2e737667"></a>
|
|
2412
|
+
|
|
2413
|
+
<a href="https://resist.bot"><img width="150" valign="middle" src="https://user-images.githubusercontent.com/3322287/51992724-28736180-2473-11e9-9764-599cfda4b012.png"></a>
|
|
2414
|
+
|
|
2415
|
+
<a href="https://www.naturalcycles.com"><img width="150" valign="middle" src="https://user-images.githubusercontent.com/170270/92244143-d0a8a200-eec2-11ea-9fc0-1c07f90b2113.png"></a>
|
|
2416
|
+
|
|
2417
|
+
<a href="https://microlink.io"><img width="150" valign="middle" src="https://user-images.githubusercontent.com/36894700/91992974-1cc5dc00-ed35-11ea-9d04-f58b42ce6a5e.png"></a>
|
|
2418
|
+
|
|
2419
|
+
<a href="https://radity.com"><img width="150" valign="middle" src="https://user-images.githubusercontent.com/29518613/91814036-97fb9500-ec44-11ea-8c6c-d198cc23ca29.png"></a>
|
|
2420
|
+
|
|
2421
|
+
<br>
|
|
2422
|
+
|
|
2423
|
+
> Segment is a happy user of Got! Got powers the main backend API that our app talks to. It's used by our in-house RPC client that we use to communicate with all microservices.
|
|
2424
|
+
>
|
|
2425
|
+
> — <a href="https://github.com/vadimdemedes">Vadim Demedes</a>
|
|
2426
|
+
|
|
2427
|
+
> Antora, a static site generator for creating documentation sites, uses Got to download the UI bundle. In Antora, the UI bundle (aka theme) is maintained as a separate project. That project exports the UI as a zip file we call the UI bundle. The main site generator downloads that UI from a URL using Got and streams it to vinyl-zip to extract the files. Those files go on to be used to create the HTML pages and supporting assets.
|
|
2428
|
+
>
|
|
2429
|
+
> — <a href="https://github.com/mojavelinux">Dan Allen</a>
|
|
2430
|
+
|
|
2431
|
+
> GetVoIP is happily using Got in production. One of the unique capabilities of Got is the ability to handle Unix sockets which enables us to build a full control interfaces for our docker stack.
|
|
2432
|
+
>
|
|
2433
|
+
> — <a href="https://github.com/danielkalen">Daniel Kalen</a>
|
|
2434
|
+
|
|
2435
|
+
> We're using Got inside of Exoframe to handle all the communication between CLI and server. Exoframe is a self-hosted tool that allows simple one-command deployments using Docker.
|
|
2436
|
+
>
|
|
2437
|
+
> — <a href="https://github.com/yamalight">Tim Ermilov</a>
|
|
2438
|
+
|
|
2439
|
+
> Karaoke Mugen uses Got to fetch content updates from its online server.
|
|
2440
|
+
>
|
|
2441
|
+
> — <a href="https://github.com/AxelTerizaki">Axel Terizaki</a>
|
|
2442
|
+
|
|
2443
|
+
> Renovate uses Got, gh-got and gl-got to send millions of queries per day to GitHub, GitLab, npmjs, PyPi, Packagist, Docker Hub, Terraform, CircleCI, and more.
|
|
2444
|
+
>
|
|
2445
|
+
> — <a href="https://github.com/rarkins">Rhys Arkins</a>
|
|
2446
|
+
|
|
2447
|
+
> Resistbot uses Got to communicate from the API frontend where all correspondence ingresses to the officials lookup database in back.
|
|
2448
|
+
>
|
|
2449
|
+
> — <a href="https://github.com/chris-erickson">Chris Erickson</a>
|
|
2450
|
+
|
|
2451
|
+
> Natural Cycles is using Got to communicate with all kinds of 3rd-party REST APIs (over 9000!).
|
|
2452
|
+
>
|
|
2453
|
+
> — <a href="https://github.com/kirillgroshkov">Kirill Groshkov</a>
|
|
2454
|
+
|
|
2455
|
+
> Microlink is a cloud browser as an API service that uses Got widely as the main HTTP client, serving ~22M requests a month, every time a network call needs to be performed.
|
|
2456
|
+
>
|
|
2457
|
+
> — <a href="https://github.com/Kikobeats">Kiko Beats</a>
|
|
2458
|
+
|
|
2459
|
+
> We’re using Got at Radity. Thanks for such an amazing work!
|
|
2460
|
+
>
|
|
2461
|
+
> — <a href="https://github.com/MirzayevFarid">Mirzayev Farid</a>
|
|
2462
|
+
|
|
2250
2463
|
## For enterprise
|
|
2251
2464
|
|
|
2252
2465
|
Available as part of the Tidelift Subscription.
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const types_1 = require("./types");
|
|
4
|
-
const retryAfterStatusCodes = new Set([413, 429, 503]);
|
|
5
|
-
const isErrorWithResponse = (error) => (error instanceof types_1.HTTPError || error instanceof types_1.ParseError || error instanceof types_1.MaxRedirectsError);
|
|
6
|
-
const calculateRetryDelay = ({ attemptCount, retryOptions, error }) => {
|
|
7
|
-
if (attemptCount > retryOptions.limit) {
|
|
8
|
-
return 0;
|
|
9
|
-
}
|
|
10
|
-
const hasMethod = retryOptions.methods.includes(error.options.method);
|
|
11
|
-
const hasErrorCode = retryOptions.errorCodes.includes(error.code);
|
|
12
|
-
const hasStatusCode = isErrorWithResponse(error) && retryOptions.statusCodes.includes(error.response.statusCode);
|
|
13
|
-
if (!hasMethod || (!hasErrorCode && !hasStatusCode)) {
|
|
14
|
-
return 0;
|
|
15
|
-
}
|
|
16
|
-
if (isErrorWithResponse(error)) {
|
|
17
|
-
const { response } = error;
|
|
18
|
-
if (response && 'retry-after' in response.headers && retryAfterStatusCodes.has(response.statusCode)) {
|
|
19
|
-
let after = Number(response.headers['retry-after']);
|
|
20
|
-
if (Number.isNaN(after)) {
|
|
21
|
-
after = Date.parse(response.headers['retry-after']) - Date.now();
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
after *= 1000;
|
|
25
|
-
}
|
|
26
|
-
if (retryOptions.maxRetryAfter === undefined || after > retryOptions.maxRetryAfter) {
|
|
27
|
-
return 0;
|
|
28
|
-
}
|
|
29
|
-
return after;
|
|
30
|
-
}
|
|
31
|
-
if (response.statusCode === 413) {
|
|
32
|
-
return 0;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const noise = Math.random() * 100;
|
|
36
|
-
return ((2 ** (attemptCount - 1)) * 1000) + noise;
|
|
37
|
-
};
|
|
38
|
-
exports.default = calculateRetryDelay;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { URL } from 'url';
|
|
3
|
-
import { Options, NormalizedOptions, Defaults, ResponseType, Response } from './types';
|
|
4
|
-
import Request, { ParseJsonFunction } from '../core';
|
|
5
|
-
export declare const knownBodyTypes: string[];
|
|
6
|
-
export declare const parseBody: (response: Response, responseType: ResponseType, parseJson: ParseJsonFunction, encoding?: "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex" | undefined) => unknown;
|
|
7
|
-
export default class PromisableRequest extends Request {
|
|
8
|
-
['constructor']: typeof PromisableRequest;
|
|
9
|
-
options: NormalizedOptions;
|
|
10
|
-
static normalizeArguments(url?: string | URL, nonNormalizedOptions?: Options, defaults?: Defaults): NormalizedOptions;
|
|
11
|
-
static mergeOptions(...sources: Options[]): NormalizedOptions;
|
|
12
|
-
_beforeError(error: Error): void;
|
|
13
|
-
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseBody = exports.knownBodyTypes = void 0;
|
|
4
|
-
const is_1 = require("@sindresorhus/is");
|
|
5
|
-
const types_1 = require("./types");
|
|
6
|
-
const core_1 = require("../core");
|
|
7
|
-
if (!core_1.knownHookEvents.includes('beforeRetry')) {
|
|
8
|
-
core_1.knownHookEvents.push('beforeRetry', 'afterResponse');
|
|
9
|
-
}
|
|
10
|
-
exports.knownBodyTypes = ['json', 'buffer', 'text'];
|
|
11
|
-
exports.parseBody = (response, responseType, parseJson, encoding) => {
|
|
12
|
-
const { rawBody } = response;
|
|
13
|
-
try {
|
|
14
|
-
if (responseType === 'text') {
|
|
15
|
-
return rawBody.toString(encoding);
|
|
16
|
-
}
|
|
17
|
-
if (responseType === 'json') {
|
|
18
|
-
return rawBody.length === 0 ? '' : parseJson(rawBody.toString());
|
|
19
|
-
}
|
|
20
|
-
if (responseType === 'buffer') {
|
|
21
|
-
return Buffer.from(rawBody);
|
|
22
|
-
}
|
|
23
|
-
throw new types_1.ParseError({
|
|
24
|
-
message: `Unknown body type '${responseType}'`,
|
|
25
|
-
name: 'Error'
|
|
26
|
-
}, response);
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
throw new types_1.ParseError(error, response);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
class PromisableRequest extends core_1.default {
|
|
33
|
-
static normalizeArguments(url, nonNormalizedOptions, defaults) {
|
|
34
|
-
const options = super.normalizeArguments(url, nonNormalizedOptions, defaults);
|
|
35
|
-
if (is_1.default.null_(options.encoding)) {
|
|
36
|
-
throw new TypeError('To get a Buffer, set `options.responseType` to `buffer` instead');
|
|
37
|
-
}
|
|
38
|
-
is_1.assert.any([is_1.default.string, is_1.default.undefined], options.encoding);
|
|
39
|
-
is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.resolveBodyOnly);
|
|
40
|
-
is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.methodRewriting);
|
|
41
|
-
is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.isStream);
|
|
42
|
-
is_1.assert.any([is_1.default.string, is_1.default.undefined], options.responseType);
|
|
43
|
-
// `options.responseType`
|
|
44
|
-
if (options.responseType === undefined) {
|
|
45
|
-
options.responseType = 'text';
|
|
46
|
-
}
|
|
47
|
-
// `options.retry`
|
|
48
|
-
const { retry } = options;
|
|
49
|
-
if (defaults) {
|
|
50
|
-
options.retry = { ...defaults.retry };
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
options.retry = {
|
|
54
|
-
calculateDelay: retryObject => retryObject.computedValue,
|
|
55
|
-
limit: 0,
|
|
56
|
-
methods: [],
|
|
57
|
-
statusCodes: [],
|
|
58
|
-
errorCodes: [],
|
|
59
|
-
maxRetryAfter: undefined
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (is_1.default.object(retry)) {
|
|
63
|
-
options.retry = {
|
|
64
|
-
...options.retry,
|
|
65
|
-
...retry
|
|
66
|
-
};
|
|
67
|
-
options.retry.methods = [...new Set(options.retry.methods.map(method => method.toUpperCase()))];
|
|
68
|
-
options.retry.statusCodes = [...new Set(options.retry.statusCodes)];
|
|
69
|
-
options.retry.errorCodes = [...new Set(options.retry.errorCodes)];
|
|
70
|
-
}
|
|
71
|
-
else if (is_1.default.number(retry)) {
|
|
72
|
-
options.retry.limit = retry;
|
|
73
|
-
}
|
|
74
|
-
if (is_1.default.undefined(options.retry.maxRetryAfter)) {
|
|
75
|
-
options.retry.maxRetryAfter = Math.min(
|
|
76
|
-
// TypeScript is not smart enough to handle `.filter(x => is.number(x))`.
|
|
77
|
-
// eslint-disable-next-line unicorn/no-fn-reference-in-iterator
|
|
78
|
-
...[options.timeout.request, options.timeout.connect].filter(is_1.default.number));
|
|
79
|
-
}
|
|
80
|
-
// `options.pagination`
|
|
81
|
-
if (is_1.default.object(options.pagination)) {
|
|
82
|
-
if (defaults) {
|
|
83
|
-
options.pagination = {
|
|
84
|
-
...defaults.pagination,
|
|
85
|
-
...options.pagination
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
const { pagination } = options;
|
|
89
|
-
if (!is_1.default.function_(pagination.transform)) {
|
|
90
|
-
throw new Error('`options.pagination.transform` must be implemented');
|
|
91
|
-
}
|
|
92
|
-
if (!is_1.default.function_(pagination.shouldContinue)) {
|
|
93
|
-
throw new Error('`options.pagination.shouldContinue` must be implemented');
|
|
94
|
-
}
|
|
95
|
-
if (!is_1.default.function_(pagination.filter)) {
|
|
96
|
-
throw new TypeError('`options.pagination.filter` must be implemented');
|
|
97
|
-
}
|
|
98
|
-
if (!is_1.default.function_(pagination.paginate)) {
|
|
99
|
-
throw new Error('`options.pagination.paginate` must be implemented');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// JSON mode
|
|
103
|
-
if (options.responseType === 'json' && options.headers.accept === undefined) {
|
|
104
|
-
options.headers.accept = 'application/json';
|
|
105
|
-
}
|
|
106
|
-
return options;
|
|
107
|
-
}
|
|
108
|
-
static mergeOptions(...sources) {
|
|
109
|
-
let mergedOptions;
|
|
110
|
-
for (const source of sources) {
|
|
111
|
-
mergedOptions = PromisableRequest.normalizeArguments(undefined, source, mergedOptions);
|
|
112
|
-
}
|
|
113
|
-
return mergedOptions;
|
|
114
|
-
}
|
|
115
|
-
_beforeError(error) {
|
|
116
|
-
if (this.destroyed) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (!(error instanceof core_1.RequestError)) {
|
|
120
|
-
error = new core_1.RequestError(error.message, error, this);
|
|
121
|
-
}
|
|
122
|
-
// Let the promise decide whether to abort or not
|
|
123
|
-
// It is also responsible for the `beforeError` hook
|
|
124
|
-
this.emit('error', error);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
exports.default = PromisableRequest;
|