got 11.6.0 → 11.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/source/as-promise/index.js +3 -2
- package/dist/source/as-promise/parse-body.js +1 -1
- package/dist/source/core/index.d.ts +6 -15
- package/dist/source/core/index.js +63 -35
- package/dist/source/core/utils/get-body-size.js +3 -0
- package/dist/source/core/utils/url-to-options.js +1 -1
- package/dist/source/create.js +4 -4
- package/package.json +7 -7
- package/readme.md +181 -27
|
@@ -133,9 +133,10 @@ function asPromise(normalizedOptions) {
|
|
|
133
133
|
reject(error);
|
|
134
134
|
};
|
|
135
135
|
request.once('error', onError);
|
|
136
|
+
const previousBody = request.options.body;
|
|
136
137
|
request.once('retry', (newRetryCount, error) => {
|
|
137
|
-
var _a;
|
|
138
|
-
if (is_1.default.nodeStream((
|
|
138
|
+
var _a, _b;
|
|
139
|
+
if (previousBody === ((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.body) && is_1.default.nodeStream((_b = error.request) === null || _b === void 0 ? void 0 : _b.options.body)) {
|
|
139
140
|
onError(error);
|
|
140
141
|
return;
|
|
141
142
|
}
|
|
@@ -11,7 +11,7 @@ const parseBody = (response, responseType, parseJson, encoding) => {
|
|
|
11
11
|
return rawBody.length === 0 ? '' : parseJson(rawBody.toString());
|
|
12
12
|
}
|
|
13
13
|
if (responseType === 'buffer') {
|
|
14
|
-
return
|
|
14
|
+
return rawBody;
|
|
15
15
|
}
|
|
16
16
|
throw new types_1.ParseError({
|
|
17
17
|
message: `Unknown body type '${responseType}'`,
|
|
@@ -41,12 +41,8 @@ export interface Agents {
|
|
|
41
41
|
}
|
|
42
42
|
export declare const withoutBody: ReadonlySet<string>;
|
|
43
43
|
export interface ToughCookieJar {
|
|
44
|
-
getCookieString: ((currentUrl: string, options:
|
|
45
|
-
|
|
46
|
-
}, cb: (err: Error | null, cookies: string) => void) => void) & ((url: string, callback: (error: Error | null, cookieHeader: string) => void) => void);
|
|
47
|
-
setCookie: ((cookieOrString: unknown, currentUrl: string, options: {
|
|
48
|
-
[key: string]: unknown;
|
|
49
|
-
}, cb: (err: Error | null, cookie: unknown) => void) => void) & ((rawCookie: string, url: string, callback: (error: Error | null, result: unknown) => void) => void);
|
|
44
|
+
getCookieString: ((currentUrl: string, options: Record<string, unknown>, cb: (err: Error | null, cookies: string) => void) => void) & ((url: string, callback: (error: Error | null, cookieHeader: string) => void) => void);
|
|
45
|
+
setCookie: ((cookieOrString: unknown, currentUrl: string, options: Record<string, unknown>, cb: (err: Error | null, cookie: unknown) => void) => void) & ((rawCookie: string, url: string, callback: (error: Error | null, result: unknown) => void) => void);
|
|
50
46
|
}
|
|
51
47
|
export interface PromiseCookieJar {
|
|
52
48
|
getCookieString: (url: string) => Promise<string>;
|
|
@@ -352,9 +348,7 @@ interface PlainOptions extends URLOptions {
|
|
|
352
348
|
|
|
353
349
|
__Note #2__: This option is not enumerable and will not be merged with the instance defaults.
|
|
354
350
|
*/
|
|
355
|
-
form?:
|
|
356
|
-
[key: string]: any;
|
|
357
|
-
};
|
|
351
|
+
form?: Record<string, any>;
|
|
358
352
|
/**
|
|
359
353
|
JSON body. If the `Content-Type` header is not set, it will be set to `application/json`.
|
|
360
354
|
|
|
@@ -362,9 +356,7 @@ interface PlainOptions extends URLOptions {
|
|
|
362
356
|
|
|
363
357
|
__Note #2__: This option is not enumerable and will not be merged with the instance defaults.
|
|
364
358
|
*/
|
|
365
|
-
json?:
|
|
366
|
-
[key: string]: any;
|
|
367
|
-
};
|
|
359
|
+
json?: Record<string, any>;
|
|
368
360
|
/**
|
|
369
361
|
The URL to request, as a string, a [`https.request` options object](https://nodejs.org/api/https.html#https_https_request_options_callback), or a [WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url).
|
|
370
362
|
|
|
@@ -415,9 +407,7 @@ interface PlainOptions extends URLOptions {
|
|
|
415
407
|
//=> 'key=a&key=b'
|
|
416
408
|
```
|
|
417
409
|
*/
|
|
418
|
-
searchParams?: string |
|
|
419
|
-
[key: string]: string | number | boolean | null | undefined;
|
|
420
|
-
} | URLSearchParams;
|
|
410
|
+
searchParams?: string | Record<string, string | number | boolean | null | undefined> | URLSearchParams;
|
|
421
411
|
/**
|
|
422
412
|
An instance of [`CacheableLookup`](https://github.com/szmarczak/cacheable-lookup) used for making DNS lookups.
|
|
423
413
|
Useful when making lots of requests to different *public* hostnames.
|
|
@@ -738,6 +728,7 @@ export interface HTTPSOptions {
|
|
|
738
728
|
The passphrase to decrypt the `options.https.key` (if different keys have different passphrases refer to `options.https.key` documentation).
|
|
739
729
|
*/
|
|
740
730
|
passphrase?: SecureContextOptions['passphrase'];
|
|
731
|
+
pfx?: SecureContextOptions['pfx'];
|
|
741
732
|
}
|
|
742
733
|
interface NormalizedPlainOptions extends PlainOptions {
|
|
743
734
|
method: Method;
|
|
@@ -295,18 +295,28 @@ class Request extends stream_1.Duplex {
|
|
|
295
295
|
if (json || body || form) {
|
|
296
296
|
this._lockWrite();
|
|
297
297
|
}
|
|
298
|
-
(
|
|
299
|
-
|
|
298
|
+
if (exports.kIsNormalizedAlready in options) {
|
|
299
|
+
this.options = options;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
300
302
|
try {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
303
|
+
// @ts-expect-error Common TypeScript bug saying that `this.constructor` is not accessible
|
|
304
|
+
this.options = this.constructor.normalizeArguments(url, options, defaults);
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
// TODO: Move this to `_destroy()`
|
|
308
|
+
if (is_1.default.nodeStream(options.body)) {
|
|
309
|
+
options.body.destroy();
|
|
306
310
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
311
|
+
this.destroy(error);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
(async () => {
|
|
316
|
+
var _a;
|
|
317
|
+
try {
|
|
318
|
+
if (this.options.body instanceof fs_1.ReadStream) {
|
|
319
|
+
await waitForOpenFile(this.options.body);
|
|
310
320
|
}
|
|
311
321
|
const { url: normalizedURL } = this.options;
|
|
312
322
|
if (!normalizedURL) {
|
|
@@ -338,10 +348,10 @@ class Request extends stream_1.Duplex {
|
|
|
338
348
|
this.destroy(error);
|
|
339
349
|
}
|
|
340
350
|
}
|
|
341
|
-
})(
|
|
351
|
+
})();
|
|
342
352
|
}
|
|
343
353
|
static normalizeArguments(url, options, defaults) {
|
|
344
|
-
var _a, _b, _c, _d;
|
|
354
|
+
var _a, _b, _c, _d, _e;
|
|
345
355
|
const rawOptions = options;
|
|
346
356
|
if (is_1.default.object(url) && !is_1.default.urlInstance(url)) {
|
|
347
357
|
options = { ...defaults, ...url, ...options };
|
|
@@ -394,6 +404,7 @@ class Request extends stream_1.Duplex {
|
|
|
394
404
|
is_1.assert.any([is_1.default.string, is_1.default.object, is_1.default.array, is_1.default.undefined], options.https.key);
|
|
395
405
|
is_1.assert.any([is_1.default.string, is_1.default.object, is_1.default.array, is_1.default.undefined], options.https.certificate);
|
|
396
406
|
is_1.assert.any([is_1.default.string, is_1.default.undefined], options.https.passphrase);
|
|
407
|
+
is_1.assert.any([is_1.default.string, is_1.default.buffer, is_1.default.array, is_1.default.undefined], options.https.pfx);
|
|
397
408
|
}
|
|
398
409
|
is_1.assert.any([is_1.default.object, is_1.default.undefined], options.cacheOptions);
|
|
399
410
|
// `options.method`
|
|
@@ -453,15 +464,15 @@ class Request extends stream_1.Duplex {
|
|
|
453
464
|
options.username = (_b = options.username) !== null && _b !== void 0 ? _b : '';
|
|
454
465
|
options.password = (_c = options.password) !== null && _c !== void 0 ? _c : '';
|
|
455
466
|
// `options.prefixUrl` & `options.url`
|
|
456
|
-
if (options.prefixUrl) {
|
|
467
|
+
if (is_1.default.undefined(options.prefixUrl)) {
|
|
468
|
+
options.prefixUrl = (_d = defaults === null || defaults === void 0 ? void 0 : defaults.prefixUrl) !== null && _d !== void 0 ? _d : '';
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
457
471
|
options.prefixUrl = options.prefixUrl.toString();
|
|
458
472
|
if (options.prefixUrl !== '' && !options.prefixUrl.endsWith('/')) {
|
|
459
473
|
options.prefixUrl += '/';
|
|
460
474
|
}
|
|
461
475
|
}
|
|
462
|
-
else {
|
|
463
|
-
options.prefixUrl = '';
|
|
464
|
-
}
|
|
465
476
|
if (is_1.default.string(options.url)) {
|
|
466
477
|
if (options.url.startsWith('/')) {
|
|
467
478
|
throw new Error('`input` must not start with a slash when using `prefixUrl`');
|
|
@@ -472,6 +483,9 @@ class Request extends stream_1.Duplex {
|
|
|
472
483
|
options.url = options_to_url_1.default(options.prefixUrl, options);
|
|
473
484
|
}
|
|
474
485
|
if (options.url) {
|
|
486
|
+
if ('port' in options) {
|
|
487
|
+
delete options.port;
|
|
488
|
+
}
|
|
475
489
|
// Make it possible to change `options.prefixUrl`
|
|
476
490
|
let { prefixUrl } = options;
|
|
477
491
|
Object.defineProperty(options, 'prefixUrl', {
|
|
@@ -614,7 +628,7 @@ class Request extends stream_1.Duplex {
|
|
|
614
628
|
if (defaults && !areHooksDefault) {
|
|
615
629
|
for (const event of exports.knownHookEvents) {
|
|
616
630
|
const defaultHooks = defaults.hooks[event];
|
|
617
|
-
if (defaultHooks.length
|
|
631
|
+
if (defaultHooks.length > 0) {
|
|
618
632
|
// See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044
|
|
619
633
|
options.hooks[event] = [
|
|
620
634
|
...defaults.hooks[event],
|
|
@@ -649,6 +663,9 @@ class Request extends stream_1.Duplex {
|
|
|
649
663
|
if ('passphrase' in options) {
|
|
650
664
|
deprecation_warning_1.default('"options.passphrase" was never documented, please use "options.https.passphrase"');
|
|
651
665
|
}
|
|
666
|
+
if ('pfx' in options) {
|
|
667
|
+
deprecation_warning_1.default('"options.pfx" was never documented, please use "options.https.pfx"');
|
|
668
|
+
}
|
|
652
669
|
// Other options
|
|
653
670
|
if ('followRedirects' in options) {
|
|
654
671
|
throw new TypeError('The `followRedirects` option does not exist. Use `followRedirect` instead.');
|
|
@@ -660,7 +677,7 @@ class Request extends stream_1.Duplex {
|
|
|
660
677
|
}
|
|
661
678
|
}
|
|
662
679
|
}
|
|
663
|
-
options.maxRedirects = (
|
|
680
|
+
options.maxRedirects = (_e = options.maxRedirects) !== null && _e !== void 0 ? _e : 0;
|
|
664
681
|
// Set non-enumerable properties
|
|
665
682
|
exports.setNonEnumerableProperties([defaults, rawOptions], options);
|
|
666
683
|
return normalize_arguments_1.default(options, defaults);
|
|
@@ -826,6 +843,8 @@ class Request extends stream_1.Duplex {
|
|
|
826
843
|
if ('form' in options) {
|
|
827
844
|
delete options.form;
|
|
828
845
|
}
|
|
846
|
+
this[kBody] = undefined;
|
|
847
|
+
delete options.headers['content-length'];
|
|
829
848
|
}
|
|
830
849
|
if (this.redirects.length >= options.maxRedirects) {
|
|
831
850
|
this._beforeError(new MaxRedirectsError(this));
|
|
@@ -839,7 +858,7 @@ class Request extends stream_1.Duplex {
|
|
|
839
858
|
const redirectString = redirectUrl.toString();
|
|
840
859
|
decodeURI(redirectString);
|
|
841
860
|
// Redirecting to a different site, clear sensitive data.
|
|
842
|
-
if (redirectUrl.hostname !== url.hostname) {
|
|
861
|
+
if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) {
|
|
843
862
|
if ('host' in options.headers) {
|
|
844
863
|
delete options.headers.host;
|
|
845
864
|
}
|
|
@@ -850,13 +869,14 @@ class Request extends stream_1.Duplex {
|
|
|
850
869
|
delete options.headers.authorization;
|
|
851
870
|
}
|
|
852
871
|
if (options.username || options.password) {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
delete options.username;
|
|
856
|
-
// @ts-expect-error
|
|
857
|
-
delete options.password;
|
|
872
|
+
options.username = '';
|
|
873
|
+
options.password = '';
|
|
858
874
|
}
|
|
859
875
|
}
|
|
876
|
+
else {
|
|
877
|
+
redirectUrl.username = options.username;
|
|
878
|
+
redirectUrl.password = options.password;
|
|
879
|
+
}
|
|
860
880
|
this.redirects.push(redirectString);
|
|
861
881
|
options.url = redirectUrl;
|
|
862
882
|
for (const hook of options.hooks.beforeRedirect) {
|
|
@@ -930,12 +950,7 @@ class Request extends stream_1.Duplex {
|
|
|
930
950
|
request.destroy();
|
|
931
951
|
// Node.js <= 12.18.2 mistakenly emits the response `end` first.
|
|
932
952
|
(_a = request.res) === null || _a === void 0 ? void 0 : _a.removeAllListeners('end');
|
|
933
|
-
|
|
934
|
-
error = new TimeoutError(error, this.timings, this);
|
|
935
|
-
}
|
|
936
|
-
else {
|
|
937
|
-
error = new RequestError(error.message, error, this);
|
|
938
|
-
}
|
|
953
|
+
error = error instanceof timed_out_1.TimeoutError ? new TimeoutError(error, this.timings, this) : new RequestError(error.message, error, this);
|
|
939
954
|
this._beforeError(error);
|
|
940
955
|
});
|
|
941
956
|
this[kUnproxyEvents] = proxy_events_1.default(request, this, proxiedRequestEvents);
|
|
@@ -1023,6 +1038,9 @@ class Request extends stream_1.Duplex {
|
|
|
1023
1038
|
break;
|
|
1024
1039
|
}
|
|
1025
1040
|
}
|
|
1041
|
+
if (options.body && this[kBody] !== options.body) {
|
|
1042
|
+
this[kBody] = options.body;
|
|
1043
|
+
}
|
|
1026
1044
|
const { agent, request, timeout, url } = options;
|
|
1027
1045
|
if (options.dnsCache && !('lookup' in options)) {
|
|
1028
1046
|
options.lookup = options.dnsCache.lookup;
|
|
@@ -1095,6 +1113,9 @@ class Request extends stream_1.Duplex {
|
|
|
1095
1113
|
if (options.https.passphrase) {
|
|
1096
1114
|
requestOptions.passphrase = options.https.passphrase;
|
|
1097
1115
|
}
|
|
1116
|
+
if (options.https.pfx) {
|
|
1117
|
+
requestOptions.pfx = options.https.pfx;
|
|
1118
|
+
}
|
|
1098
1119
|
}
|
|
1099
1120
|
try {
|
|
1100
1121
|
let requestOrResponse = await fn(url, requestOptions);
|
|
@@ -1126,6 +1147,9 @@ class Request extends stream_1.Duplex {
|
|
|
1126
1147
|
if (options.https.passphrase) {
|
|
1127
1148
|
delete requestOptions.passphrase;
|
|
1128
1149
|
}
|
|
1150
|
+
if (options.https.pfx) {
|
|
1151
|
+
delete requestOptions.pfx;
|
|
1152
|
+
}
|
|
1129
1153
|
}
|
|
1130
1154
|
if (isClientRequest(requestOrResponse)) {
|
|
1131
1155
|
this._onRequest(requestOrResponse);
|
|
@@ -1179,9 +1203,9 @@ class Request extends stream_1.Duplex {
|
|
|
1179
1203
|
response.setEncoding(this._readableState.encoding);
|
|
1180
1204
|
try {
|
|
1181
1205
|
response.rawBody = await get_buffer_1.default(response);
|
|
1206
|
+
response.body = response.rawBody.toString();
|
|
1182
1207
|
}
|
|
1183
1208
|
catch (_a) { }
|
|
1184
|
-
response.body = response.rawBody.toString();
|
|
1185
1209
|
}
|
|
1186
1210
|
if (this.listenerCount('retry') !== 0) {
|
|
1187
1211
|
let backoff;
|
|
@@ -1277,6 +1301,10 @@ class Request extends stream_1.Duplex {
|
|
|
1277
1301
|
}
|
|
1278
1302
|
}
|
|
1279
1303
|
_writeRequest(chunk, encoding, callback) {
|
|
1304
|
+
if (this[kRequest].destroyed) {
|
|
1305
|
+
// Probably the `ClientRequest` instance will throw
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1280
1308
|
this._progressCallbacks.push(() => {
|
|
1281
1309
|
this[kUploadedSize] += Buffer.byteLength(chunk, encoding);
|
|
1282
1310
|
const progress = this.uploadProgress;
|
|
@@ -1286,7 +1314,7 @@ class Request extends stream_1.Duplex {
|
|
|
1286
1314
|
});
|
|
1287
1315
|
// TODO: What happens if it's from cache? Then this[kRequest] won't be defined.
|
|
1288
1316
|
this[kRequest].write(chunk, encoding, (error) => {
|
|
1289
|
-
if (!error && this._progressCallbacks.length
|
|
1317
|
+
if (!error && this._progressCallbacks.length > 0) {
|
|
1290
1318
|
this._progressCallbacks.shift()();
|
|
1291
1319
|
}
|
|
1292
1320
|
callback(error);
|
|
@@ -1350,7 +1378,7 @@ class Request extends stream_1.Duplex {
|
|
|
1350
1378
|
*/
|
|
1351
1379
|
get ip() {
|
|
1352
1380
|
var _a;
|
|
1353
|
-
return (_a = this
|
|
1381
|
+
return (_a = this.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress;
|
|
1354
1382
|
}
|
|
1355
1383
|
/**
|
|
1356
1384
|
Indicates whether the request has been aborted or not.
|
|
@@ -1360,8 +1388,8 @@ class Request extends stream_1.Duplex {
|
|
|
1360
1388
|
return ((_b = (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.destroyed) !== null && _b !== void 0 ? _b : this.destroyed) && !((_c = this[kOriginalResponse]) === null || _c === void 0 ? void 0 : _c.complete);
|
|
1361
1389
|
}
|
|
1362
1390
|
get socket() {
|
|
1363
|
-
var _a;
|
|
1364
|
-
return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket;
|
|
1391
|
+
var _a, _b;
|
|
1392
|
+
return (_b = (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket) !== null && _b !== void 0 ? _b : undefined;
|
|
1365
1393
|
}
|
|
1366
1394
|
/**
|
|
1367
1395
|
Progress event for downloading (receiving a response).
|
|
@@ -14,7 +14,7 @@ exports.default = (url) => {
|
|
|
14
14
|
href: url.href,
|
|
15
15
|
path: `${url.pathname || ''}${url.search || ''}`
|
|
16
16
|
};
|
|
17
|
-
if (is_1.default.string(url.port) && url.port.length
|
|
17
|
+
if (is_1.default.string(url.port) && url.port.length > 0) {
|
|
18
18
|
options.port = Number(url.port);
|
|
19
19
|
}
|
|
20
20
|
if (url.username || url.password) {
|
package/dist/source/create.js
CHANGED
|
@@ -82,7 +82,7 @@ const create = (defaults) => {
|
|
|
82
82
|
return result;
|
|
83
83
|
}));
|
|
84
84
|
// Got interface
|
|
85
|
-
const got = ((url, options, _defaults) => {
|
|
85
|
+
const got = ((url, options = {}, _defaults) => {
|
|
86
86
|
var _a, _b;
|
|
87
87
|
let iteration = 0;
|
|
88
88
|
const iterateHandlers = (newOptions) => {
|
|
@@ -103,7 +103,7 @@ const create = (defaults) => {
|
|
|
103
103
|
let initHookError;
|
|
104
104
|
try {
|
|
105
105
|
callInitHooks(defaults.options.hooks.init, options);
|
|
106
|
-
callInitHooks((_a = options
|
|
106
|
+
callInitHooks((_a = options.hooks) === null || _a === void 0 ? void 0 : _a.init, options);
|
|
107
107
|
}
|
|
108
108
|
catch (error) {
|
|
109
109
|
initHookError = error;
|
|
@@ -117,11 +117,11 @@ const create = (defaults) => {
|
|
|
117
117
|
return iterateHandlers(normalizedOptions);
|
|
118
118
|
}
|
|
119
119
|
catch (error) {
|
|
120
|
-
if (options
|
|
120
|
+
if (options.isStream) {
|
|
121
121
|
throw error;
|
|
122
122
|
}
|
|
123
123
|
else {
|
|
124
|
-
return create_rejection_1.default(error, defaults.options.hooks.beforeError, (_b = options
|
|
124
|
+
return create_rejection_1.default(error, defaults.options.hooks.beforeError, (_b = options.hooks) === null || _b === void 0 ? void 0 : _b.beforeError);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "got",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.8.0",
|
|
4
4
|
"description": "Human-friendly and powerful HTTP request library for Node.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/got",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"ky"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@sindresorhus/is": "^
|
|
46
|
+
"@sindresorhus/is": "^4.0.0",
|
|
47
47
|
"@szmarczak/http-timer": "^4.0.5",
|
|
48
48
|
"@types/cacheable-request": "^6.0.1",
|
|
49
49
|
"@types/responselike": "^1.0.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@sinonjs/fake-timers": "^6.0.1",
|
|
62
62
|
"@types/benchmark": "^1.0.33",
|
|
63
63
|
"@types/express": "^4.17.7",
|
|
64
|
-
"@types/node": "^14.
|
|
64
|
+
"@types/node": "^14.14.0",
|
|
65
65
|
"@types/node-fetch": "^2.5.7",
|
|
66
66
|
"@types/pem": "^1.9.5",
|
|
67
67
|
"@types/pify": "^3.0.2",
|
|
@@ -87,11 +87,11 @@
|
|
|
87
87
|
"pify": "^5.0.0",
|
|
88
88
|
"sinon": "^9.0.3",
|
|
89
89
|
"slow-stream": "0.0.4",
|
|
90
|
-
"tempy": "^0.
|
|
90
|
+
"tempy": "^1.0.0",
|
|
91
91
|
"to-readable-stream": "^2.1.0",
|
|
92
92
|
"tough-cookie": "^4.0.0",
|
|
93
|
-
"typescript": "
|
|
94
|
-
"xo": "^0.
|
|
93
|
+
"typescript": "4.0.3",
|
|
94
|
+
"xo": "^0.34.1"
|
|
95
95
|
},
|
|
96
96
|
"types": "dist/source",
|
|
97
97
|
"sideEffects": false,
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"node/prefer-global/url": "off",
|
|
124
124
|
"node/prefer-global/url-search-params": "off",
|
|
125
125
|
"import/no-anonymous-default-export": "off",
|
|
126
|
-
"@typescript-eslint/no-
|
|
126
|
+
"@typescript-eslint/no-implicit-any-catch": "off"
|
|
127
127
|
}
|
|
128
128
|
},
|
|
129
129
|
"runkitExampleFilename": "./documentation/examples/runkit-example.js"
|
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>
|
|
@@ -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
|
|
|
@@ -105,16 +107,16 @@ const got = require('got');
|
|
|
105
107
|
const pipeline = promisify(stream.pipeline);
|
|
106
108
|
|
|
107
109
|
(async () => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
110
|
+
await pipeline(
|
|
111
|
+
got.stream('https://sindresorhus.com'),
|
|
112
|
+
fs.createWriteStream('index.html')
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// For POST, PUT, PATCH, and DELETE methods, `got.stream` returns a `stream.Writable`.
|
|
116
|
+
await pipeline(
|
|
117
|
+
fs.createReadStream('index.html'),
|
|
118
|
+
got.stream.post('https://sindresorhus.com')
|
|
119
|
+
);
|
|
118
120
|
})();
|
|
119
121
|
```
|
|
120
122
|
|
|
@@ -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
|
|
|
@@ -304,7 +306,7 @@ Example:
|
|
|
304
306
|
const bufferPromise = responsePromise.buffer();
|
|
305
307
|
const jsonPromise = responsePromise.json();
|
|
306
308
|
|
|
307
|
-
const [response, buffer, json] = Promise.all([responsePromise, bufferPromise, jsonPromise]);
|
|
309
|
+
const [response, buffer, json] = await Promise.all([responsePromise, bufferPromise, jsonPromise]);
|
|
308
310
|
// `response` is an instance of Got Response
|
|
309
311
|
// `buffer` is an instance of Buffer
|
|
310
312
|
// `json` is an object
|
|
@@ -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`\
|
|
@@ -517,6 +521,8 @@ Delays between retries counts with function `1000 * Math.pow(2, retry - 1) + Mat
|
|
|
517
521
|
|
|
518
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).
|
|
519
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
|
+
|
|
520
526
|
By default, it retries *only* on the specified methods, status codes, and on these network errors:
|
|
521
527
|
- `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached.
|
|
522
528
|
- `ECONNRESET`: Connection was forcibly closed by a peer.
|
|
@@ -649,6 +655,15 @@ await got('https://api6.ipify.org', {
|
|
|
649
655
|
});
|
|
650
656
|
```
|
|
651
657
|
|
|
658
|
+
###### lookup
|
|
659
|
+
|
|
660
|
+
Type: `Function`\
|
|
661
|
+
Default: [`dns.lookup`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback)
|
|
662
|
+
|
|
663
|
+
Custom DNS resolution logic.
|
|
664
|
+
|
|
665
|
+
The function signature is the same as [`dns.lookup`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
|
|
666
|
+
|
|
652
667
|
###### request
|
|
653
668
|
|
|
654
669
|
Type: `Function`\
|
|
@@ -724,7 +739,7 @@ Called with plain [request options](#options), right before their normalization.
|
|
|
724
739
|
See the [Request migration guide](documentation/migration-guides.md#breaking-changes) for an example.
|
|
725
740
|
|
|
726
741
|
**Note #1:** This hook must be synchronous!\
|
|
727
|
-
**Note #2:** Errors in this hook will be converted into an instances of [`RequestError`](#
|
|
742
|
+
**Note #2:** Errors in this hook will be converted into an instances of [`RequestError`](#gotrequesterror).\
|
|
728
743
|
**Note #3:** The options object may not have a `url` property. To modify it, use a `beforeRequest` hook instead.
|
|
729
744
|
|
|
730
745
|
###### hooks.beforeRequest
|
|
@@ -734,6 +749,24 @@ Default: `[]`
|
|
|
734
749
|
|
|
735
750
|
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.
|
|
736
751
|
|
|
752
|
+
**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:
|
|
753
|
+
|
|
754
|
+
```js
|
|
755
|
+
const got = require('got');
|
|
756
|
+
|
|
757
|
+
got.post({
|
|
758
|
+
json: {payload: 'old'},
|
|
759
|
+
hooks: {
|
|
760
|
+
beforeRequest: [
|
|
761
|
+
options => {
|
|
762
|
+
options.body = JSON.stringify({payload: 'new'});
|
|
763
|
+
options.headers['content-length'] = options.body.length.toString();
|
|
764
|
+
}
|
|
765
|
+
]
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
```
|
|
769
|
+
|
|
737
770
|
**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.
|
|
738
771
|
|
|
739
772
|
###### hooks.beforeRedirect
|
|
@@ -849,12 +882,12 @@ got('https://api.github.com/some-endpoint', {
|
|
|
849
882
|
beforeError: [
|
|
850
883
|
error => {
|
|
851
884
|
const {response} = error;
|
|
852
|
-
|
|
885
|
+
if (response && response.body) {
|
|
853
886
|
error.name = 'GitHubError';
|
|
854
887
|
error.message = `${response.body.message} (${response.statusCode})`;
|
|
855
888
|
}
|
|
856
889
|
|
|
857
|
-
|
|
890
|
+
return error;
|
|
858
891
|
}
|
|
859
892
|
]
|
|
860
893
|
}
|
|
@@ -1018,7 +1051,24 @@ Type: `string`
|
|
|
1018
1051
|
|
|
1019
1052
|
The passphrase to decrypt the `options.https.key` (if different keys have different passphrases refer to `options.https.key` documentation).
|
|
1020
1053
|
|
|
1021
|
-
#####
|
|
1054
|
+
##### https.pfx
|
|
1055
|
+
|
|
1056
|
+
Type: `string | Buffer | Array<string | Buffer | object>`
|
|
1057
|
+
|
|
1058
|
+
[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.
|
|
1059
|
+
|
|
1060
|
+
Multiple PFX's can be be provided as an array of unencrypted buffers or an array of objects like:
|
|
1061
|
+
|
|
1062
|
+
```ts
|
|
1063
|
+
{
|
|
1064
|
+
buffer: string | Buffer,
|
|
1065
|
+
passphrase?: string
|
|
1066
|
+
}
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
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.
|
|
1070
|
+
|
|
1071
|
+
##### Examples for `https.key`, `https.certificate`, `https.passphrase`, and `https.pfx`
|
|
1022
1072
|
|
|
1023
1073
|
```js
|
|
1024
1074
|
// Single key with certificate
|
|
@@ -1065,6 +1115,45 @@ got('https://example.com', {
|
|
|
1065
1115
|
]
|
|
1066
1116
|
}
|
|
1067
1117
|
});
|
|
1118
|
+
|
|
1119
|
+
// Single encrypted PFX with passphrase
|
|
1120
|
+
got('https://example.com', {
|
|
1121
|
+
https: {
|
|
1122
|
+
pfx: fs.readFileSync('./fake.pfx'),
|
|
1123
|
+
passphrase: 'passphrase'
|
|
1124
|
+
}
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
// Multiple encrypted PFX's with different passphrases
|
|
1128
|
+
got('https://example.com', {
|
|
1129
|
+
https: {
|
|
1130
|
+
pfx: [
|
|
1131
|
+
{
|
|
1132
|
+
buffer: fs.readFileSync('./key1.pfx'),
|
|
1133
|
+
passphrase: 'passphrase1'
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
buffer: fs.readFileSync('./key2.pfx'),
|
|
1137
|
+
passphrase: 'passphrase2'
|
|
1138
|
+
}
|
|
1139
|
+
]
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1143
|
+
// Multiple encrypted PFX's with single passphrase
|
|
1144
|
+
got('https://example.com', {
|
|
1145
|
+
https: {
|
|
1146
|
+
passphrase: 'passphrase',
|
|
1147
|
+
pfx: [
|
|
1148
|
+
{
|
|
1149
|
+
buffer: fs.readFileSync('./key1.pfx')
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
buffer: fs.readFileSync('./key2.pfx')
|
|
1153
|
+
}
|
|
1154
|
+
]
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1068
1157
|
```
|
|
1069
1158
|
|
|
1070
1159
|
##### https.rejectUnauthorized
|
|
@@ -1318,7 +1407,7 @@ The same as `response.socket`.
|
|
|
1318
1407
|
|
|
1319
1408
|
##### .on('error', error)
|
|
1320
1409
|
|
|
1321
|
-
The emitted `error` is an instance of [`RequestError`](#
|
|
1410
|
+
The emitted `error` is an instance of [`RequestError`](#gotrequesterror).
|
|
1322
1411
|
|
|
1323
1412
|
#### Pagination
|
|
1324
1413
|
|
|
@@ -2192,12 +2281,12 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2192
2281
|
[ab]: https://badgen.net/travis/axios/axios?label
|
|
2193
2282
|
[sb]: https://badgen.net/travis/visionmedia/superagent?label
|
|
2194
2283
|
|
|
2195
|
-
[g5]: https://travis-ci.
|
|
2196
|
-
[k5]: https://travis-ci.
|
|
2197
|
-
[r5]: https://travis-ci.org/request/request
|
|
2198
|
-
[n5]: https://travis-ci.org/bitinn/node-fetch
|
|
2199
|
-
[a5]: https://travis-ci.org/axios/axios
|
|
2200
|
-
[s5]: https://travis-ci.org/visionmedia/superagent
|
|
2284
|
+
[g5]: https://travis-ci.com/github/sindresorhus/got
|
|
2285
|
+
[k5]: https://travis-ci.com/github/sindresorhus/ky
|
|
2286
|
+
[r5]: https://travis-ci.org/github/request/request
|
|
2287
|
+
[n5]: https://travis-ci.org/github/bitinn/node-fetch
|
|
2288
|
+
[a5]: https://travis-ci.org/github/axios/axios
|
|
2289
|
+
[s5]: https://travis-ci.org/github/visionmedia/superagent
|
|
2201
2290
|
|
|
2202
2291
|
<!-- BUGS -->
|
|
2203
2292
|
[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
|
|
@@ -2304,9 +2393,9 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2304
2393
|
|
|
2305
2394
|
## Maintainers
|
|
2306
2395
|
|
|
2307
|
-
[](https://sindresorhus.com) | [](https://github.com/szmarczak)
|
|
2308
|
-
|
|
2309
|
-
[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak)
|
|
2396
|
+
[](https://sindresorhus.com) | [](https://github.com/szmarczak) | [](https://github.com/Giotino)
|
|
2397
|
+
---|---|---
|
|
2398
|
+
[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak) | [Giovanni Minotti](https://github.com/Giotino)
|
|
2310
2399
|
|
|
2311
2400
|
###### Former
|
|
2312
2401
|
|
|
@@ -2315,6 +2404,71 @@ The Electron `net` module is not consistent with the Node.js `http` module. See
|
|
|
2315
2404
|
- [Brandon Smith](https://github.com/brandon93s)
|
|
2316
2405
|
- [Luke Childs](https://github.com/lukechilds)
|
|
2317
2406
|
|
|
2407
|
+
<a name="widely-used"></a>
|
|
2408
|
+
## These amazing companies are using Got
|
|
2409
|
+
|
|
2410
|
+
<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>
|
|
2411
|
+
|
|
2412
|
+
<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>
|
|
2413
|
+
|
|
2414
|
+
<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>
|
|
2415
|
+
|
|
2416
|
+
<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>
|
|
2417
|
+
|
|
2418
|
+
<a href="http://karaokes.moe"><img width="140" valign="middle" src="https://camo.githubusercontent.com/6860e5fa4684c14d8e1aa65df0aba4e6808ea1a9/687474703a2f2f6b6172616f6b65732e6d6f652f6173736574732f696d616765732f696e6465782e706e67"></a>
|
|
2419
|
+
|
|
2420
|
+
<a href="https://github.com/renovatebot/renovate"><img width="150" valign="middle" src="https://camo.githubusercontent.com/206d470ac709b9a702a97b0c08d6f389a086793d/68747470733a2f2f72656e6f76617465626f742e636f6d2f696d616765732f6c6f676f2e737667"></a>
|
|
2421
|
+
|
|
2422
|
+
<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>
|
|
2423
|
+
|
|
2424
|
+
<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>
|
|
2425
|
+
|
|
2426
|
+
<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>
|
|
2427
|
+
|
|
2428
|
+
<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>
|
|
2429
|
+
|
|
2430
|
+
<br>
|
|
2431
|
+
|
|
2432
|
+
> 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.
|
|
2433
|
+
>
|
|
2434
|
+
> — <a href="https://github.com/vadimdemedes">Vadim Demedes</a>
|
|
2435
|
+
|
|
2436
|
+
> 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.
|
|
2437
|
+
>
|
|
2438
|
+
> — <a href="https://github.com/mojavelinux">Dan Allen</a>
|
|
2439
|
+
|
|
2440
|
+
> 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.
|
|
2441
|
+
>
|
|
2442
|
+
> — <a href="https://github.com/danielkalen">Daniel Kalen</a>
|
|
2443
|
+
|
|
2444
|
+
> 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.
|
|
2445
|
+
>
|
|
2446
|
+
> — <a href="https://github.com/yamalight">Tim Ermilov</a>
|
|
2447
|
+
|
|
2448
|
+
> Karaoke Mugen uses Got to fetch content updates from its online server.
|
|
2449
|
+
>
|
|
2450
|
+
> — <a href="https://github.com/AxelTerizaki">Axel Terizaki</a>
|
|
2451
|
+
|
|
2452
|
+
> 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.
|
|
2453
|
+
>
|
|
2454
|
+
> — <a href="https://github.com/rarkins">Rhys Arkins</a>
|
|
2455
|
+
|
|
2456
|
+
> Resistbot uses Got to communicate from the API frontend where all correspondence ingresses to the officials lookup database in back.
|
|
2457
|
+
>
|
|
2458
|
+
> — <a href="https://github.com/chris-erickson">Chris Erickson</a>
|
|
2459
|
+
|
|
2460
|
+
> Natural Cycles is using Got to communicate with all kinds of 3rd-party REST APIs (over 9000!).
|
|
2461
|
+
>
|
|
2462
|
+
> — <a href="https://github.com/kirillgroshkov">Kirill Groshkov</a>
|
|
2463
|
+
|
|
2464
|
+
> 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.
|
|
2465
|
+
>
|
|
2466
|
+
> — <a href="https://github.com/Kikobeats">Kiko Beats</a>
|
|
2467
|
+
|
|
2468
|
+
> We’re using Got at Radity. Thanks for such an amazing work!
|
|
2469
|
+
>
|
|
2470
|
+
> — <a href="https://github.com/MirzayevFarid">Mirzayev Farid</a>
|
|
2471
|
+
|
|
2318
2472
|
## For enterprise
|
|
2319
2473
|
|
|
2320
2474
|
Available as part of the Tidelift Subscription.
|