got 12.0.0-beta.4 → 12.0.2
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 +4 -8
- 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 +31 -8
- package/dist/source/core/options.d.ts +183 -66
- package/dist/source/core/options.js +38 -31
- package/dist/source/core/response.d.ts +2 -1
- package/dist/source/core/response.js +5 -5
- 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 +35 -29
- package/readme.md +86 -75
|
@@ -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) => {
|
|
@@ -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
|
}
|
|
@@ -395,7 +410,7 @@ export default class Request extends Duplex {
|
|
|
395
410
|
}
|
|
396
411
|
let data;
|
|
397
412
|
while ((data = response.read()) !== null) {
|
|
398
|
-
this._downloadedSize += data.length;
|
|
413
|
+
this._downloadedSize += data.length; // eslint-disable-line @typescript-eslint/restrict-plus-operands
|
|
399
414
|
const progress = this.downloadProgress;
|
|
400
415
|
if (progress.percent < 1) {
|
|
401
416
|
this.emit('downloadProgress', progress);
|
|
@@ -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') {
|
|
@@ -1093,7 +1117,6 @@ export default class Request extends Duplex {
|
|
|
1093
1117
|
return this._isFromCache;
|
|
1094
1118
|
}
|
|
1095
1119
|
get reusedSocket() {
|
|
1096
|
-
// @ts-expect-error `@types/node` has incomplete types
|
|
1097
1120
|
return this._request?.reusedSocket;
|
|
1098
1121
|
}
|
|
1099
1122
|
}
|
|
@@ -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,14 +269,15 @@ export interface Hooks {
|
|
|
156
269
|
*/
|
|
157
270
|
beforeRetry: BeforeRetryHook[];
|
|
158
271
|
/**
|
|
159
|
-
|
|
272
|
+
Each function should return the response. This is especially useful when you want to refresh an access token.
|
|
160
273
|
|
|
161
|
-
|
|
162
|
-
This is especially useful when you want to refresh an access token.
|
|
274
|
+
@default []
|
|
163
275
|
|
|
164
|
-
|
|
276
|
+
**Note:**
|
|
277
|
+
> - When using the Stream API, this hook is ignored.
|
|
165
278
|
|
|
166
|
-
|
|
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.
|
|
167
281
|
Meanwhile the `init`, `beforeRequest` , `beforeRedirect` as well as already executed `afterResponse` hooks will be skipped.
|
|
168
282
|
|
|
169
283
|
@example
|
|
@@ -174,15 +288,17 @@ export interface Hooks {
|
|
|
174
288
|
hooks: {
|
|
175
289
|
afterResponse: [
|
|
176
290
|
(response, retryWithMergedOptions) => {
|
|
177
|
-
|
|
291
|
+
// Unauthorized
|
|
292
|
+
if (response.statusCode === 401) {
|
|
293
|
+
// Refresh the access token
|
|
178
294
|
const updatedOptions = {
|
|
179
295
|
headers: {
|
|
180
|
-
token: getNewToken()
|
|
296
|
+
token: getNewToken()
|
|
181
297
|
}
|
|
182
298
|
};
|
|
183
299
|
|
|
184
|
-
//
|
|
185
|
-
instance.defaults.options
|
|
300
|
+
// Update the defaults
|
|
301
|
+
instance.defaults.options.merge(updatedOptions);
|
|
186
302
|
|
|
187
303
|
// Make a new retry
|
|
188
304
|
return retryWithMergedOptions(updatedOptions);
|
|
@@ -193,7 +309,7 @@ export interface Hooks {
|
|
|
193
309
|
}
|
|
194
310
|
],
|
|
195
311
|
beforeRetry: [
|
|
196
|
-
|
|
312
|
+
error => {
|
|
197
313
|
// This will be called on `retryWithMergedOptions(...)`
|
|
198
314
|
}
|
|
199
315
|
]
|
|
@@ -561,12 +677,12 @@ export default class Options {
|
|
|
561
677
|
|
|
562
678
|
__Note #4__: This option is not enumerable and will not be merged with the instance defaults.
|
|
563
679
|
|
|
564
|
-
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`.
|
|
565
681
|
|
|
566
682
|
Since Got 12, the `content-length` is not automatically set when `body` is a `fs.createReadStream`.
|
|
567
683
|
*/
|
|
568
|
-
get body(): string | Buffer | Readable | Generator | AsyncGenerator | undefined;
|
|
569
|
-
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);
|
|
570
686
|
/**
|
|
571
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).
|
|
572
688
|
|
|
@@ -984,25 +1100,27 @@ export default class Options {
|
|
|
984
1100
|
headers: Headers;
|
|
985
1101
|
timeout: Delays;
|
|
986
1102
|
request: RequestFunction | undefined;
|
|
1103
|
+
username: string;
|
|
1104
|
+
password: string;
|
|
987
1105
|
json: Record<string, any> | undefined;
|
|
988
1106
|
retry: Partial<RetryOptions>;
|
|
989
1107
|
agent: Agents;
|
|
990
1108
|
h2session: http2wrapper.ClientHttp2Session | undefined;
|
|
991
1109
|
decompress: boolean;
|
|
992
1110
|
prefixUrl: string | URL;
|
|
993
|
-
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;
|
|
994
1112
|
form: Record<string, any> | undefined;
|
|
995
1113
|
url: string | URL | undefined;
|
|
996
1114
|
cookieJar: PromiseCookieJar | ToughCookieJar | undefined;
|
|
997
1115
|
ignoreInvalidCookies: boolean;
|
|
998
1116
|
searchParams: string | SearchParameters | URLSearchParams | undefined;
|
|
999
1117
|
dnsLookup: {
|
|
1000
|
-
(hostname: string, family: import("cacheable-lookup").IPFamily, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1001
|
-
(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;
|
|
1002
1120
|
(hostname: string, options: import("cacheable-lookup").LookupOptions & {
|
|
1003
1121
|
all: true;
|
|
1004
|
-
}, callback: (error: NodeJS.ErrnoException, result: readonly import("cacheable-lookup").EntryObject[]) => void): void;
|
|
1005
|
-
(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;
|
|
1006
1124
|
} | undefined;
|
|
1007
1125
|
dnsCache: boolean | CacheableLookup | undefined;
|
|
1008
1126
|
context: Record<string, unknown>;
|
|
@@ -1011,8 +1129,6 @@ export default class Options {
|
|
|
1011
1129
|
maxRedirects: number;
|
|
1012
1130
|
cache: string | boolean | CacheableRequest.StorageAdapter | undefined;
|
|
1013
1131
|
throwHttpErrors: boolean;
|
|
1014
|
-
username: string;
|
|
1015
|
-
password: string;
|
|
1016
1132
|
http2: boolean;
|
|
1017
1133
|
allowGetBody: boolean;
|
|
1018
1134
|
methodRewriting: boolean;
|
|
@@ -1051,15 +1167,15 @@ export default class Options {
|
|
|
1051
1167
|
ecdhCurve: string | undefined;
|
|
1052
1168
|
crl: string | Buffer | (string | Buffer)[] | undefined;
|
|
1053
1169
|
lookup: {
|
|
1054
|
-
(hostname: string, family: import("cacheable-lookup").IPFamily, callback: (error: NodeJS.ErrnoException, address: string, family: import("cacheable-lookup").IPFamily) => void): void;
|
|
1055
|
-
(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;
|
|
1056
1172
|
(hostname: string, options: import("cacheable-lookup").LookupOptions & {
|
|
1057
1173
|
all: true;
|
|
1058
|
-
}, callback: (error: NodeJS.ErrnoException, result: readonly import("cacheable-lookup").EntryObject[]) => void): void;
|
|
1059
|
-
(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;
|
|
1060
1176
|
} | undefined;
|
|
1061
1177
|
family: DnsLookupIpVersion;
|
|
1062
|
-
agent: false | Agents |
|
|
1178
|
+
agent: false | Agents | http.Agent | undefined;
|
|
1063
1179
|
setHost: boolean;
|
|
1064
1180
|
method: Method;
|
|
1065
1181
|
maxHeaderSize: number | undefined;
|
|
@@ -1068,6 +1184,7 @@ export default class Options {
|
|
|
1068
1184
|
createConnection: CreateConnectionFunction | undefined;
|
|
1069
1185
|
timeout: number | undefined;
|
|
1070
1186
|
h2session: http2wrapper.ClientHttp2Session | undefined;
|
|
1187
|
+
signal?: AbortSignal | undefined;
|
|
1071
1188
|
protocol?: string | null | undefined;
|
|
1072
1189
|
host?: string | null | undefined;
|
|
1073
1190
|
hostname?: string | null | undefined;
|
|
@@ -1076,7 +1193,7 @@ export default class Options {
|
|
|
1076
1193
|
socketPath?: string | undefined;
|
|
1077
1194
|
path?: string | null | undefined;
|
|
1078
1195
|
auth?: string | null | undefined;
|
|
1079
|
-
_defaultAgent?:
|
|
1196
|
+
_defaultAgent?: http.Agent | undefined;
|
|
1080
1197
|
clientCertEngine?: string | undefined;
|
|
1081
1198
|
privateKeyEngine?: string | undefined;
|
|
1082
1199
|
privateKeyIdentifier?: string | undefined;
|
|
@@ -1090,8 +1207,8 @@ export default class Options {
|
|
|
1090
1207
|
immutableMinTimeToLive?: number | undefined;
|
|
1091
1208
|
ignoreCargoCult?: boolean | undefined;
|
|
1092
1209
|
};
|
|
1093
|
-
getRequestFunction(): RequestFunction | typeof
|
|
1094
|
-
getFallbackRequestFunction(): RequestFunction | typeof
|
|
1210
|
+
getRequestFunction(): RequestFunction | typeof https.request | undefined;
|
|
1211
|
+
getFallbackRequestFunction(): RequestFunction | typeof https.request | undefined;
|
|
1095
1212
|
freeze(): void;
|
|
1096
1213
|
}
|
|
1097
1214
|
export {};
|