got 9.5.1 → 9.6.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/package.json +4 -4
- package/readme.md +41 -1
- package/source/as-promise.js +1 -0
- package/source/as-stream.js +1 -0
- package/source/errors.js +1 -0
- package/source/known-hook-events.js +2 -0
- package/source/normalize-arguments.js +19 -2
- package/source/request-as-event-emitter.js +22 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "got",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.6.0",
|
|
4
4
|
"description": "Simplified HTTP requests",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/got",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"url-parse-lax": "^3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"ava": "^1.0
|
|
50
|
+
"ava": "^1.1.0",
|
|
51
51
|
"coveralls": "^3.0.0",
|
|
52
52
|
"delay": "^4.1.0",
|
|
53
53
|
"form-data": "^2.3.3",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"slow-stream": "0.0.4",
|
|
62
62
|
"tempfile": "^2.0.0",
|
|
63
63
|
"tempy": "^0.2.1",
|
|
64
|
-
"tough-cookie": "^
|
|
65
|
-
"xo": "^0.
|
|
64
|
+
"tough-cookie": "^3.0.0",
|
|
65
|
+
"xo": "^0.24.0"
|
|
66
66
|
},
|
|
67
67
|
"ava": {
|
|
68
68
|
"concurrency": 4
|
package/readme.md
CHANGED
|
@@ -35,7 +35,7 @@ Got is for Node.js. For browsers, we recommend [Ky](https://github.com/sindresor
|
|
|
35
35
|
- [Errors with metadata](#errors)
|
|
36
36
|
- [JSON mode](#json)
|
|
37
37
|
- [WHATWG URL support](#url)
|
|
38
|
-
- [Hooks](
|
|
38
|
+
- [Hooks](#hooks)
|
|
39
39
|
- [Instances with custom defaults](#instances)
|
|
40
40
|
- [Composable](advanced-creation.md#merging-instances)
|
|
41
41
|
- [Electron support](#useelectronnet)
|
|
@@ -351,6 +351,17 @@ Type: `Object<string, Function[]>`
|
|
|
351
351
|
|
|
352
352
|
Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially.
|
|
353
353
|
|
|
354
|
+
###### hooks.init
|
|
355
|
+
|
|
356
|
+
Type: `Function[]`<br>
|
|
357
|
+
Default: `[]`
|
|
358
|
+
|
|
359
|
+
Called with plain [request options](#options), right before their normalization. This is especially useful in conjunction with [`got.extend()`](#instances) and [`got.create()`](advanced-creation.md) when the input needs custom handling.
|
|
360
|
+
|
|
361
|
+
See the [Request migration guide](migration-guides.md#breaking-changes) for an example.
|
|
362
|
+
|
|
363
|
+
**Note**: This hook must be synchronous!
|
|
364
|
+
|
|
354
365
|
###### hooks.beforeRequest
|
|
355
366
|
|
|
356
367
|
Type: `Function[]`<br>
|
|
@@ -447,6 +458,35 @@ const instance = got.extend({
|
|
|
447
458
|
});
|
|
448
459
|
```
|
|
449
460
|
|
|
461
|
+
###### hooks.beforeError
|
|
462
|
+
|
|
463
|
+
Type: `Function[]`<br>
|
|
464
|
+
Default: `[]`
|
|
465
|
+
|
|
466
|
+
Called with an `Error` instance. The error is passed to the hook right before it's thrown. This is especially useful when you want to have more detailed errors.
|
|
467
|
+
|
|
468
|
+
**Note**: Errors thrown while normalizing input options are thrown directly and not part of this hook.
|
|
469
|
+
|
|
470
|
+
```js
|
|
471
|
+
const got = require('got');
|
|
472
|
+
|
|
473
|
+
got('api.github.com/some-endpoint', {
|
|
474
|
+
hooks: {
|
|
475
|
+
onError: [
|
|
476
|
+
error => {
|
|
477
|
+
const {response} = error;
|
|
478
|
+
if (response && response.body) {
|
|
479
|
+
error.name = 'GitHubError';
|
|
480
|
+
error.message = `${response.body.message} (${error.statusCode})`;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return error;
|
|
484
|
+
}
|
|
485
|
+
]
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
```
|
|
489
|
+
|
|
450
490
|
#### Response
|
|
451
491
|
|
|
452
492
|
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.
|
package/source/as-promise.js
CHANGED
package/source/as-stream.js
CHANGED
package/source/errors.js
CHANGED
|
@@ -11,8 +11,15 @@ const knownHookEvents = require('./known-hook-events');
|
|
|
11
11
|
|
|
12
12
|
const retryAfterStatusCodes = new Set([413, 429, 503]);
|
|
13
13
|
|
|
14
|
-
// `preNormalize` handles static
|
|
15
|
-
//
|
|
14
|
+
// `preNormalize` handles static options (e.g. headers).
|
|
15
|
+
// For example, when you create a custom instance and make a request
|
|
16
|
+
// with no static changes, they won't be normalized again.
|
|
17
|
+
//
|
|
18
|
+
// `normalize` operates on dynamic options - they cannot be saved.
|
|
19
|
+
// For example, `body` is everytime different per request.
|
|
20
|
+
// When it's done normalizing the new options, it performs merge()
|
|
21
|
+
// on the prenormalized options and the normalized ones.
|
|
22
|
+
|
|
16
23
|
const preNormalize = (options, defaults) => {
|
|
17
24
|
if (is.nullOrUndefined(options.headers)) {
|
|
18
25
|
options.headers = {};
|
|
@@ -49,6 +56,7 @@ const preNormalize = (options, defaults) => {
|
|
|
49
56
|
} else if (is.object(options.timeout)) {
|
|
50
57
|
options.gotTimeout = options.timeout;
|
|
51
58
|
}
|
|
59
|
+
|
|
52
60
|
delete options.timeout;
|
|
53
61
|
|
|
54
62
|
const {retry} = options;
|
|
@@ -125,6 +133,14 @@ const normalize = (url, options, defaults) => {
|
|
|
125
133
|
// Override both null/undefined with default protocol
|
|
126
134
|
options = merge({path: ''}, url, {protocol: url.protocol || 'https:'}, options);
|
|
127
135
|
|
|
136
|
+
for (const hook of options.hooks.init) {
|
|
137
|
+
const called = hook(options);
|
|
138
|
+
|
|
139
|
+
if (is.promise(called)) {
|
|
140
|
+
throw new TypeError('The `init` hook must be a synchronous function');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
128
144
|
const {baseUrl} = options;
|
|
129
145
|
Object.defineProperty(options, 'baseUrl', {
|
|
130
146
|
set: () => {
|
|
@@ -138,6 +154,7 @@ const normalize = (url, options, defaults) => {
|
|
|
138
154
|
if (!is.string(query)) {
|
|
139
155
|
options.query = (new URLSearchParams(query)).toString();
|
|
140
156
|
}
|
|
157
|
+
|
|
141
158
|
options.path = `${options.path.split('?')[0]}?${options.query}`;
|
|
142
159
|
delete options.query;
|
|
143
160
|
}
|
|
@@ -33,6 +33,19 @@ module.exports = (options, input) => {
|
|
|
33
33
|
const getCookieString = options.cookieJar ? util.promisify(options.cookieJar.getCookieString.bind(options.cookieJar)) : null;
|
|
34
34
|
const agents = is.object(options.agent) ? options.agent : null;
|
|
35
35
|
|
|
36
|
+
const emitError = async error => {
|
|
37
|
+
try {
|
|
38
|
+
for (const hook of options.hooks.beforeError) {
|
|
39
|
+
// eslint-disable-next-line no-await-in-loop
|
|
40
|
+
error = await hook(error);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
emitter.emit('error', error);
|
|
44
|
+
} catch (error2) {
|
|
45
|
+
emitter.emit('error', error2);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
36
49
|
const get = async options => {
|
|
37
50
|
const currentUrl = redirectString || requestUrl;
|
|
38
51
|
|
|
@@ -141,7 +154,7 @@ module.exports = (options, input) => {
|
|
|
141
154
|
|
|
142
155
|
getResponse(response, options, emitter);
|
|
143
156
|
} catch (error) {
|
|
144
|
-
|
|
157
|
+
emitError(error);
|
|
145
158
|
}
|
|
146
159
|
};
|
|
147
160
|
|
|
@@ -166,7 +179,7 @@ module.exports = (options, input) => {
|
|
|
166
179
|
}
|
|
167
180
|
|
|
168
181
|
if (emitter.retry(error) === false) {
|
|
169
|
-
|
|
182
|
+
emitError(error);
|
|
170
183
|
}
|
|
171
184
|
});
|
|
172
185
|
|
|
@@ -198,7 +211,7 @@ module.exports = (options, input) => {
|
|
|
198
211
|
request.end(uploadComplete);
|
|
199
212
|
}
|
|
200
213
|
} catch (error) {
|
|
201
|
-
|
|
214
|
+
emitError(new RequestError(error, options));
|
|
202
215
|
}
|
|
203
216
|
};
|
|
204
217
|
|
|
@@ -208,9 +221,9 @@ module.exports = (options, input) => {
|
|
|
208
221
|
|
|
209
222
|
cacheRequest.once('error', error => {
|
|
210
223
|
if (error instanceof CacheableRequest.RequestError) {
|
|
211
|
-
|
|
224
|
+
emitError(new RequestError(error, options));
|
|
212
225
|
} else {
|
|
213
|
-
|
|
226
|
+
emitError(new CacheError(error, options));
|
|
214
227
|
}
|
|
215
228
|
});
|
|
216
229
|
|
|
@@ -220,7 +233,7 @@ module.exports = (options, input) => {
|
|
|
220
233
|
try {
|
|
221
234
|
handleRequest(fn.request(options, handleResponse));
|
|
222
235
|
} catch (error) {
|
|
223
|
-
|
|
236
|
+
emitError(new RequestError(error, options));
|
|
224
237
|
}
|
|
225
238
|
}
|
|
226
239
|
};
|
|
@@ -231,7 +244,7 @@ module.exports = (options, input) => {
|
|
|
231
244
|
try {
|
|
232
245
|
backoff = options.retry.retries(++retryCount, error);
|
|
233
246
|
} catch (error2) {
|
|
234
|
-
|
|
247
|
+
emitError(error2);
|
|
235
248
|
return;
|
|
236
249
|
}
|
|
237
250
|
|
|
@@ -245,7 +258,7 @@ module.exports = (options, input) => {
|
|
|
245
258
|
|
|
246
259
|
await get(options);
|
|
247
260
|
} catch (error) {
|
|
248
|
-
|
|
261
|
+
emitError(error);
|
|
249
262
|
}
|
|
250
263
|
};
|
|
251
264
|
|
|
@@ -291,7 +304,7 @@ module.exports = (options, input) => {
|
|
|
291
304
|
|
|
292
305
|
await get(options);
|
|
293
306
|
} catch (error) {
|
|
294
|
-
|
|
307
|
+
emitError(error);
|
|
295
308
|
}
|
|
296
309
|
});
|
|
297
310
|
|