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/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`](#got.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
- ##### Examples for `https.key`, `https.certificate` and `https.passphrase`
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`](#got.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`. Note that all other types of errors listed below are subclasses of this one, with the exception of `CancelError`.
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()`. This type is not a subclass of `RequestError` as it is re-exported from the `p-cancelable` package.
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 hestitate to try it out!\
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.org/sindresorhus/got
2128
- [k5]: https://travis-ci.org/sindresorhus/ky
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
- [![Sindre Sorhus](https://github.com/sindresorhus.png?size=100)](https://sindresorhus.com) | [![Szymon Marczak](https://github.com/szmarczak.png?size=100)](https://github.com/szmarczak)
2240
- ---|---
2241
- [Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak)
2387
+ [![Sindre Sorhus](https://github.com/sindresorhus.png?size=100)](https://sindresorhus.com) | [![Szymon Marczak](https://github.com/szmarczak.png?size=100)](https://github.com/szmarczak) | [![Giovanni Minotti](https://github.com/Giotino.png?size=100)](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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
2409
+ <a href="http://karaokes.moe"><img width="140" valign="middle" src="https://camo.githubusercontent.com/6860e5fa4684c14d8e1aa65df0aba4e6808ea1a9/687474703a2f2f6b6172616f6b65732e6d6f652f6173736574732f696d616765732f696e6465782e706e67"></a>
2410
+ &nbsp;&nbsp;&nbsp;&nbsp;
2411
+ <a href="https://github.com/renovatebot/renovate"><img width="150" valign="middle" src="https://camo.githubusercontent.com/206d470ac709b9a702a97b0c08d6f389a086793d/68747470733a2f2f72656e6f76617465626f742e636f6d2f696d616765732f6c6f676f2e737667"></a>
2412
+ &nbsp;&nbsp;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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;