got 10.5.5 → 10.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,7 +21,7 @@ function asStream(options) {
21
21
  throw new Error('Got\'s stream is not writable when the `body`, `json` or `form` option is used');
22
22
  };
23
23
  }
24
- else if (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH') {
24
+ else if (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH' || (options.allowGetBody && options.method === 'GET')) {
25
25
  options.body = input;
26
26
  }
27
27
  else {
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { Merge } from 'type-fest';
2
+ import { Merge, Except } from 'type-fest';
3
3
  import { ProxyStream } from './as-stream';
4
4
  import * as errors from './errors';
5
5
  import { CancelableRequest, Defaults, ExtendOptions, HandlerFunction, NormalizedOptions, Options, Response, URLOrOptions, PaginationOptions } from './types';
@@ -51,9 +51,11 @@ export interface GotRequestMethod {
51
51
  isStream: true;
52
52
  }>): ProxyStream<T>;
53
53
  }
54
+ export declare type GotPaginateOptions<T> = Except<Options, keyof PaginationOptions<unknown>> & PaginationOptions<T>;
55
+ export declare type URLOrGotPaginateOptions<T> = string | GotPaginateOptions<T>;
54
56
  export interface GotPaginate {
55
- <T>(url: URLOrOptions & PaginationOptions<T>, options?: Options & PaginationOptions<T>): AsyncIterableIterator<T>;
56
- all<T>(url: URLOrOptions & PaginationOptions<T>, options?: Options & PaginationOptions<T>): Promise<T[]>;
57
+ <T>(url: URLOrGotPaginateOptions<T>, options?: GotPaginateOptions<T>): AsyncIterableIterator<T>;
58
+ all<T>(url: URLOrGotPaginateOptions<T>, options?: GotPaginateOptions<T>): Promise<T[]>;
57
59
  }
