got 12.0.0-beta.2 → 12.0.1
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 -1
- package/dist/source/as-promise/index.js +5 -9
- package/dist/source/as-promise/types.d.ts +19 -0
- package/dist/source/as-promise/types.js +3 -0
- package/dist/source/core/errors.js +1 -0
- package/dist/source/core/index.d.ts +6 -6
- package/dist/source/core/index.js +30 -6
- package/dist/source/core/options.d.ts +186 -66
- package/dist/source/core/options.js +90 -21
- package/dist/source/core/response.d.ts +2 -1
- package/dist/source/core/response.js +4 -4
- package/dist/source/core/timed-out.d.ts +1 -1
- package/dist/source/core/timed-out.js +1 -1
- package/dist/source/core/utils/get-body-size.d.ts +1 -1
- package/dist/source/core/utils/get-body-size.js +2 -1
- package/dist/source/core/utils/is-client-request.d.ts +2 -2
- package/dist/source/core/utils/is-form-data.d.ts +1 -1
- package/dist/source/core/utils/options-to-url.d.ts +1 -1
- package/dist/source/core/utils/options-to-url.js +1 -1
- package/dist/source/core/utils/proxy-events.d.ts +1 -1
- package/dist/source/core/utils/unhandle.d.ts +1 -1
- package/dist/source/core/utils/url-to-options.d.ts +1 -1
- package/dist/source/index.d.ts +1 -0
- package/dist/source/types.d.ts +2 -1
- package/package.json +32 -26
- package/readme.md +92 -73
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
2
|
import is from '@sindresorhus/is';
|
|
3
3
|
import PCancelable from 'p-cancelable';
|
|
4
4
|
import { HTTPError, RetryError, } from '../core/errors.js';
|
|
@@ -38,7 +38,7 @@ export default function asPromise(firstRequest) {
|
|
|
38
38
|
request.once('response', async (response) => {
|
|
39
39
|
// Parse body
|
|
40
40
|
const contentEncoding = (response.headers['content-encoding'] ?? '').toLowerCase();
|
|
41
|
-
const isCompressed = contentEncoding === 'gzip' || contentEncoding === '
|
|
41
|
+
const isCompressed = contentEncoding === 'gzip' || contentEncoding === 'deflate' || contentEncoding === 'br';
|
|
42
42
|
const { options } = request;
|
|
43
43
|
if (isCompressed && !options.decompress) {
|
|
44
44
|
response.body = response.rawBody;
|
|
@@ -48,7 +48,7 @@ export default function asPromise(firstRequest) {
|
|
|
48
48
|
response.body = parseBody(response, options.responseType, options.parseJson, options.encoding);
|
|
49
49
|
}
|
|
50
50
|
catch (error) {
|
|
51
|
-
//
|
|
51
|
+
// Fall back to `utf8`
|
|
52
52
|
response.body = response.rawBody.toString();
|
|
53
53
|
if (isResponseOk(response)) {
|
|
54
54
|
request._beforeError(error);
|
|
@@ -58,10 +58,7 @@ export default function asPromise(firstRequest) {
|
|
|
58
58
|
}
|
|
59
59
|
try {
|
|
60
60
|
const hooks = options.hooks.afterResponse;
|
|
61
|
-
|
|
62
|
-
// eslint-disable-next-line unicorn/no-for-loop
|
|
63
|
-
for (let index = 0; index < hooks.length; index++) {
|
|
64
|
-
const hook = hooks[index];
|
|
61
|
+
for (const [index, hook] of hooks.entries()) {
|
|
65
62
|
// @ts-expect-error TS doesn't notice that CancelableRequest is a Promise
|
|
66
63
|
// eslint-disable-next-line no-await-in-loop
|
|
67
64
|
response = await hook(response, async (updatedOptions) => {
|
|
@@ -75,7 +72,7 @@ export default function asPromise(firstRequest) {
|
|
|
75
72
|
options.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
|
|
76
73
|
throw new RetryError(request);
|
|
77
74
|
});
|
|
78
|
-
if (!(is.object(response) && is.number(response.statusCode) && response.body)) {
|
|
75
|
+
if (!(is.object(response) && is.number(response.statusCode) && !is.nullOrUndefined(response.body))) {
|
|
79
76
|
throw new TypeError('The `afterResponse` hook returned an invalid value');
|
|
80
77
|
}
|
|
81
78
|
}
|
|
@@ -108,7 +105,6 @@ export default function asPromise(firstRequest) {
|
|
|
108
105
|
request.once('error', onError);
|
|
109
106
|
const previousBody = request.options?.body;
|
|
110
107
|
request.once('retry', (newRetryCount, error) => {
|
|
111
|
-
// @ts-expect-error
|
|
112
108
|
firstRequest = undefined;
|
|
113
109
|
const newBody = request.options.body;
|
|
114
110
|
if (previousBody === newBody && is.nodeStream(newBody)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import type { Buffer } from 'node:buffer';
|
|
2
3
|
import PCancelable from 'p-cancelable';
|
|
3
4
|
import { RequestError } from '../core/errors.js';
|
|
4
5
|
import type Request from '../core/index.js';
|
|
@@ -10,10 +11,28 @@ An error to be thrown when the request is aborted with `.cancel()`.
|
|
|
10
11
|
export declare class CancelError extends RequestError {
|
|
11
12
|
readonly response: Response;
|
|
12
13
|
constructor(request: Request);
|
|
14
|
+
/**
|
|
15
|
+
Whether the promise is canceled.
|
|
16
|
+
*/
|
|
13
17
|
get isCanceled(): boolean;
|
|
14
18
|
}
|
|
15
19
|
export interface CancelableRequest<T extends Response | Response['body'] = Response['body']> extends PCancelable<T>, RequestEvents<CancelableRequest<T>> {
|
|
20
|
+
/**
|
|
21
|
+
A shortcut method that gives a Promise returning a JSON object.
|
|
22
|
+
|
|
23
|
+
It is semantically the same as settings `options.resolveBodyOnly` to `true` and `options.responseType` to `'json'`.
|
|
24
|
+
*/
|
|
16
25
|
json: <ReturnType>() => CancelableRequest<ReturnType>;
|
|
26
|
+
/**
|
|
27
|
+
A shortcut method that gives a Promise returning a [Buffer](https://nodejs.org/api/buffer.html).
|
|
28
|
+
|
|
29
|
+
It is semantically the same as settings `options.resolveBodyOnly` to `true` and `options.responseType` to `'buffer'`.
|
|
30
|
+
*/
|
|
17
31
|
buffer: () => CancelableRequest<Buffer>;
|
|
32
|
+
/**
|
|
33
|
+
A shortcut method that gives a Promise returning a string.
|
|
34
|
+
|
|
35
|
+
It is semantically the same as settings `options.resolveBodyOnly` to `true` and `options.responseType` to `'text'`.
|
|
36
|
+
*/
|
|
18
37
|
text: () => CancelableRequest<string>;
|
|
19
38
|
}
|
|
@@ -93,6 +93,7 @@ export class MaxRedirectsError extends RequestError {
|
|
|
93
93
|
An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
|
|
94
94
|
Includes a `response` property.
|
|
95
95
|
*/
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
96
97
|
export class HTTPError extends RequestError {
|
|
97
98
|
constructor(response) {
|
|
98
99
|
super(`Response code ${response.statusCode} (${response.statusMessage})`, {}, response.request);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { Duplex } from 'stream';
|
|
3
|
-
import { URL } from 'url';
|
|
4
|
-
import { ServerResponse } from 'http';
|
|
5
|
-
import type { ClientRequest } from 'http';
|
|
6
|
-
import type { Socket } from 'net';
|
|
2
|
+
import { Duplex } from 'node:stream';
|
|
3
|
+
import { URL } from 'node:url';
|
|
4
|
+
import { ServerResponse } from 'node:http';
|
|
5
|
+
import type { ClientRequest } from 'node:http';
|
|
6
|
+
import type { Socket } from 'node:net';
|
|
7
7
|
import CacheableRequest from 'cacheable-request';
|
|
8
8
|
import type { Timings } from '@szmarczak/http-timer';
|
|
9
9
|
import type ResponseLike from 'responselike';
|
|
@@ -114,7 +114,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
|
|
|
114
114
|
flush(): Promise<void>;
|
|
115
115
|
_beforeError(error: Error): void;
|
|
116
116
|
_read(): void;
|
|
117
|
-
_write(chunk:
|
|
117
|
+
_write(chunk: unknown, encoding: BufferEncoding | undefined, callback: (error?: Error | null) => void): void;
|
|
118
118
|
_final(callback: (error?: Error | null) => void): void;
|
|
119
119
|
_destroy(error: Error | null, callback: (error: Error | null) => void): void;
|
|
120
120
|
pipe<T extends NodeJS.WritableStream>(destination: T, options?: {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
import { Duplex } from 'node:stream';
|
|
4
|
+
import { URL, URLSearchParams } from 'node:url';
|
|
5
|
+
import http, { ServerResponse } from 'node:http';
|
|
4
6
|
import timer from '@szmarczak/http-timer';
|
|
5
7
|
import CacheableRequest from 'cacheable-request';
|
|
6
8
|
import decompressResponse from 'decompress-response';
|
|
7
9
|
import is from '@sindresorhus/is';
|
|
8
10
|
import { buffer as getBuffer } from 'get-stream';
|
|
11
|
+
import { FormDataEncoder, isFormDataLike } from 'form-data-encoder';
|
|
9
12
|
import getBodySize from './utils/get-body-size.js';
|
|
10
13
|
import isFormData from './utils/is-form-data.js';
|
|
11
14
|
import proxyEvents from './utils/proxy-events.js';
|
|
@@ -221,6 +224,11 @@ export default class Request extends Duplex {
|
|
|
221
224
|
Object.assign(this.options.headers, source.headers);
|
|
222
225
|
}
|
|
223
226
|
});
|
|
227
|
+
this.on('newListener', event => {
|
|
228
|
+
if (event === 'retry' && this.listenerCount('retry') > 0) {
|
|
229
|
+
throw new Error('A retry listener has been attached already.');
|
|
230
|
+
}
|
|
231
|
+
});
|
|
224
232
|
try {
|
|
225
233
|
this.options = new Options(url, options, defaults);
|
|
226
234
|
if (!this.options.url) {
|
|
@@ -377,7 +385,14 @@ export default class Request extends Duplex {
|
|
|
377
385
|
return;
|
|
378
386
|
}
|
|
379
387
|
this.destroy();
|
|
380
|
-
this.emit('retry', this.retryCount + 1, error)
|
|
388
|
+
this.emit('retry', this.retryCount + 1, error, (updatedOptions) => {
|
|
389
|
+
const request = new Request(options.url, updatedOptions, options);
|
|
390
|
+
request.retryCount = this.retryCount + 1;
|
|
391
|
+
process.nextTick(() => {
|
|
392
|
+
void request.flush();
|
|
393
|
+
});
|
|
394
|
+
return request;
|
|
395
|
+
});
|
|
381
396
|
return;
|
|
382
397
|
}
|
|
383
398
|
}
|
|
@@ -404,7 +419,6 @@ export default class Request extends Duplex {
|
|
|
404
419
|
}
|
|
405
420
|
}
|
|
406
421
|
}
|
|
407
|
-
// Node.js 12 has incorrect types, so the encoding must be a string
|
|
408
422
|
_write(chunk, encoding, callback) {
|
|
409
423
|
const write = () => {
|
|
410
424
|
this._writeRequest(chunk, encoding, callback);
|
|
@@ -493,6 +507,7 @@ export default class Request extends Duplex {
|
|
|
493
507
|
const { options } = this;
|
|
494
508
|
const { headers } = options;
|
|
495
509
|
const isForm = !is.undefined(options.form);
|
|
510
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
496
511
|
const isJSON = !is.undefined(options.json);
|
|
497
512
|
const isBody = !is.undefined(options.body);
|
|
498
513
|
const cannotHaveBody = methodsWithoutBody.has(options.method) && !(options.method === 'GET' && options.allowGetBody);
|
|
@@ -504,6 +519,15 @@ export default class Request extends Duplex {
|
|
|
504
519
|
// Serialize body
|
|
505
520
|
const noContentType = !is.string(headers['content-type']);
|
|
506
521
|
if (isBody) {
|
|
522
|
+
// Body is spec-compliant FormData
|
|
523
|
+
if (isFormDataLike(options.body)) {
|
|
524
|
+
const encoder = new FormDataEncoder(options.body);
|
|
525
|
+
if (noContentType) {
|
|
526
|
+
headers['content-type'] = encoder.headers['Content-Type'];
|
|
527
|
+
}
|
|
528
|
+
headers['content-length'] = encoder.headers['Content-Length'];
|
|
529
|
+
options.body = encoder.encode();
|
|
530
|
+
}
|
|
507
531
|
// Special case for https://github.com/form-data/form-data
|
|
508
532
|
if (isFormData(options.body) && noContentType) {
|
|
509
533
|
headers['content-type'] = `multipart/form-data; boundary=${options.body.getBoundary()}`;
|
|
@@ -826,7 +850,7 @@ export default class Request extends Duplex {
|
|
|
826
850
|
if (is.promise(result)) {
|
|
827
851
|
// We only need to implement the error handler in order to support HTTP2 caching.
|
|
828
852
|
// The result will be a promise anyway.
|
|
829
|
-
// @ts-expect-error
|
|
853
|
+
// @ts-expect-error ignore
|
|
830
854
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
831
855
|
result.once = (event, handler) => {
|
|
832
856
|
if (event === 'error') {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
import { URL, URLSearchParams } from 'node:url';
|
|
4
|
+
import { checkServerIdentity } from 'node:tls';
|
|
5
|
+
import http from 'node:http';
|
|
6
|
+
import https from 'node:https';
|
|
7
|
+
import type { Readable } from 'node:stream';
|
|
8
|
+
import type { Socket } from 'node:net';
|
|
9
|
+
import type { SecureContextOptions, DetailedPeerCertificate } from 'node:tls';
|
|
10
|
+
import type { Agent as HttpAgent, ClientRequest } from 'node:http';
|
|
11
|
+
import type { RequestOptions as HttpsRequestOptions, Agent as HttpsAgent } from 'node:https';
|
|
10
12
|
import CacheableLookup from 'cacheable-lookup';
|
|
11
13
|
import http2wrapper, { ClientHttp2Session } from 'http2-wrapper';
|
|
14
|
+
import type { FormDataLike } from 'form-data-encoder';
|
|
12
15
|
import type CacheableRequest from 'cacheable-request';
|
|
13
16
|
import type ResponseLike from 'responselike';
|
|
14
17
|
import type { IncomingMessageWithTimings } from '@szmarczak/http-timer';
|
|
@@ -50,39 +53,146 @@ All available hooks of Got.
|
|
|
50
53
|
*/
|
|
51
54
|
export interface Hooks {
|
|
52
55
|
/**
|
|
53
|
-
Called with plain request options, right before their normalization.
|
|
56
|
+
Called with the plain request options, right before their normalization.
|
|
57
|
+
|
|
58
|
+
The second argument represents the current `Options` instance.
|
|
59
|
+
|
|
60
|
+
@default []
|
|
61
|
+
|
|
62
|
+
**Note:**
|
|
63
|
+
> - This hook must be synchronous.
|
|
64
|
+
|
|
65
|
+
**Note:**
|
|
66
|
+
> - This is called every time options are merged.
|
|
67
|
+
|
|
68
|
+
**Note:**
|
|
69
|
+
> - The `options` object may not have the `url` property. To modify it, use a `beforeRequest` hook instead.
|
|
70
|
+
|
|
71
|
+
**Note:**
|
|
72
|
+
> - This hook is called when a new instance of `Options` is created.
|
|
73
|
+
> - Do not confuse this with the creation of `Request` or `got(…)`.
|
|
74
|
+
|
|
75
|
+
**Note:**
|
|
76
|
+
> - When using `got(url)` or `got(url, undefined, defaults)` this hook will **not** be called.
|
|
77
|
+
|
|
54
78
|
This is especially useful in conjunction with `got.extend()` when the input needs custom handling.
|
|
55
79
|
|
|
56
|
-
|
|
80
|
+
For example, this can be used to fix typos to migrate from older versions faster.
|
|
57
81
|
|
|
58
|
-
|
|
82
|
+
@example
|
|
83
|
+
```
|
|
84
|
+
import got from 'got';
|
|
59
85
|
|
|
60
|
-
|
|
61
|
-
|
|
86
|
+
const instance = got.extend({
|
|
87
|
+
hooks: {
|
|
88
|
+
init: [
|
|
89
|
+
plain => {
|
|
90
|
+
if ('followRedirects' in plain) {
|
|
91
|
+
plain.followRedirect = plain.followRedirects;
|
|
92
|
+
delete plain.followRedirects;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
});
|
|
62
98
|
|
|
63
|
-
|
|
99
|
+
// Normally, the following would throw:
|
|
100
|
+
const response = await instance(
|
|
101
|
+
'https://example.com',
|
|
102
|
+
{
|
|
103
|
+
followRedirects: true
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// There is no option named `followRedirects`, but we correct it in an `init` hook.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Or you can create your own option and store it in a context:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
import got from 'got';
|
|
114
|
+
|
|
115
|
+
const instance = got.extend({
|
|
116
|
+
hooks: {
|
|
117
|
+
init: [
|
|
118
|
+
(plain, options) => {
|
|
119
|
+
if ('secret' in plain) {
|
|
120
|
+
options.context.secret = plain.secret;
|
|
121
|
+
delete plain.secret;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
beforeRequest: [
|
|
126
|
+
options => {
|
|
127
|
+
options.headers.secret = options.context.secret;
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const {headers} = await instance(
|
|
134
|
+
'https://httpbin.org/anything',
|
|
135
|
+
{
|
|
136
|
+
secret: 'passphrase'
|
|
137
|
+
}
|
|
138
|
+
).json();
|
|
139
|
+
|
|
140
|
+
console.log(headers.Secret);
|
|
141
|
+
//=> 'passphrase'
|
|
142
|
+
```
|
|
64
143
|
*/
|
|
65
144
|
init: InitHook[];
|
|
66
145
|
/**
|
|
67
|
-
Called
|
|
68
|
-
|
|
69
|
-
This is especially useful in conjunction with `got.extend()` when you want to
|
|
146
|
+
Called right before making the request with `options.createNativeRequestOptions()`.
|
|
147
|
+
|
|
148
|
+
This hook is especially useful in conjunction with `got.extend()` when you want to sign your request.
|
|
70
149
|
|
|
71
150
|
@default []
|
|
151
|
+
|
|
152
|
+
**Note:**
|
|
153
|
+
> - Got will make no further changes to the request before it is sent.
|
|
154
|
+
|
|
155
|
+
**Note:**
|
|
156
|
+
> - 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.
|
|
157
|
+
|
|
158
|
+
@example
|
|
159
|
+
```
|
|
160
|
+
import got from 'got';
|
|
161
|
+
|
|
162
|
+
const response = await got.post(
|
|
163
|
+
'https://httpbin.org/anything',
|
|
164
|
+
{
|
|
165
|
+
json: {payload: 'old'},
|
|
166
|
+
hooks: {
|
|
167
|
+
beforeRequest: [
|
|
168
|
+
options => {
|
|
169
|
+
options.body = JSON.stringify({payload: 'new'});
|
|
170
|
+
options.headers['content-length'] = options.body.length.toString();
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Tip:**
|
|
179
|
+
> - You can indirectly override the `request` function by early 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.
|
|
180
|
+
> - [Read more about this tip](https://github.com/sindresorhus/got/blob/main/documentation/cache.md#advanced-caching-mechanisms).
|
|
72
181
|
*/
|
|
73
182
|
beforeRequest: BeforeRequestHook[];
|
|
74
183
|
/**
|
|
75
|
-
|
|
76
|
-
Got will make no further changes to the request.
|
|
77
|
-
This is especially useful when you want to avoid dead sites.
|
|
184
|
+
The equivalent of `beforeRequest` but when redirecting.
|
|
78
185
|
|
|
79
186
|
@default []
|
|
80
187
|
|
|
188
|
+
**Tip:**
|
|
189
|
+
> - This is especially useful when you want to avoid dead sites.
|
|
190
|
+
|
|
81
191
|
@example
|
|
82
192
|
```
|
|
83
193
|
import got from 'got';
|
|
84
194
|
|
|
85
|
-
await got('https://example.com', {
|
|
195
|
+
const response = await got('https://example.com', {
|
|
86
196
|
hooks: {
|
|
87
197
|
beforeRedirect: [
|
|
88
198
|
(options, response) => {
|
|
@@ -97,19 +207,17 @@ export interface Hooks {
|
|
|
97
207
|
*/
|
|
98
208
|
beforeRedirect: BeforeRedirectHook[];
|
|
99
209
|
/**
|
|
100
|
-
Called with
|
|
101
|
-
The error is passed to the hook right before it's thrown.
|
|
102
|
-
This is especially useful when you want to have more detailed errors.
|
|
210
|
+
Called with a `RequestError` instance. The error is passed to the hook right before it's thrown.
|
|
103
211
|
|
|
104
|
-
|
|
212
|
+
This is especially useful when you want to have more detailed errors.
|
|
105
213
|
|
|
106
214
|
@default []
|
|
107
215
|
|
|
108
|
-
@example
|
|
109
216
|
```
|
|
110
217
|
import got from 'got';
|
|
111
218
|
|
|
112
|
-
await got('https://api.github.com/
|
|
219
|
+
await got('https://api.github.com/repos/sindresorhus/got/commits', {
|
|
220
|
+
responseType: 'json',
|
|
113
221
|
hooks: {
|
|
114
222
|
beforeError: [
|
|
115
223
|
error => {
|
|
@@ -128,26 +236,31 @@ export interface Hooks {
|
|
|
128
236
|
*/
|
|
129
237
|
beforeError: BeforeErrorHook[];
|
|
130
238
|
/**
|
|
131
|
-
|
|
132
|
-
Got will make no further changes to the request.
|
|
133
|
-
This is especially useful when some extra work is required before the next try.
|
|
134
|
-
|
|
135
|
-
__Note__: When using streams, this hook is ignored.
|
|
136
|
-
__Note__: When retrying in a `afterResponse` hook, all remaining `beforeRetry` hooks will be called without the `error` and `retryCount` arguments.
|
|
239
|
+
The equivalent of `beforeError` but when retrying. Additionally, there is a second argument `retryCount`, the current retry number.
|
|
137
240
|
|
|
138
241
|
@default []
|
|
139
242
|
|
|
243
|
+
**Note:**
|
|
244
|
+
> - When using the Stream API, this hook is ignored.
|
|
245
|
+
|
|
246
|
+
**Note:**
|
|
247
|
+
> - When retrying, the `beforeRequest` hook is called afterwards.
|
|
248
|
+
|
|
249
|
+
**Note:**
|
|
250
|
+
> - If no retry occurs, the `beforeError` hook is called instead.
|
|
251
|
+
|
|
252
|
+
This hook is especially useful when you want to retrieve the cause of a retry.
|
|
253
|
+
|
|
140
254
|
@example
|
|
141
255
|
```
|
|
142
256
|
import got from 'got';
|
|
143
257
|
|
|
144
|
-
got
|
|
258
|
+
await got('https://httpbin.org/status/500', {
|
|
145
259
|
hooks: {
|
|
146
260
|
beforeRetry: [
|
|
147
|
-
(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
261
|
+
(error, retryCount) => {
|
|
262
|
+
console.log(`Retrying [${retryCount}]: ${error.code}`);
|
|
263
|
+
// Retrying [1]: ERR_NON_2XX_3XX_RESPONSE
|
|
151
264
|
}
|
|
152
265
|
]
|
|
153
266
|
}
|
|
@@ -156,13 +269,16 @@ export interface Hooks {
|
|
|
156
269
|
*/
|
|
157
270
|
beforeRetry: BeforeRetryHook[];
|
|
158
271
|
/**
|
|
159
|
-
|
|
160
|
-
Calling the retry function will trigger `beforeRetry` hooks.
|
|
272
|
+
Each function should return the response. This is especially useful when you want to refresh an access token.
|
|
161
273
|
|
|
162
|
-
|
|
163
|
-
This is especially useful when you want to refresh an access token.
|
|
274
|
+
@default []
|
|
164
275
|
|
|
165
|
-
|
|
276
|
+
**Note:**
|
|
277
|
+
> - When using the Stream API, this hook is ignored.
|
|
278
|
+
|
|
279
|
+
**Note:**
|
|
280
|
+
> - Calling the `retryWithMergedOptions` function will trigger `beforeRetry` hooks. If the retry is successful, all remaining `afterResponse` hooks will be called. In case of an error, `beforeRetry` hooks will be called instead.
|
|
281
|
+
Meanwhile the `init`, `beforeRequest` , `beforeRedirect` as well as already executed `afterResponse` hooks will be skipped.
|
|
166
282
|
|
|
167
283
|
@example
|
|
168
284
|
```
|
|
@@ -172,15 +288,17 @@ export interface Hooks {
|
|
|
172
288
|
hooks: {
|
|
173
289
|
afterResponse: [
|
|
174
290
|
(response, retryWithMergedOptions) => {
|
|
175
|
-
|
|
291
|
+
// Unauthorized
|
|
292
|
+
if (response.statusCode === 401) {
|
|
293
|
+
// Refresh the access token
|
|
176
294
|
const updatedOptions = {
|
|
177
295
|
headers: {
|
|
178
|
-
token: getNewToken()
|
|
296
|
+
token: getNewToken()
|
|
179
297
|
}
|
|
180
298
|
};
|
|
181
299
|
|
|
182
|
-
//
|
|
183
|
-
instance.defaults.options
|
|
300
|
+
// Update the defaults
|
|
301
|
+
instance.defaults.options.merge(updatedOptions);
|
|
184
302
|
|
|
185
303
|
// Make a new retry
|
|
186
304
|
return retryWithMergedOptions(updatedOptions);
|
|
@@ -191,7 +309,7 @@ export interface Hooks {
|
|
|
191
309
|
}
|
|
192
310
|
],
|
|
193
311
|
beforeRetry: [
|
|
194
|
-
|
|
312
|
+
error => {
|
|
195
313
|
// This will be called on `retryWithMergedOptions(...)`
|
|
196
314
|
}
|
|
197
315
|
]
|
|
@@ -559,12 +677,12 @@ export default class Options {
|
|
|
559
677
|
|
|
560
678
|
__Note #4__: This option is not enumerable and will not be merged with the instance defaults.
|
|
561
679
|
|
|
562
|
-
The `content-length` header will be automatically set if `body` is a `string` / `Buffer` / [`form-data` instance](https://github.com/form-data/form-data), and `content-length` and `transfer-encoding` are not manually set in `options.headers`.
|
|
680
|
+
The `content-length` header will be automatically set if `body` is a `string` / `Buffer` / [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) / [`form-data` instance](https://github.com/form-data/form-data), and `content-length` and `transfer-encoding` are not manually set in `options.headers`.
|
|
563
681
|
|
|
564
682
|
Since Got 12, the `content-length` is not automatically set when `body` is a `fs.createReadStream`.
|
|
565
683
|
*/
|
|
566
|
-
get body(): string | Buffer | Readable | Generator | AsyncGenerator | undefined;
|
|
567
|
-
set body(value: string | Buffer | Readable | Generator | AsyncGenerator | undefined);
|
|
684
|
+
get body(): string | Buffer | Readable | Generator | AsyncGenerator | FormDataLike | undefined;
|
|
685
|
+
set body(value: string | Buffer | Readable | Generator | AsyncGenerator | FormDataLike | undefined);
|
|
568
686
|
/**
|
|
569
687
|
The form body is converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
|
|
570
688
|
|
|
@@ -982,25 +1100,27 @@ export default class Options {
|
|
|
982
1100
|
headers: Headers;
|
|
983
1101
|
timeout: Delays;
|
|
984
1102
|
request: RequestFunction | undefined;
|
|
1103
|
+
username: string;
|
|
1104
|
+
password: string;
|
|
985
1105
|
json: Record<string, any> | undefined;
|
|
986
1106
|
retry: Partial<RetryOptions>;
|
|
987
1107
|
agent: Agents;
|
|
988
1108
|
h2session: http2wrapper.ClientHttp2Session | undefined;
|
|
989
1109
|
decompress: boolean;
|
|
990
1110
|
prefixUrl: string | URL;
|
|
991
|
-
body: string | Readable | Buffer | Generator<unknown, any, unknown> | AsyncGenerator<unknown, any, unknown> | undefined;
|
|
1111
|
+
body: string | Readable | Buffer | Generator<unknown, any, unknown> | AsyncGenerator<unknown, any, unknown> | FormDataLike | undefined;
|
|
992
1112
|
form: Record<string, any> | undefined;
|
|
993
1113
|
url: string | URL | undefined;
|
|
994
1114
|
cookieJar: PromiseCookieJar | ToughCookieJar | undefined;
|
|
995
1115
|
ignoreInvalidCookies: boolean;
|
|
996
1116
|
searchParams: string | SearchParameters | URLSearchParams | undefined;
|
|
997
1117
|
dnsLookup: {
|
|
998
|
-
(hostname: string, family: import("cacheable-lookup").IPFamily, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
999
|
-
(hostname: string, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1118
|
+
(hostname: string, family: import("cacheable-lookup").IPFamily, callback: (error: NodeJS.ErrnoException | null, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1119
|
+
(hostname: string, callback: (error: NodeJS.ErrnoException | null, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1000
1120
|
(hostname: string, options: import("cacheable-lookup").LookupOptions & {
|
|
1001
1121
|
all: true;
|
|
1002
|
-
}, callback: (error: NodeJS.ErrnoException, result: readonly import("cacheable-lookup").EntryObject[]) => void): void;
|
|
1003
|
-
(hostname: string, options: import("cacheable-lookup").LookupOptions, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1122
|
+
}, callback: (error: NodeJS.ErrnoException | null, result: readonly import("cacheable-lookup").EntryObject[]) => void): void;
|
|
1123
|
+
(hostname: string, options: import("cacheable-lookup").LookupOptions, callback: (error: NodeJS.ErrnoException | null, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1004
1124
|
} | undefined;
|
|
1005
1125
|
dnsCache: boolean | CacheableLookup | undefined;
|
|
1006
1126
|
context: Record<string, unknown>;
|
|
@@ -1009,8 +1129,6 @@ export default class Options {
|
|
|
1009
1129
|
maxRedirects: number;
|
|
1010
1130
|
cache: string | boolean | CacheableRequest.StorageAdapter | undefined;
|
|
1011
1131
|
throwHttpErrors: boolean;
|
|
1012
|
-
username: string;
|
|
1013
|
-
password: string;
|
|
1014
1132
|
http2: boolean;
|
|
1015
1133
|
allowGetBody: boolean;
|
|
1016
1134
|
methodRewriting: boolean;
|
|
@@ -1031,6 +1149,7 @@ export default class Options {
|
|
|
1031
1149
|
maxHeaderSize: number | undefined;
|
|
1032
1150
|
};
|
|
1033
1151
|
createNativeRequestOptions(): {
|
|
1152
|
+
ALPNProtocols: string[] | undefined;
|
|
1034
1153
|
ca: string | Buffer | (string | Buffer)[] | undefined;
|
|
1035
1154
|
cert: string | Buffer | (string | Buffer)[] | undefined;
|
|
1036
1155
|
key: string | Buffer | (Buffer | import("tls").KeyObject)[] | undefined;
|
|
@@ -1048,15 +1167,15 @@ export default class Options {
|
|
|
1048
1167
|
ecdhCurve: string | undefined;
|
|
1049
1168
|
crl: string | Buffer | (string | Buffer)[] | undefined;
|
|
1050
1169
|
lookup: {
|
|
1051
|
-
(hostname: string, family: import("cacheable-lookup").IPFamily, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1052
|
-
(hostname: string, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1170
|
+
(hostname: string, family: import("cacheable-lookup").IPFamily, callback: (error: NodeJS.ErrnoException | null, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1171
|
+
(hostname: string, callback: (error: NodeJS.ErrnoException | null, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1053
1172
|
(hostname: string, options: import("cacheable-lookup").LookupOptions & {
|
|
1054
1173
|
all: true;
|
|
1055
|
-
}, callback: (error: NodeJS.ErrnoException, result: readonly import("cacheable-lookup").EntryObject[]) => void): void;
|
|
1056
|
-
(hostname: string, options: import("cacheable-lookup").LookupOptions, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1174
|
+
}, callback: (error: NodeJS.ErrnoException | null, result: readonly import("cacheable-lookup").EntryObject[]) => void): void;
|
|
1175
|
+
(hostname: string, options: import("cacheable-lookup").LookupOptions, callback: (error: NodeJS.ErrnoException | null, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1057
1176
|
} | undefined;
|
|
1058
1177
|
family: DnsLookupIpVersion;
|
|
1059
|
-
agent: false | Agents |
|
|
1178
|
+
agent: false | Agents | http.Agent | undefined;
|
|
1060
1179
|
setHost: boolean;
|
|
1061
1180
|
method: Method;
|
|
1062
1181
|
maxHeaderSize: number | undefined;
|
|
@@ -1065,6 +1184,7 @@ export default class Options {
|
|
|
1065
1184
|
createConnection: CreateConnectionFunction | undefined;
|
|
1066
1185
|
timeout: number | undefined;
|
|
1067
1186
|
h2session: http2wrapper.ClientHttp2Session | undefined;
|
|
1187
|
+
signal?: AbortSignal | undefined;
|
|
1068
1188
|
protocol?: string | null | undefined;
|
|
1069
1189
|
host?: string | null | undefined;
|
|
1070
1190
|
hostname?: string | null | undefined;
|
|
@@ -1073,7 +1193,7 @@ export default class Options {
|
|
|
1073
1193
|
socketPath?: string | undefined;
|
|
1074
1194
|
path?: string | null | undefined;
|
|
1075
1195
|
auth?: string | null | undefined;
|
|
1076
|
-
_defaultAgent?:
|
|
1196
|
+
_defaultAgent?: http.Agent | undefined;
|
|
1077
1197
|
clientCertEngine?: string | undefined;
|
|
1078
1198
|
privateKeyEngine?: string | undefined;
|
|
1079
1199
|
privateKeyIdentifier?: string | undefined;
|
|
@@ -1087,8 +1207,8 @@ export default class Options {
|
|
|
1087
1207
|
immutableMinTimeToLive?: number | undefined;
|
|
1088
1208
|
ignoreCargoCult?: boolean | undefined;
|
|
1089
1209
|
};
|
|
1090
|
-
getRequestFunction(): RequestFunction | typeof
|
|
1091
|
-
getFallbackRequestFunction(): RequestFunction | typeof
|
|
1210
|
+
getRequestFunction(): RequestFunction | typeof https.request | undefined;
|
|
1211
|
+
getFallbackRequestFunction(): RequestFunction | typeof https.request | undefined;
|
|
1092
1212
|
freeze(): void;
|
|
1093
1213
|
}
|
|
1094
1214
|
export {};
|