got 14.6.0 → 14.6.2
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 +16 -8
- package/dist/source/core/diagnostics-channel.d.ts +89 -0
- package/dist/source/core/diagnostics-channel.js +49 -0
- package/dist/source/core/errors.d.ts +14 -1
- package/dist/source/core/errors.js +27 -19
- package/dist/source/core/index.d.ts +6 -1
- package/dist/source/core/index.js +277 -100
- package/dist/source/core/options.d.ts +153 -4
- package/dist/source/core/options.js +79 -8
- package/dist/source/core/response.d.ts +2 -0
- package/dist/source/core/response.js +2 -2
- package/dist/source/core/timed-out.d.ts +1 -0
- package/dist/source/core/timed-out.js +2 -3
- package/dist/source/core/utils/get-body-size.js +1 -2
- package/dist/source/core/utils/weakable-map.d.ts +0 -1
- package/dist/source/core/utils/weakable-map.js +2 -6
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.js +1 -0
- package/package.json +3 -1
|
@@ -40,7 +40,7 @@ export default function asPromise(firstRequest) {
|
|
|
40
40
|
request.once('response', async (response) => {
|
|
41
41
|
// Parse body
|
|
42
42
|
const contentEncoding = (response.headers['content-encoding'] ?? '').toLowerCase();
|
|
43
|
-
const isCompressed = contentEncoding === 'gzip' || contentEncoding === 'deflate' || contentEncoding === 'br';
|
|
43
|
+
const isCompressed = contentEncoding === 'gzip' || contentEncoding === 'deflate' || contentEncoding === 'br' || contentEncoding === 'zstd';
|
|
44
44
|
const { options } = request;
|
|
45
45
|
if (isCompressed && !options.decompress) {
|
|
46
46
|
response.body = response.rawBody;
|
|
@@ -170,27 +170,35 @@ export default function asPromise(firstRequest) {
|
|
|
170
170
|
emitter.off(event, function_);
|
|
171
171
|
return promise;
|
|
172
172
|
};
|
|
173
|
-
const shortcut = (responseType) => {
|
|
173
|
+
const shortcut = (promiseToAwait, responseType) => {
|
|
174
174
|
const newPromise = (async () => {
|
|
175
175
|
// Wait until downloading has ended
|
|
176
|
-
await
|
|
176
|
+
await promiseToAwait;
|
|
177
177
|
const { options } = globalResponse.request;
|
|
178
178
|
return parseBody(globalResponse, responseType, options.parseJson, options.encoding);
|
|
179
179
|
})();
|
|
180
180
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
181
|
-
Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(
|
|
181
|
+
Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(promiseToAwait));
|
|
182
182
|
return newPromise;
|
|
183
183
|
};
|
|
184
|
-
|
|
184
|
+
// Note: These use `function` syntax (not arrows) to access `this` context.
|
|
185
|
+
// When custom handlers wrap the promise to transform errors, these methods
|
|
186
|
+
// are copied to the handler's promise. Using `this` ensures we await the
|
|
187
|
+
// handler's wrapped promise, not the original, so errors propagate correctly.
|
|
188
|
+
promise.json = function () {
|
|
185
189
|
if (globalRequest.options) {
|
|
186
190
|
const { headers } = globalRequest.options;
|
|
187
191
|
if (!globalRequest.writableFinished && !('accept' in headers)) {
|
|
188
192
|
headers.accept = 'application/json';
|
|
189
193
|
}
|
|
190
194
|
}
|
|
191
|
-
return shortcut('json');
|
|
195
|
+
return shortcut(this, 'json');
|
|
196
|
+
};
|
|
197
|
+
promise.buffer = function () {
|
|
198
|
+
return shortcut(this, 'buffer');
|
|
199
|
+
};
|
|
200
|
+
promise.text = function () {
|
|
201
|
+
return shortcut(this, 'text');
|
|
192
202
|
};
|
|
193
|
-
promise.buffer = () => shortcut('buffer');
|
|
194
|
-
promise.text = () => shortcut('text');
|
|
195
203
|
return promise;
|
|
196
204
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Timings } from '@szmarczak/http-timer';
|
|
2
|
+
import type { RequestError } from './errors.js';
|
|
3
|
+
export type RequestId = string;
|
|
4
|
+
/**
|
|
5
|
+
Message for the `got:request:create` diagnostic channel.
|
|
6
|
+
|
|
7
|
+
Emitted when a request is created.
|
|
8
|
+
*/
|
|
9
|
+
export type DiagnosticRequestCreate = {
|
|
10
|
+
requestId: RequestId;
|
|
11
|
+
url: string;
|
|
12
|
+
method: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
Message for the `got:request:start` diagnostic channel.
|
|
16
|
+
|
|
17
|
+
Emitted before the native HTTP request is sent.
|
|
18
|
+
*/
|
|
19
|
+
export type DiagnosticRequestStart = {
|
|
20
|
+
requestId: RequestId;
|
|
21
|
+
url: string;
|
|
22
|
+
method: string;
|
|
23
|
+
headers: Record<string, string | string[] | undefined>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
Message for the `got:response:start` diagnostic channel.
|
|
27
|
+
|
|
28
|
+
Emitted when response headers are received.
|
|
29
|
+
*/
|
|
30
|
+
export type DiagnosticResponseStart = {
|
|
31
|
+
requestId: RequestId;
|
|
32
|
+
url: string;
|
|
33
|
+
statusCode: number;
|
|
34
|
+
headers: Record<string, string | string[] | undefined>;
|
|
35
|
+
isFromCache: boolean;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
Message for the `got:response:end` diagnostic channel.
|
|
39
|
+
|
|
40
|
+
Emitted when the response completes.
|
|
41
|
+
*/
|
|
42
|
+
export type DiagnosticResponseEnd = {
|
|
43
|
+
requestId: RequestId;
|
|
44
|
+
url: string;
|
|
45
|
+
statusCode: number;
|
|
46
|
+
bodySize?: number;
|
|
47
|
+
timings?: Timings;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
Message for the `got:request:retry` diagnostic channel.
|
|
51
|
+
|
|
52
|
+
Emitted when retrying a request.
|
|
53
|
+
*/
|
|
54
|
+
export type DiagnosticRequestRetry = {
|
|
55
|
+
requestId: RequestId;
|
|
56
|
+
retryCount: number;
|
|
57
|
+
error: RequestError;
|
|
58
|
+
delay: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
Message for the `got:request:error` diagnostic channel.
|
|
62
|
+
|
|
63
|
+
Emitted when a request fails.
|
|
64
|
+
*/
|
|
65
|
+
export type DiagnosticRequestError = {
|
|
66
|
+
requestId: RequestId;
|
|
67
|
+
url: string;
|
|
68
|
+
error: RequestError;
|
|
69
|
+
timings?: Timings;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
Message for the `got:response:redirect` diagnostic channel.
|
|
73
|
+
|
|
74
|
+
Emitted when following a redirect.
|
|
75
|
+
*/
|
|
76
|
+
export type DiagnosticResponseRedirect = {
|
|
77
|
+
requestId: RequestId;
|
|
78
|
+
fromUrl: string;
|
|
79
|
+
toUrl: string;
|
|
80
|
+
statusCode: number;
|
|
81
|
+
};
|
|
82
|
+
export declare function generateRequestId(): RequestId;
|
|
83
|
+
export declare function publishRequestCreate(message: DiagnosticRequestCreate): void;
|
|
84
|
+
export declare function publishRequestStart(message: DiagnosticRequestStart): void;
|
|
85
|
+
export declare function publishResponseStart(message: DiagnosticResponseStart): void;
|
|
86
|
+
export declare function publishResponseEnd(message: DiagnosticResponseEnd): void;
|
|
87
|
+
export declare function publishRetry(message: DiagnosticRequestRetry): void;
|
|
88
|
+
export declare function publishError(message: DiagnosticRequestError): void;
|
|
89
|
+
export declare function publishRedirect(message: DiagnosticResponseRedirect): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import diagnosticsChannel from 'node:diagnostics_channel';
|
|
3
|
+
const channels = {
|
|
4
|
+
requestCreate: diagnosticsChannel.channel('got:request:create'),
|
|
5
|
+
requestStart: diagnosticsChannel.channel('got:request:start'),
|
|
6
|
+
responseStart: diagnosticsChannel.channel('got:response:start'),
|
|
7
|
+
responseEnd: diagnosticsChannel.channel('got:response:end'),
|
|
8
|
+
retry: diagnosticsChannel.channel('got:request:retry'),
|
|
9
|
+
error: diagnosticsChannel.channel('got:request:error'),
|
|
10
|
+
redirect: diagnosticsChannel.channel('got:response:redirect'),
|
|
11
|
+
};
|
|
12
|
+
export function generateRequestId() {
|
|
13
|
+
return randomUUID();
|
|
14
|
+
}
|
|
15
|
+
export function publishRequestCreate(message) {
|
|
16
|
+
if (channels.requestCreate.hasSubscribers) {
|
|
17
|
+
channels.requestCreate.publish(message);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function publishRequestStart(message) {
|
|
21
|
+
if (channels.requestStart.hasSubscribers) {
|
|
22
|
+
channels.requestStart.publish(message);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function publishResponseStart(message) {
|
|
26
|
+
if (channels.responseStart.hasSubscribers) {
|
|
27
|
+
channels.responseStart.publish(message);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function publishResponseEnd(message) {
|
|
31
|
+
if (channels.responseEnd.hasSubscribers) {
|
|
32
|
+
channels.responseEnd.publish(message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function publishRetry(message) {
|
|
36
|
+
if (channels.retry.hasSubscribers) {
|
|
37
|
+
channels.retry.publish(message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function publishError(message) {
|
|
41
|
+
if (channels.error.hasSubscribers) {
|
|
42
|
+
channels.error.publish(message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function publishRedirect(message) {
|
|
46
|
+
if (channels.redirect.hasSubscribers) {
|
|
47
|
+
channels.redirect.publish(message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -9,8 +9,9 @@ An error to be thrown when a request fails.
|
|
|
9
9
|
Contains a `code` property with error class code, like `ECONNREFUSED`.
|
|
10
10
|
*/
|
|
11
11
|
export declare class RequestError<T = unknown> extends Error {
|
|
12
|
-
|
|
12
|
+
name: string;
|
|
13
13
|
code: string;
|
|
14
|
+
input?: string;
|
|
14
15
|
stack: string;
|
|
15
16
|
readonly options: Options;
|
|
16
17
|
readonly response?: Response<T>;
|
|
@@ -25,6 +26,8 @@ An error to be thrown when the server redirects you more than ten times.
|
|
|
25
26
|
Includes a `response` property.
|
|
26
27
|
*/
|
|
27
28
|
export declare class MaxRedirectsError extends RequestError {
|
|
29
|
+
name: string;
|
|
30
|
+
code: string;
|
|
28
31
|
readonly response: Response;
|
|
29
32
|
readonly request: Request;
|
|
30
33
|
readonly timings: Timings;
|
|
@@ -35,6 +38,8 @@ An error to be thrown when the server response code is not 2xx nor 3xx if `optio
|
|
|
35
38
|
Includes a `response` property.
|
|
36
39
|
*/
|
|
37
40
|
export declare class HTTPError<T = any> extends RequestError<T> {
|
|
41
|
+
name: string;
|
|
42
|
+
code: string;
|
|
38
43
|
readonly response: Response<T>;
|
|
39
44
|
readonly request: Request;
|
|
40
45
|
readonly timings: Timings;
|
|
@@ -45,6 +50,7 @@ An error to be thrown when a cache method fails.
|
|
|
45
50
|
For example, if the database goes down or there's a filesystem error.
|
|
46
51
|
*/
|
|
47
52
|
export declare class CacheError extends RequestError {
|
|
53
|
+
name: string;
|
|
48
54
|
readonly request: Request;
|
|
49
55
|
constructor(error: Error, request: Request);
|
|
50
56
|
}
|
|
@@ -52,6 +58,7 @@ export declare class CacheError extends RequestError {
|
|
|
52
58
|
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
|
|
53
59
|
*/
|
|
54
60
|
export declare class UploadError extends RequestError {
|
|
61
|
+
name: string;
|
|
55
62
|
readonly request: Request;
|
|
56
63
|
constructor(error: Error, request: Request);
|
|
57
64
|
}
|
|
@@ -60,6 +67,7 @@ An error to be thrown when the request is aborted due to a timeout.
|
|
|
60
67
|
Includes an `event` and `timings` property.
|
|
61
68
|
*/
|
|
62
69
|
export declare class TimeoutError extends RequestError {
|
|
70
|
+
name: string;
|
|
63
71
|
readonly request: Request;
|
|
64
72
|
readonly timings: Timings;
|
|
65
73
|
readonly event: string;
|
|
@@ -69,6 +77,7 @@ export declare class TimeoutError extends RequestError {
|
|
|
69
77
|
An error to be thrown when reading from response stream fails.
|
|
70
78
|
*/
|
|
71
79
|
export declare class ReadError extends RequestError {
|
|
80
|
+
name: string;
|
|
72
81
|
readonly request: Request;
|
|
73
82
|
readonly response: Response;
|
|
74
83
|
readonly timings: Timings;
|
|
@@ -78,12 +87,16 @@ export declare class ReadError extends RequestError {
|
|
|
78
87
|
An error which always triggers a new retry when thrown.
|
|
79
88
|
*/
|
|
80
89
|
export declare class RetryError extends RequestError {
|
|
90
|
+
name: string;
|
|
91
|
+
code: string;
|
|
81
92
|
constructor(request: Request);
|
|
82
93
|
}
|
|
83
94
|
/**
|
|
84
95
|
An error to be thrown when the request is aborted by AbortController.
|
|
85
96
|
*/
|
|
86
97
|
export declare class AbortError extends RequestError {
|
|
98
|
+
name: string;
|
|
99
|
+
code: string;
|
|
87
100
|
constructor(request: Request);
|
|
88
101
|
}
|
|
89
102
|
export {};
|
|
@@ -8,8 +8,9 @@ An error to be thrown when a request fails.
|
|
|
8
8
|
Contains a `code` property with error class code, like `ECONNREFUSED`.
|
|
9
9
|
*/
|
|
10
10
|
export class RequestError extends Error {
|
|
11
|
+
name = 'RequestError';
|
|
12
|
+
code = 'ERR_GOT_REQUEST_ERROR';
|
|
11
13
|
input;
|
|
12
|
-
code;
|
|
13
14
|
stack;
|
|
14
15
|
response;
|
|
15
16
|
request;
|
|
@@ -17,8 +18,9 @@ export class RequestError extends Error {
|
|
|
17
18
|
constructor(message, error, self) {
|
|
18
19
|
super(message, { cause: error });
|
|
19
20
|
Error.captureStackTrace(this, this.constructor);
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
if (error.code) {
|
|
22
|
+
this.code = error.code;
|
|
23
|
+
}
|
|
22
24
|
this.input = error.input;
|
|
23
25
|
if (isRequest(self)) {
|
|
24
26
|
Object.defineProperty(this, 'request', {
|
|
@@ -53,10 +55,10 @@ An error to be thrown when the server redirects you more than ten times.
|
|
|
53
55
|
Includes a `response` property.
|
|
54
56
|
*/
|
|
55
57
|
export class MaxRedirectsError extends RequestError {
|
|
58
|
+
name = 'MaxRedirectsError';
|
|
59
|
+
code = 'ERR_TOO_MANY_REDIRECTS';
|
|
56
60
|
constructor(request) {
|
|
57
61
|
super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
|
|
58
|
-
this.name = 'MaxRedirectsError';
|
|
59
|
-
this.code = 'ERR_TOO_MANY_REDIRECTS';
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
/**
|
|
@@ -66,10 +68,10 @@ Includes a `response` property.
|
|
|
66
68
|
// TODO: Change `HTTPError<T = any>` to `HTTPError<T = unknown>` in the next major version to enforce type usage.
|
|
67
69
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
68
70
|
export class HTTPError extends RequestError {
|
|
71
|
+
name = 'HTTPError';
|
|
72
|
+
code = 'ERR_NON_2XX_3XX_RESPONSE';
|
|
69
73
|
constructor(response) {
|
|
70
|
-
super(`
|
|
71
|
-
this.name = 'HTTPError';
|
|
72
|
-
this.code = 'ERR_NON_2XX_3XX_RESPONSE';
|
|
74
|
+
super(`Request failed with status code ${response.statusCode} (${response.statusMessage}): ${response.request.options.method} ${response.request.options.url.toString()}`, {}, response.request);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
@@ -77,20 +79,24 @@ An error to be thrown when a cache method fails.
|
|
|
77
79
|
For example, if the database goes down or there's a filesystem error.
|
|
78
80
|
*/
|
|
79
81
|
export class CacheError extends RequestError {
|
|
82
|
+
name = 'CacheError';
|
|
80
83
|
constructor(error, request) {
|
|
81
84
|
super(error.message, error, request);
|
|
82
|
-
this.
|
|
83
|
-
|
|
85
|
+
if (this.code === 'ERR_GOT_REQUEST_ERROR') {
|
|
86
|
+
this.code = 'ERR_CACHE_ACCESS';
|
|
87
|
+
}
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
/**
|
|
87
91
|
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
|
|
88
92
|
*/
|
|
89
93
|
export class UploadError extends RequestError {
|
|
94
|
+
name = 'UploadError';
|
|
90
95
|
constructor(error, request) {
|
|
91
96
|
super(error.message, error, request);
|
|
92
|
-
this.
|
|
93
|
-
|
|
97
|
+
if (this.code === 'ERR_GOT_REQUEST_ERROR') {
|
|
98
|
+
this.code = 'ERR_UPLOAD';
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
102
|
/**
|
|
@@ -98,11 +104,11 @@ An error to be thrown when the request is aborted due to a timeout.
|
|
|
98
104
|
Includes an `event` and `timings` property.
|
|
99
105
|
*/
|
|
100
106
|
export class TimeoutError extends RequestError {
|
|
107
|
+
name = 'TimeoutError';
|
|
101
108
|
timings;
|
|
102
109
|
event;
|
|
103
110
|
constructor(error, timings, request) {
|
|
104
111
|
super(error.message, error, request);
|
|
105
|
-
this.name = 'TimeoutError';
|
|
106
112
|
this.event = error.event;
|
|
107
113
|
this.timings = timings;
|
|
108
114
|
}
|
|
@@ -111,29 +117,31 @@ export class TimeoutError extends RequestError {
|
|
|
111
117
|
An error to be thrown when reading from response stream fails.
|
|
112
118
|
*/
|
|
113
119
|
export class ReadError extends RequestError {
|
|
120
|
+
name = 'ReadError';
|
|
114
121
|
constructor(error, request) {
|
|
115
122
|
super(error.message, error, request);
|
|
116
|
-
this.
|
|
117
|
-
|
|
123
|
+
if (this.code === 'ERR_GOT_REQUEST_ERROR') {
|
|
124
|
+
this.code = 'ERR_READING_RESPONSE_STREAM';
|
|
125
|
+
}
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
/**
|
|
121
129
|
An error which always triggers a new retry when thrown.
|
|
122
130
|
*/
|
|
123
131
|
export class RetryError extends RequestError {
|
|
132
|
+
name = 'RetryError';
|
|
133
|
+
code = 'ERR_RETRYING';
|
|
124
134
|
constructor(request) {
|
|
125
135
|
super('Retrying', {}, request);
|
|
126
|
-
this.name = 'RetryError';
|
|
127
|
-
this.code = 'ERR_RETRYING';
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
138
|
/**
|
|
131
139
|
An error to be thrown when the request is aborted by AbortController.
|
|
132
140
|
*/
|
|
133
141
|
export class AbortError extends RequestError {
|
|
142
|
+
name = 'AbortError';
|
|
143
|
+
code = 'ERR_ABORTED';
|
|
134
144
|
constructor(request) {
|
|
135
145
|
super('This operation was aborted.', {}, request);
|
|
136
|
-
this.code = 'ERR_ABORTED';
|
|
137
|
-
this.name = 'AbortError';
|
|
138
146
|
}
|
|
139
147
|
}
|
|
@@ -107,7 +107,8 @@ export default class Request extends Duplex implements RequestEvents<Request> {
|
|
|
107
107
|
private _flushed;
|
|
108
108
|
private _aborted;
|
|
109
109
|
private _expectedContentLength?;
|
|
110
|
-
private
|
|
110
|
+
private _compressedBytesCount?;
|
|
111
|
+
private readonly _requestId;
|
|
111
112
|
private _requestInitialized;
|
|
112
113
|
constructor(url: UrlType, options?: OptionsType, defaults?: DefaultsType);
|
|
113
114
|
flush(): Promise<void>;
|
|
@@ -183,5 +184,9 @@ export default class Request extends Duplex implements RequestEvents<Request> {
|
|
|
183
184
|
*/
|
|
184
185
|
get isFromCache(): boolean | undefined;
|
|
185
186
|
get reusedSocket(): boolean | undefined;
|
|
187
|
+
/**
|
|
188
|
+
Whether the stream is read-only. Returns `true` when `body`, `json`, or `form` options are provided.
|
|
189
|
+
*/
|
|
190
|
+
get isReadonly(): boolean;
|
|
186
191
|
}
|
|
187
192
|
export {};
|