58
60
  export interface Got extends Record<HTTPAlias, GotRequestMethod>, GotRequestMethod {
59
61
  stream: GotStream;
@@ -111,19 +111,21 @@ const create = (defaults) => {
111
111
  const result = await got(normalizedOptions);
112
112
  // eslint-disable-next-line no-await-in-loop
113
113
  const parsed = await pagination.transform(result);
114
+ const current = [];
114
115
  for (const item of parsed) {
115
- if (pagination.filter(item, all)) {
116
- if (!pagination.shouldContinue(item, all)) {
116
+ if (pagination.filter(item, all, current)) {
117
+ if (!pagination.shouldContinue(item, all, current)) {
117
118
  return;
118
119
  }
119
120
  yield item;
120
121
  all.push(item);
122
+ current.push(item);
121
123
  if (all.length === pagination.countLimit) {
122
124
  return;
123
125
  }
124
126
  }
125
127
  }
126
- const optionsToMerge = pagination.paginate(result);
128
+ const optionsToMerge = pagination.paginate(result, all, current);
127
129
  if (optionsToMerge === false) {
128
130
  return;
129
131
  }
@@ -67,10 +67,14 @@ const defaults = {
67
67
  maxRedirects: 10,
68
68
  prefixUrl: '',
69
69
  methodRewriting: true,
70
+ allowGetBody: false,
70
71
  ignoreInvalidCookies: false,
71
72
  context: {},
72
73
  _pagination: {
73
74
  transform: (response) => {
75
+ if (response.request.options.responseType === 'json') {
76
+ return response.body;
77
+ }
74
78
  return JSON.parse(response.body);
75
79
  },
76
80
  paginate: response => {
@@ -6,7 +6,7 @@ Called with plain request options, right before their normalization. This is esp
6
6
 
7
7
  @see [Request migration guide](https://github.com/sindresorhus/got/blob/master/migration-guides.md#breaking-changes) for an example.
8
8
  */
9
- export declare type InitHook = (options: NormalizedOptions) => void;
9
+ export declare type InitHook = (options: Options) => void;
10
10
  /**
11
11
  Called with normalized [request options](https://github.com/sindresorhus/got#options). Got will make no further changes to the request before it is sent (except the body serialization). This is especially useful in conjunction with [`got.extend()`](https://github.com/sindresorhus/got#instances) when you want to create an API client that, for example, uses HMAC-signing.
12
12
 
@@ -193,6 +193,7 @@ exports.preNormalizeArguments = (options, defaults) => {
193
193
  options.dnsCache = (_e = options.dnsCache, (_e !== null && _e !== void 0 ? _e : false));
194
194
  options.useElectronNet = Boolean(options.useElectronNet);
195
195
  options.methodRewriting = Boolean(options.methodRewriting);
196
+ options.allowGetBody = Boolean(options.allowGetBody);
196
197
  options.context = (_f = options.context, (_f !== null && _f !== void 0 ? _f : {}));
197
198
  return options;
198
199
  };
@@ -218,27 +219,52 @@ exports.mergeOptions = (...sources) => {
218
219
  return mergedOptions;
219
220
  };
220
221
  exports.normalizeArguments = (url, options, defaults) => {
221
- var _a, _b, _c, _d;
222
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
222
223
  // Merge options
223
224
  if (typeof url === 'undefined') {
224
225
  throw new TypeError('Missing `url` argument');
225
226
  }
226
- if (typeof options === 'undefined') {
227
- options = {};
228
- }
229
- if (is_1.default.urlInstance(url) || is_1.default.string(url)) {
230
- if (Reflect.has(options, 'url')) {
231
- throw new TypeError('The `url` option cannot be used if the input is a valid URL.');
227
+ const runInitHooks = (hooks, options) => {
228
+ if (hooks && options) {
229
+ for (const hook of hooks) {
230
+ const result = hook(options);
231
+ if (is_1.default.promise(result)) {
232
+ throw new TypeError('The `init` hook must be a synchronous function');
233
+ }
234
+ }
235
+ }
236
+ };
237
+ const hasUrl = is_1.default.urlInstance(url) || is_1.default.string(url);
238
+ if (hasUrl) {
239
+ if (options) {
240
+ if (Reflect.has(options, 'url')) {
241
+ throw new TypeError('The `url` option cannot be used if the input is a valid URL.');
242
+ }
243
+ }
244
+ else {
245
+ options = {};
232
246
  }
233
247
  // @ts-ignore URL is not URL
234
248
  options.url = url;
235
- options = exports.mergeOptions((_b = (_a = defaults) === null || _a === void 0 ? void 0 : _a.options, (_b !== null && _b !== void 0 ? _b : {})), options);
249
+ runInitHooks((_a = defaults) === null || _a === void 0 ? void 0 : _a.options.hooks.init, options);
250
+ runInitHooks((_b = options.hooks) === null || _b === void 0 ? void 0 : _b.init, options);
251
+ }
252
+ else if (Reflect.has(url, 'resolve')) {
253
+ throw new Error('The legacy `url.Url` is deprecated. Use `URL` instead.');
236
254
  }
237
255
  else {
238
- if (Reflect.has(url, 'resolve')) {
239
- throw new Error('The legacy `url.Url` is deprecated. Use `URL` instead.');
256
+ runInitHooks((_c = defaults) === null || _c === void 0 ? void 0 : _c.options.hooks.init, url);
257
+ runInitHooks((_d = url.hooks) === null || _d === void 0 ? void 0 : _d.init, url);
258
+ if (options) {
259
+ runInitHooks((_e = defaults) === null || _e === void 0 ? void 0 : _e.options.hooks.init, options);
260
+ runInitHooks((_f = options.hooks) === null || _f === void 0 ? void 0 : _f.init, options);
240
261
  }
241
- options = exports.mergeOptions((_d = (_c = defaults) === null || _c === void 0 ? void 0 : _c.options, (_d !== null && _d !== void 0 ? _d : {})), url, options);
262
+ }
263
+ if (hasUrl) {
264
+ options = exports.mergeOptions((_h = (_g = defaults) === null || _g === void 0 ? void 0 : _g.options, (_h !== null && _h !== void 0 ? _h : {})), (options !== null && options !== void 0 ? options : {}));
265
+ }
266
+ else {
267
+ options = exports.mergeOptions((_k = (_j = defaults) === null || _j === void 0 ? void 0 : _j.options, (_k !== null && _k !== void 0 ? _k : {})), url, (options !== null && options !== void 0 ? options : {}));
242
268
  }
243
269
  // Normalize URL
244
270
  // TODO: drop `optionsToUrl` in Got 12
@@ -278,15 +304,10 @@ exports.normalizeArguments = (url, options, defaults) => {
278
304
  delete normalizedOptions.headers[key];
279
305
  }
280
306
  }
281
- for (const hook of normalizedOptions.hooks.init) {
282
- const result = hook(normalizedOptions);
283
- if (is_1.default.promise(result)) {
284
- throw new TypeError('The `init` hook must be a synchronous function');
285
- }
286
- }
287
307
  return normalizedOptions;
288
308
  };
289
- const withoutBody = new Set(['GET', 'HEAD']);
309
+ const withoutBody = new Set(['HEAD']);
310
+ const withoutBodyUnlessSpecified = 'GET';
290
311
  exports.normalizeRequestArguments = async (options) => {
291
312
  var _a, _b, _c;
292
313
  options = exports.mergeOptions(options);
@@ -301,6 +322,9 @@ exports.normalizeRequestArguments = async (options) => {
301
322
  if ((isBody || isForm || isJson) && withoutBody.has(options.method)) {
302
323
  throw new TypeError(`The \`${options.method}\` method cannot be used with a body`);
303
324
  }
325
+ if (!options.allowGetBody && (isBody || isForm || isJson) && withoutBodyUnlessSpecified === options.method) {
326
+ throw new TypeError(`The \`${options.method}\` method cannot be used with a body`);
327
+ }
304
328
  if ([isBody, isForm, isJson].filter(isTrue => isTrue).length > 1) {
305
329
  throw new TypeError('The `body`, `json` and `form` options are mutually exclusive');
306
330
  }
@@ -347,7 +371,7 @@ exports.normalizeRequestArguments = async (options) => {
347
371
  // a payload body and the method semantics do not anticipate such a
348
372
  // body.
349
373
  if (is_1.default.undefined(headers['content-length']) && is_1.default.undefined(headers['transfer-encoding'])) {
350
- if ((options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH' || options.method === 'DELETE') &&
374
+ if ((options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH' || options.method === 'DELETE' || (options.allowGetBody && options.method === 'GET')) &&
351
375
  !is_1.default.undefined(uploadBodySize)) {
352
376
  // @ts-ignore We assign if it is undefined, so this IS correct
353
377
  headers['content-length'] = String(uploadBodySize);
@@ -81,6 +81,7 @@ exports.default = (options) => {
81
81
  }
82
82
  if (options.followRedirect && Reflect.has(typedResponse.headers, 'location') && redirectCodes.has(statusCode)) {
83
83
  typedResponse.resume(); // We're being redirected, we don't care about the response.
84
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare
84
85
  if (statusCode === 303 || options.methodRewriting === false) {
85
86
  if (options.method !== 'GET' && options.method !== 'HEAD') {
86
87
  // Server responded with "see other", indicating that the resource exists at another location,
@@ -104,9 +104,9 @@ export declare type DefaultOptions = Merge<Required<Except<GotOptions, 'hooks' |
104
104
  export interface PaginationOptions<T> {
105
105
  _pagination?: {
106
106
  transform?: (response: Response) => Promise<T[]> | T[];
107
- filter?: (item: T, allItems: T[]) => boolean;
108
- paginate?: (response: Response) => Options | false;
109
- shouldContinue?: (item: T, allItems: T[]) => boolean;
107
+ filter?: (item: T, allItems: T[], currentItems: T[]) => boolean;
108
+ paginate?: (response: Response, allItems: T[], currentItems: T[]) => Options | false;
109
+ shouldContinue?: (item: T, allItems: T[], currentItems: T[]) => boolean;
110
110
  countLimit?: number;
111
111
  };
112
112
  }
@@ -145,6 +145,7 @@ export interface GotOptions extends PaginationOptions<unknown> {
145
145
  };
146
146
  maxRedirects?: number;
147
147
  lookup?: CacheableLookup['lookup'];
148
+ allowGetBody?: boolean;
148
149
  methodRewriting?: boolean;
149
150
  }
150
151
  export declare type Options = Merge<https.RequestOptions, Merge<GotOptions, URLOptions>>;
@@ -173,6 +174,7 @@ export interface NormalizedOptions extends Options {
173
174
  followRedirect: boolean;
174
175
  useElectronNet: boolean;
175
176
  methodRewriting: boolean;
177
+ allowGetBody: boolean;
176
178
  context: {
177
179
  [key: string]: any;
178
180
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "got",
3
- "version": "10.5.5",
3
+ "version": "10.7.0",
4
4
  "description": "Human-friendly and powerful HTTP request library for Node.js",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/got",
@@ -41,7 +41,7 @@
41
41
  "superagent"
42
42
  ],
43
43
  "dependencies": {
44
- "@sindresorhus/is": "^1.0.0",
44
+ "@sindresorhus/is": "^2.0.0",
45
45
  "@szmarczak/http-timer": "^4.0.0",
46
46
  "@types/cacheable-request": "^6.0.1",
47
47
  "cacheable-lookup": "^2.0.0",
@@ -50,15 +50,15 @@
50
50
  "duplexer3": "^0.1.4",
51
51
  "get-stream": "^5.0.0",
52
52
  "lowercase-keys": "^2.0.0",
53
- "mimic-response": "^2.0.0",
53
+ "mimic-response": "^2.1.0",
54
54
  "p-cancelable": "^2.0.0",
55
55
  "p-event": "^4.0.0",
56
56
  "responselike": "^2.0.0",
57
57
  "to-readable-stream": "^2.0.0",
58
- "type-fest": "^0.9.0"
58
+ "type-fest": "^0.10.0"
59
59
  },
60
60
  "devDependencies": {
61
- "@ava/typescript": "^1.1.0",
61
+ "@ava/typescript": "^1.1.1",
62
62
  "@sindresorhus/tsconfig": "^0.7.0",
63
63
  "@types/duplexer3": "^0.1.0",
64
64
  "@types/express": "^4.17.2",
@@ -67,34 +67,33 @@
67
67
  "@types/proxyquire": "^1.3.28",
68
68
  "@types/sinon": "^7.0.13",
69
69
  "@types/tough-cookie": "^2.3.5",
70
- "@typescript-eslint/eslint-plugin": "^2.17.0",
71
- "@typescript-eslint/parser": "^2.17.0",
72
- "ava": "^3.2.0",
70
+ "@typescript-eslint/eslint-plugin": "^2.19.2",
71
+ "@typescript-eslint/parser": "^2.19.2",
72
+ "ava": "^3.3.0",
73
73
  "coveralls": "^3.0.4",
74
74
  "create-test-server": "^3.0.1",
75
75
  "del-cli": "^3.0.0",
76
76
  "delay": "^4.3.0",
77
- "eslint-config-xo-typescript": "^0.24.1",
77
+ "eslint-config-xo-typescript": "^0.26.0",
78
78
  "express": "^4.17.1",
79
79
  "form-data": "^3.0.0",
80
80
  "get-port": "^5.0.0",
81
81
  "keyv": "^4.0.0",
82
- "lolex": "^5.1.1",
83
- "nock": "^11.3.4",
84
- "np": "^5.1.3",
82
+ "lolex": "^6.0.0",
83
+ "nock": "^12.0.0",
84
+ "np": "^6.0.0",
85
85
  "nyc": "^15.0.0",
86
86
  "proxyquire": "^2.0.1",
87
87
  "sinon": "^8.1.1",
88
88
  "slow-stream": "0.0.4",
89
- "tempy": "^0.3.0",
89
+ "tempy": "^0.4.0",
90
90
  "tough-cookie": "^3.0.0",
91
91
  "typescript": "3.7.5",
92
- "xo": "^0.25.3"
92
+ "xo": "^0.26.0"
93
93
  },
94
94
  "types": "dist/source",
95
95
  "sideEffects": false,
96
96
  "browser": {
97
- "decompress-response": false,
98
97
  "electron": false
99
98
  },
100
99
  "ava": {
package/readme.md CHANGED
@@ -188,7 +188,9 @@ Type: `string | Buffer | stream.Readable` or [`form-data` instance](https://gith
188
188
 
189
189
  **Note #2:** If you provide this option, `got.stream()` will be read-only.
190
190
 
191
- **Note #3:** If you provide a payload with the `GET` or `HEAD` method, it will throw a `TypeError`.
191
+ **Note #3:** If you provide a payload with the `GET` or `HEAD` method, it will throw a `TypeError` unless the method is `GET` and the `allowGetBody` option is set to `true`.
192
+
193
+ **Note #4:** This option is not enumerable and will not be merged with the instance defaults.
192
194
 
193
195
  The `content-length` header will be automatically set if `body` is a `string` / `Buffer` / `fs.createReadStream` instance / [`form-data` instance](https://github.com/form-data/form-data), and `content-length` and `transfer-encoding` are not manually set in `options.headers`.
194
196
 
@@ -196,7 +198,8 @@ The `content-length` header will be automatically set if `body` is a `string` /
196
198
 
197
199
  Type: `object | Array | number | string | boolean | null` *(JSON-serializable values)*
198
200
 
199
- **Note:** If you provide this option, `got.stream()` will be read-only.
201
+ **Note #1:** If you provide this option, `got.stream()` will be read-only.
202
+ **Note #2:** This option is not enumerable and will not be merged with the instance defaults.
200
203
 
201
204
  JSON body. If the `Content-Type` header is not set, it will be set to `application/json`.
202
205
 
@@ -217,7 +220,7 @@ const instance = got.extend({
217
220
  hooks: {
218
221
  beforeRequest: [
219
222
  options => {
220
- if (!options.context && !options.context.token) {
223
+ if (!options.context || !options.context.token) {
221
224
  throw new Error('Token required');
222
225
  }
223
226
 
@@ -248,21 +251,35 @@ Default: `'text'`
248
251
 
249
252
  The parsing method. Can be `'text'`, `'json'` or `'buffer'`.
250
253
 
251
- The promise also has `.text()`, `.json()` and `.buffer()` methods which sets this and the `resolveBodyOnly` option automatically.
254
+ The promise also has `.text()`, `.json()` and `.buffer()` methods which return another Got promise for the parsed body.\
255
+ It's like setting the options to `{responseType: 'json', resolveBodyOnly: true}` but without affecting the main Got promise.
252
256
 
253
257
  Example:
254
258
 
259
+ ```js
260
+ (async () => {
261
+ const responsePromise = got(url);
262
+ const bufferPromise = responsePromise.buffer();
263
+ const jsonPromise = responsePromise.json();
264
+
265
+ const [response, buffer, json] = Promise.all([responsePromise, bufferPromise, jsonPromise]);
266
+ // `response` is an instance of Got Response
267
+ // `buffer` is an instance of Buffer
268
+ // `json` is an object
269
+ })();
270
+ ```
271
+
255
272
  ```js
256
273
  // This
257
274
  const body = await got(url).json();
258
275
 
259
- // is the same as this
276
+ // is semantically the same as this
260
277
  const body = await got(url, {responseType: 'json', resolveBodyOnly: true});
261
278
  ```
262
279
 
263
280
  ###### resolveBodyOnly
264
281
 
265
- Type: `string`\
282
+ Type: `boolean`\
266
283
  Default: `false`
267
284
 
268
285
  When set to `true` the promise will return the [Response body](#body-1) instead of the [Response](#response) object.
@@ -307,7 +324,8 @@ To get a [`Buffer`](https://nodejs.org/api/buffer.html), you need to set [`respo
307
324
 
308
325
  Type: `object | true`
309
326
 
310
- **Note:** If you provide this option, `got.stream()` will be read-only.
327
+ **Note #1:** If you provide this option, `got.stream()` will be read-only.
328
+ **Note #2:** This option is not enumerable and will not be merged with the instance defaults.
311
329
 
312
330
  The form body is converted to query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
313
331
 
@@ -410,6 +428,15 @@ Default: `true`
410
428
 
411
429
  By default, redirects will use [method rewriting](https://tools.ietf.org/html/rfc7231#section-6.4). For example, when sending a POST request and receiving a `302`, it will resend the body to the new location using the same HTTP method (`POST` in this case).
412
430
 
431
+ ###### allowGetBody
432
+
433
+ Type: `boolean`\
434
+ Default: `false`
435
+
436
+ **Note:** The [RFC 7321](https://tools.ietf.org/html/rfc7231#section-4.3.1) doesn't specify any particular behavior for the GET method having a payload, therefore **it's considered an [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern)**.
437
+
438
+ Set this to `true` to allow sending body for the `GET` method. However, the [HTTP/2 specification](https://tools.ietf.org/html/rfc7540#section-8.1.3) says that `An HTTP GET request includes request header fields and no payload body`, therefore when using the HTTP/2 protocol this option will have no effect. This option is only meant to interact with non-compliant servers when you have no other choice.
439
+
413
440
  ###### maxRedirects
414
441
 
415
442
  Type: `number`\
@@ -551,7 +578,7 @@ got.post('https://example.com', {
551
578
  hooks: {
552
579
  beforeRetry: [
553
580
  (options, error, retryCount) => {
554
- if (error.statusCode === 413) { // Payload too large
581
+ if (error.response.statusCode === 413) { // Payload too large
555
582
  options.body = getNewBody();
556
583
  }
557
584
  }
@@ -627,7 +654,7 @@ got('https://api.github.com/some-endpoint', {
627
654
  const {response} = error;
628
655
  if (response && response.body) {
629
656
  error.name = 'GitHubError';
630
- error.message = `${response.body.message} (${error.statusCode})`;
657
+ error.message = `${response.body.message} (${response.statusCode})`;
631
658
  }
632
659
 
633
660
  return error;
@@ -655,23 +682,64 @@ A function that transform [`Response`](#response) into an array of items. This i
655
682
  Type: `Function`\
656
683
  Default: [`Link` header logic](source/index.ts)
657
684
 
658
- A function that returns an object representing Got options pointing to the next page. If there are no more pages, `false` should be returned.
685
+ The function takes three arguments:
686
+ - `response` - The current response object.
687
+ - `allItems` - An array of the emitted items.
688
+ - `currentItems` - Items from the current response.
689
+
690
+ It should return an object representing Got options pointing to the next page. If there are no more pages, `false` should be returned.
691
+
692
+ For example, if you want to stop when the response contains less items than expected, you can use something like this:
693
+
694
+ ```js
695
+ const got = require('got');
696
+
697
+ (async () => {
698
+ const limit = 10;
699
+
700
+ const items = got.paginate('https://example.com/items', {
701
+ searchParams: {
702
+ limit,
703
+ offset: 0
704
+ },
705
+ _pagination: {
706
+ paginate: (response, allItems, currentItems) => {
707
+ const previousSearchParams = response.request.options.searchParams;
708
+ const {offset: previousOffset} = previousSearchParams;
709
+
710
+ if (currentItems.length < limit) {
711
+ return false;
712
+ }
713
+
714
+ return {
715
+ searchParams: {
716
+ ...previousSearchParams,
717
+ offset: previousOffset + limit,
718
+ }
719
+ };
720
+ }
721
+ }
722
+ });
723
+
724
+ console.log('Items from all pages:', items);
725
+ })();
726
+ ```
659
727
 
660
728
  ###### \_pagination.filter
661
729
 
662
730
  Type: `Function`\
663
- Default: `(item, allItems) => true`
731
+ Default: `(item, allItems, currentItems) => true`
664
732
 
665
733
  Checks whether the item should be emitted or not.
666
734
 
667
735
  ###### \_pagination.shouldContinue
668
736
 
669
737
  Type: `Function`\
670
- Default: `(item, allItems) => true`
738
+ Default: `(item, allItems, currentItems) => true`
671
739
 
672
740
  Checks whether the pagination should continue.
673
741
 
674
- For example, if you need to stop **before** emitting an entry with some flag, you should use `(item, allItems) => !item.flag`. If you want to stop **after** emitting the entry, you should use `(item, allItems) => allItems.some(entry => entry.flag)` instead.
742
+ For example, if you need to stop **before** emitting an entry with some flag, you should use `(item, allItems, currentItems) => !item.flag`. If you want to stop **after** emitting the entry, you should use `(item, allItems, currentItems) => allItems.some(entry => entry.flag)` instead.
675
743
 
676
744
  ###### \_pagination.countLimit
677
745
 
@@ -810,7 +878,7 @@ Progress events for uploading (sending a request) and downloading (receiving a r
810
878
  }
811
879
  ```
812
880
 
813
- If it's not possible to retrieve the body size (can happen when streaming), `total` will be `undefined`.
881
+ If the `content-length` header is missing, `total` will be `undefined`.
814
882
 
815
883
  ```js
816
884
  (async () => {
@@ -1003,6 +1071,14 @@ Options are deeply merged to a new object. The value of each key is determined a
1003
1071
  - If the parent property is a plain `object` too, both values are merged recursively into a new `object`.
1004
1072
  - Otherwise, only the new value is deeply cloned.
1005
1073
  - If the new property is an `Array`, it overwrites the old one with a deep clone of the new property.
1074
+ - Properties that are not enumerable, such as `context`, `body`, `json`, and `form`, will not be merged.
1075
+ ```js
1076
+ const a = {json: {cat: 'meow'}};
1077
+ const b = {json: {cow: 'moo'}};
1078
+
1079
+ got.mergeOptions(a, b);
1080
+ //=> {json: {cow: 'moo'}}
1081
+ ```
1006
1082
  - Otherwise, the new value is assigned to the key.
1007
1083
 
1008
1084
  #### got.defaults