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.
- package/dist/source/as-stream.js +1 -1
- package/dist/source/create.d.ts +5 -3
- package/dist/source/create.js +5 -3
- package/dist/source/index.js +4 -0
- package/dist/source/known-hook-events.d.ts +1 -1
- package/dist/source/normalize-arguments.js +43 -19
- package/dist/source/request-as-event-emitter.js +1 -0
- package/dist/source/types.d.ts +5 -3
- package/package.json +14 -15
- package/readme.md +90 -14
package/dist/source/as-stream.js
CHANGED
|
@@ -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 {
|
package/dist/source/create.d.ts
CHANGED
|
@@ -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:
|
|
56
|
-
all<T>(url:
|
|
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;
|
package/dist/source/create.js
CHANGED
|
@@ -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
|
}
|
package/dist/source/index.js
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
227
|
-
options
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
-
|
|
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
|
-
|
|
239
|
-
|
|
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
|
-
|
|
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(['
|
|
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,
|
package/dist/source/types.d.ts
CHANGED
|
@@ -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.
|
|
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": "^
|
|
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.
|
|
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.
|
|
58
|
+
"type-fest": "^0.10.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@ava/typescript": "^1.1.
|
|
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.
|
|
71
|
-
"@typescript-eslint/parser": "^2.
|
|
72
|
-
"ava": "^3.
|
|
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.
|
|
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": "^
|
|
83
|
-
"nock": "^
|
|
84
|
-
"np": "^
|
|
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.
|
|
89
|
+
"tempy": "^0.4.0",
|
|
90
90
|
"tough-cookie": "^3.0.0",
|
|
91
91
|
"typescript": "3.7.5",
|
|
92
|
-
"xo": "^0.
|
|
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
|
|
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
|
|
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: `
|
|
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} (${
|
|
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
|
-
|
|
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
|
|
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
|