got 11.1.3 → 11.1.4

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.
@@ -1,3 +1,4 @@
1
1
  import { RetryFunction } from './types';
2
- declare const calculateRetryDelay: RetryFunction;
2
+ declare type Returns<T extends (...args: any) => unknown, V> = (...args: Parameters<T>) => V;
3
+ declare const calculateRetryDelay: Returns<RetryFunction, number>;
3
4
  export default calculateRetryDelay;
@@ -39,6 +39,11 @@ class PromisableRequest extends core_1.default {
39
39
  is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.resolveBodyOnly);
40
40
  is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.methodRewriting);
41
41
  is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.isStream);
42
+ is_1.assert.any([is_1.default.string, is_1.default.undefined], options.responseType);
43
+ // `options.responseType`
44
+ if (options.responseType === undefined) {
45
+ options.responseType = 'text';
46
+ }
42
47
  // `options.retry`
43
48
  const { retry } = options;
44
49
  if (defaults) {
@@ -51,7 +51,7 @@ function asPromise(options) {
51
51
  _reject(error);
52
52
  };
53
53
  globalRequest = request;
54
- request.once('response', async (response) => {
54
+ const onResponse = async (response) => {
55
55
  response.retryCount = retryCount;
56
56
  if (response.request.aborted) {
57
57
  // Canceled while downloading - will throw a `CancelError` or `TimeoutError` error
@@ -126,8 +126,9 @@ function asPromise(options) {
126
126
  }
127
127
  globalResponse = response;
128
128
  resolve(options.resolveBodyOnly ? response.body : response);
129
- });
130
- request.once('error', (error) => {
129
+ };
130
+ request.once('response', onResponse);
131
+ request.once('error', async (error) => {
131
132
  if (promise.isCanceled) {
132
133
  return;
133
134
  }
@@ -135,10 +136,11 @@ function asPromise(options) {
135
136
  reject(error);
136
137
  return;
137
138
  }
139
+ request.off('response', onResponse);
138
140
  let backoff;
139
141
  retryCount++;
140
142
  try {
141
- backoff = options.retry.calculateDelay({
143
+ backoff = await options.retry.calculateDelay({
142
144
  attemptCount: retryCount,
143
145
  retryOptions: options.retry,
144
146
  error,
@@ -181,7 +183,8 @@ function asPromise(options) {
181
183
  // The retry has not been made
182
184
  retryCount--;
183
185
  if (error instanceof types_1.HTTPError) {
184
- // It will be handled by the `response` event
186
+ // The error will be handled by the `response` event
187
+ onResponse(request._response);
185
188
  return;
186
189
  }
187
190
  // Don't emit the `response` event
@@ -13,7 +13,7 @@ export interface RetryObject {
13
13
  error: TimeoutError | RequestError;
14
14
  computedValue: number;
15
15
  }
16
- export declare type RetryFunction = (retryObject: RetryObject) => number;
16
+ export declare type RetryFunction = (retryObject: RetryObject) => number | Promise<number>;
17
17
  export interface RequiredRetryOptions {
18
18
  limit: number;
19
19
  methods: Method[];
@@ -4,7 +4,7 @@ import { URL, URLSearchParams } from 'url';
4
4
  import { Socket } from 'net';
5
5
  import { SecureContextOptions } from 'tls';
6
6
  import http = require('http');
7
- import { ClientRequest, RequestOptions, IncomingMessage, ServerResponse, request as httpRequest } from 'http';
7
+ import { ClientRequest, RequestOptions, ServerResponse, request as httpRequest } from 'http';
8
8
  import https = require('https');
9
9
  import { Timings, IncomingMessageWithTimings } from '@szmarczak/http-timer';
10
10
  import CacheableLookup from 'cacheable-lookup';
@@ -65,7 +65,7 @@ export interface Hooks {
65
65
  }
66
66
  export declare type HookEvent = 'init' | 'beforeRequest' | 'beforeRedirect' | 'beforeError';
67
67
  export declare const knownHookEvents: HookEvent[];
68
- declare type AcceptableResponse = IncomingMessage | ResponseLike;
68
+ declare type AcceptableResponse = IncomingMessageWithTimings | ResponseLike;
69
69
  declare type AcceptableRequestResult = AcceptableResponse | ClientRequest | Promise<AcceptableResponse | ClientRequest> | undefined;
70
70
  export declare type RequestFunction = (url: URL, options: RequestOptions, callback?: (response: AcceptableResponse) => void) => AcceptableRequestResult;
71
71
  export declare type Headers = Record<string, string | string[] | undefined>;
@@ -249,8 +249,8 @@ export default class Request extends Duplex implements RequestEvents<Request> {
249
249
  [kStartedReading]?: boolean;
250
250
  [kCancelTimeouts]?: () => void;
251
251
  [kResponseSize]?: number;
252
- [kResponse]?: IncomingMessage;
253
- [kOriginalResponse]?: IncomingMessage;
252
+ [kResponse]?: IncomingMessageWithTimings;
253
+ [kOriginalResponse]?: IncomingMessageWithTimings;
254
254
  [kRequest]?: ClientRequest;
255
255
  _noPipe?: boolean;
256
256
  _progressCallbacks: Array<() => void>;
@@ -263,7 +263,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
263
263
  _lockWrite(): void;
264
264
  _unlockWrite(): void;
265
265
  _finalizeBody(): Promise<void>;
266
- _onResponse(response: IncomingMessage): Promise<void>;
266
+ _onResponse(response: IncomingMessageWithTimings): Promise<void>;
267
267
  _onRequest(request: ClientRequest): void;
268
268
  _createCacheableRequest(url: URL, options: RequestOptions): Promise<ClientRequest | ResponseLike>;
269
269
  _makeRequest(): Promise<void>;
@@ -280,6 +280,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
280
280
  get uploadProgress(): Progress;
281
281
  get timings(): Timings | undefined;
282
282
  get isFromCache(): boolean | undefined;
283
+ get _response(): Response | undefined;
283
284
  pipe<T extends NodeJS.WritableStream>(destination: T, options?: {
284
285
  end?: boolean;
285
286
  }): T;
@@ -8,9 +8,9 @@ const http = require("http");
8
8
  const http_1 = require("http");
9
9
  const https = require("https");
10
10
  const http_timer_1 = require("@szmarczak/http-timer");
11
- const decompressResponse = require("decompress-response");
12
11
  const cacheable_lookup_1 = require("cacheable-lookup");
13
12
  const CacheableRequest = require("cacheable-request");
13
+ const decompressResponse = require("decompress-response");
14
14
  // @ts-ignore Missing types
15
15
  const http2wrapper = require("http2-wrapper");
16
16
  const lowercaseKeys = require("lowercase-keys");
@@ -329,6 +329,7 @@ class Request extends stream_1.Duplex {
329
329
  is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.http2);
330
330
  is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.allowGetBody);
331
331
  is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.rejectUnauthorized);
332
+ is_1.assert.any([is_1.default.string, is_1.default.undefined], options.localAddress);
332
333
  // `options.method`
333
334
  if (is_1.default.string(options.method)) {
334
335
  options.method = options.method.toUpperCase();
@@ -414,12 +415,6 @@ class Request extends stream_1.Duplex {
414
415
  if (options.searchParams) {
415
416
  options.url.search = options.searchParams.toString();
416
417
  }
417
- // Trigger search params normalization
418
- if (options.url.search) {
419
- const triggerSearchParameters = '_GOT_INTERNAL_TRIGGER_NORMALIZATION';
420
- options.url.searchParams.append(triggerSearchParameters, '');
421
- options.url.searchParams.delete(triggerSearchParameters);
422
- }
423
418
  // Protocol check
424
419
  if (protocol !== 'http:' && protocol !== 'https:') {
425
420
  throw new UnsupportedProtocolError(options);
@@ -466,7 +461,7 @@ class Request extends stream_1.Duplex {
466
461
  if (options.dnsCache === true) {
467
462
  options.dnsCache = new cacheable_lookup_1.default();
468
463
  }
469
- else if (!is_1.default.undefined(options.dnsCache) && !(options.dnsCache instanceof cacheable_lookup_1.default)) {
464
+ else if (!is_1.default.undefined(options.dnsCache) && !options.dnsCache.lookup) {
470
465
  throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${is_1.default(options.dnsCache)}`);
471
466
  }
472
467
  // `options.timeout`
@@ -699,8 +694,9 @@ class Request extends stream_1.Duplex {
699
694
  return;
700
695
  }
701
696
  try {
702
- // Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604
697
+ // Do not remove. See https://github.com/sindresorhus/got/pull/214
703
698
  const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
699
+ // Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604
704
700
  const redirectUrl = new url_1.URL(redirectBuffer, url);
705
701
  const redirectString = redirectUrl.toString();
706
702
  decodeURI(redirectString);
@@ -832,6 +828,8 @@ class Request extends stream_1.Duplex {
832
828
  const cacheRequest = cacheableStore.get(options.cache)(options, response => {
833
829
  const typedResponse = response;
834
830
  const { req } = typedResponse;
831
+ // TODO: Fix `cacheable-response`
832
+ typedResponse._readableState.autoDestroy = false;
835
833
  if (req) {
836
834
  req.emit('cacheableResponse', typedResponse);
837
835
  }
@@ -1030,6 +1028,10 @@ class Request extends stream_1.Duplex {
1030
1028
  callback();
1031
1029
  return;
1032
1030
  }
1031
+ if (this[kRequest].destroyed) {
1032
+ callback();
1033
+ return;
1034
+ }
1033
1035
  this[kRequest].end((error) => {
1034
1036
  if (!error) {
1035
1037
  this[kBodySize] = this[kUploadedSize];
@@ -1114,6 +1116,9 @@ class Request extends stream_1.Duplex {
1114
1116
  get isFromCache() {
1115
1117
  return this[kIsFromCache];
1116
1118
  }
1119
+ get _response() {
1120
+ return this[kResponse];
1121
+ }
1117
1122
  pipe(destination, options) {
1118
1123
  if (this[kStartedReading]) {
1119
1124
  throw new Error('Failed to pipe. The response has been emitted already.');
@@ -60,6 +60,7 @@ const create = (defaults) => {
60
60
  }
61
61
  return result;
62
62
  }));
63
+ // Got interface
63
64
  const got = ((url, options) => {
64
65
  var _a, _b;
65
66
  let iteration = 0;
@@ -128,7 +129,8 @@ const create = (defaults) => {
128
129
  mutableDefaults: Boolean(isMutableDefaults)
129
130
  });
130
131
  };
131
- got.paginate = (async function* (url, options) {
132
+ // Pagination
133
+ const paginateEach = (async function* (url, options) {
132
134
  let normalizedOptions = normalizeArguments(url, options, defaults.options);
133
135
  normalizedOptions.resolveBodyOnly = false;
134
136
  const pagination = normalizedOptions.pagination;
@@ -173,6 +175,9 @@ const create = (defaults) => {
173
175
  numberOfRequests++;
174
176
  }
175
177
  });
178
+ got.paginate = ((url, options) => {
179
+ return paginateEach(url, options);
180
+ });
176
181
  got.paginate.all = (async (url, options) => {
177
182
  const results = [];
178
183
  for await (const item of got.paginate(url, options)) {
@@ -180,7 +185,11 @@ const create = (defaults) => {
180
185
  }
181
186
  return results;
182
187
  });
188
+ // For those who like very descriptive names
189
+ got.paginate.each = paginateEach;
190
+ // Stream API
183
191
  got.stream = ((url, options) => got(url, { ...options, isStream: true }));
192
+ // Shortcuts
184
193
  for (const method of aliases) {
185
194
  got[method] = ((url, options) => got(url, { ...options, method }));
186
195
  got.stream[method] = ((url, options) => {
@@ -42,8 +42,10 @@ declare type ResponseBodyOnly = {
42
42
  export declare type OptionsWithPagination<T = unknown, R = unknown> = Merge<Options, PaginationOptions<T, R>>;
43
43
  export interface GotPaginate {
44
44
  <T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>): AsyncIterableIterator<T>;
45
- all<T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>): Promise<T[]>;
46
45
  <T, R = unknown>(options?: OptionsWithPagination<T, R>): AsyncIterableIterator<T>;
46
+ each<T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>): AsyncIterableIterator<T>;
47
+ each<T, R = unknown>(options?: OptionsWithPagination<T, R>): AsyncIterableIterator<T>;
48
+ all<T, R = unknown>(url: string | URL, options?: OptionsWithPagination<T, R>): Promise<T[]>;
47
49
  all<T, R = unknown>(options?: OptionsWithPagination<T, R>): Promise<T[]>;
48
50
  }
49
51
  export interface GotRequestFunction {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "got",
3
- "version": "11.1.3",
3
+ "version": "11.1.4",
4
4
  "description": "Human-friendly and powerful HTTP request library for Node.js",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/got",
@@ -47,9 +47,9 @@
47
47
  "@szmarczak/http-timer": "^4.0.5",
48
48
  "@types/cacheable-request": "^6.0.1",
49
49
  "@types/responselike": "^1.0.0",
50
- "cacheable-lookup": "^4.3.0",
50
+ "cacheable-lookup": "^5.0.3",
51
51
  "cacheable-request": "^7.0.1",
52
- "decompress-response": "^5.0.0",
52
+ "decompress-response": "^6.0.0",
53
53
  "get-stream": "^5.1.0",
54
54
  "http2-wrapper": "^1.0.0-beta.4.5",
55
55
  "lowercase-keys": "^2.0.0",
@@ -59,9 +59,9 @@
59
59
  "devDependencies": {
60
60
  "@ava/typescript": "^1.1.1",
61
61
  "@sindresorhus/tsconfig": "^0.7.0",
62
+ "@sinonjs/fake-timers": "^6.0.1",
62
63
  "@types/benchmark": "^1.0.31",
63
64
  "@types/express": "^4.17.6",
64
- "@types/lolex": "^5.1.0",
65
65
  "@types/node": "^13.13.4",
66
66
  "@types/node-fetch": "^2.5.5",
67
67
  "@types/request": "^2.48.4",
@@ -76,7 +76,6 @@
76
76
  "delay": "^4.3.0",
77
77
  "express": "^4.17.1",
78
78
  "form-data": "^3.0.0",
79
- "lolex": "^6.0.0",
80
79
  "nock": "^12.0.0",
81
80
  "node-fetch": "^2.6.0",
82
81
  "np": "^6.0.0",
@@ -125,5 +124,6 @@
125
124
  "@typescript-eslint/method-signature-style": "off",
126
125
  "unicorn/no-fn-reference-in-iterator": "off"
127
126
  }
128
- }
127
+ },
128
+ "runkitExampleFilename": "./documentation/examples/runkit-example.js"
129
129
  }
package/readme.md CHANGED
@@ -139,6 +139,16 @@ Properties from `options` will override properties in the parsed `url`.
139
139
 
140
140
  If no protocol is specified, it will throw a `TypeError`.
141
141
 
142
+ **Note:** The query string is **not** parsed as search params. Example:
143
+
144
+ ```
145
+ got('https://example.com/?query=a b'); //=> https://example.com/?query=a%20b
146
+ got('https://example.com/', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b
147
+
148
+ // The query string is overridden by `searchParams`
149
+ got('https://example.com/?query=a b', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b
150
+ ```
151
+
142
152
  ##### options
143
153
 
144
154
  Type: `object`
@@ -402,7 +412,7 @@ This also accepts an `object` with the following fields to constrain the duratio
402
412
  Type: `number | object`\
403
413
  Default:
404
414
  - limit: `2`
405
- - calculateDelay: `({attemptCount, retryOptions, error, computedValue}) => computedValue`
415
+ - calculateDelay: `({attemptCount, retryOptions, error, computedValue}) => computedValue | Promise<computedValue>`
406
416
  - methods: `GET` `PUT` `HEAD` `DELETE` `OPTIONS` `TRACE`
407
417
  - statusCodes: [`408`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) [`413`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) [`429`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) [`500`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) [`502`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) [`503`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) [`504`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504) [`521`](https://support.cloudflare.com/hc/en-us/articles/115003011431#521error) [`522`](https://support.cloudflare.com/hc/en-us/articles/115003011431#522error) [`524`](https://support.cloudflare.com/hc/en-us/articles/115003011431#524error)
408
418
  - maxRetryAfter: `undefined`
@@ -417,7 +427,7 @@ If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ret
417
427
 
418
428
  Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 1).
419
429
 
420
- 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 (`0` return value cancels retry).
430
+ 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).
421
431
 
422
432
  By default, it retries *only* on the specified methods, status codes, and on these network errors:
423
433
  - `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached.
@@ -523,7 +533,7 @@ const got = require('got');
523
533
  Type: `boolean`\
524
534
  Default: `true`
525
535
 
526
- Determines if a `got.HTTPError` is thrown for error responses (non-2xx status codes).
536
+ Determines if a [`got.HTTPError`](#gothttperror) is thrown for unsuccessful responses.
527
537
 
528
538
  If this is disabled, requests that encounter an error status code will be resolved with the `response` instead of throwing. This may be useful if you are checking for resource availability and are expecting error responses.
529
539
 
@@ -809,6 +819,31 @@ Type: `string`
809
819
 
810
820
  The IP address used to send the request from.
811
821
 
822
+ ##### rejectUnauthorized
823
+
824
+ Type: `boolean`\
825
+ Default: `true`
826
+
827
+ If set to `false`, all invalid SSL certificates will be ignored and no error will be thrown.\
828
+ If set to `true`, it will throw an error whenever an invalid SSL certificate is detected.
829
+
830
+ We strongly recommend to have this set to `true` for security reasons.
831
+
832
+ ```js
833
+ const got = require('got');
834
+
835
+ (async () => {
836
+ // Correct:
837
+ await got('https://example.com', {rejectUnauthorized: true});
838
+
839
+ // You can disable it when developing an HTTPS app:
840
+ await got('https://localhost', {rejectUnauthorized: false});
841
+
842
+ // Never do this:
843
+ await got('https://example.com', {rejectUnauthorized: false});
844
+ })();
845
+ ```
846
+
812
847
  #### Response
813
848
 
814
849
  The response object will typically be a [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage), however, if returned from the cache it will be a [response-like object](https://github.com/lukechilds/responselike) which behaves in the same way.
@@ -1302,7 +1337,7 @@ When server response code is 2xx, and parsing body fails. Includes a `response`
1302
1337
 
1303
1338
  #### got.HTTPError
1304
1339
 
1305
- When the server response code is not 2xx. Includes a `response` property.
1340
+ When the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304. Includes a `response` property.
1306
1341
 
1307
1342
  #### got.MaxRedirectsError
1308
1343