@npy/fetch 0.1.2 → 0.1.3
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/README.md +143 -50
- package/bun.lock +68 -0
- package/examples/custom-proxy-client.ts +32 -0
- package/examples/http-client.ts +47 -0
- package/examples/proxy.ts +16 -0
- package/examples/simple.ts +15 -0
- package/package.json +25 -30
- package/src/_internal/consts.ts +3 -0
- package/{_internal/decode-stream-error.d.cts → src/_internal/decode-stream-error.ts} +7 -2
- package/src/_internal/error-mapping.ts +160 -0
- package/src/_internal/guards.ts +78 -0
- package/src/_internal/net.ts +173 -0
- package/src/_internal/promises.ts +22 -0
- package/src/_internal/streams.ts +52 -0
- package/src/_internal/symbols.ts +1 -0
- package/src/agent-pool.ts +157 -0
- package/src/agent.ts +408 -0
- package/src/body.ts +179 -0
- package/src/dialers/index.ts +3 -0
- package/src/dialers/proxy.ts +102 -0
- package/src/dialers/tcp.ts +162 -0
- package/src/encoding.ts +222 -0
- package/src/errors.ts +357 -0
- package/src/fetch.ts +626 -0
- package/src/http-client.ts +111 -0
- package/src/index.ts +14 -0
- package/src/io/_utils.ts +82 -0
- package/src/io/buf-writer.ts +183 -0
- package/src/io/io.ts +322 -0
- package/src/io/readers.ts +576 -0
- package/src/io/writers.ts +331 -0
- package/{types/agent.d.cts → src/types/agent.ts} +47 -21
- package/{types/dialer.d.cts → src/types/dialer.ts} +19 -9
- package/src/types/index.ts +2 -0
- package/tests/agent-pool.test.ts +111 -0
- package/tests/agent.test.ts +134 -0
- package/tests/body.test.ts +228 -0
- package/tests/errors.test.ts +152 -0
- package/tests/fetch.test.ts +421 -0
- package/tests/io-options.test.ts +127 -0
- package/tests/multipart.test.ts +348 -0
- package/tests/test-utils.ts +335 -0
- package/tsconfig.json +15 -0
- package/LICENSE +0 -21
- package/_internal/consts.cjs +0 -4
- package/_internal/consts.d.cts +0 -3
- package/_internal/consts.d.ts +0 -3
- package/_internal/consts.js +0 -4
- package/_internal/decode-stream-error.cjs +0 -18
- package/_internal/decode-stream-error.d.ts +0 -11
- package/_internal/decode-stream-error.js +0 -18
- package/_internal/error-mapping.cjs +0 -44
- package/_internal/error-mapping.d.cts +0 -15
- package/_internal/error-mapping.d.ts +0 -15
- package/_internal/error-mapping.js +0 -41
- package/_internal/guards.cjs +0 -23
- package/_internal/guards.d.cts +0 -15
- package/_internal/guards.d.ts +0 -15
- package/_internal/guards.js +0 -15
- package/_internal/net.cjs +0 -95
- package/_internal/net.d.cts +0 -11
- package/_internal/net.d.ts +0 -11
- package/_internal/net.js +0 -92
- package/_internal/promises.cjs +0 -18
- package/_internal/promises.d.cts +0 -1
- package/_internal/promises.d.ts +0 -1
- package/_internal/promises.js +0 -18
- package/_internal/streams.cjs +0 -37
- package/_internal/streams.d.cts +0 -21
- package/_internal/streams.d.ts +0 -21
- package/_internal/streams.js +0 -36
- package/_internal/symbols.cjs +0 -4
- package/_internal/symbols.d.cts +0 -1
- package/_internal/symbols.d.ts +0 -1
- package/_internal/symbols.js +0 -4
- package/_virtual/_rolldown/runtime.cjs +0 -23
- package/agent-pool.cjs +0 -96
- package/agent-pool.d.cts +0 -2
- package/agent-pool.d.ts +0 -2
- package/agent-pool.js +0 -95
- package/agent.cjs +0 -260
- package/agent.d.cts +0 -3
- package/agent.d.ts +0 -3
- package/agent.js +0 -259
- package/body.cjs +0 -105
- package/body.d.cts +0 -12
- package/body.d.ts +0 -12
- package/body.js +0 -102
- package/dialers/index.d.cts +0 -3
- package/dialers/index.d.ts +0 -3
- package/dialers/proxy.cjs +0 -56
- package/dialers/proxy.d.cts +0 -27
- package/dialers/proxy.d.ts +0 -27
- package/dialers/proxy.js +0 -55
- package/dialers/tcp.cjs +0 -92
- package/dialers/tcp.d.cts +0 -57
- package/dialers/tcp.d.ts +0 -57
- package/dialers/tcp.js +0 -89
- package/encoding.cjs +0 -114
- package/encoding.d.cts +0 -35
- package/encoding.d.ts +0 -35
- package/encoding.js +0 -110
- package/errors.cjs +0 -275
- package/errors.d.cts +0 -110
- package/errors.d.ts +0 -110
- package/errors.js +0 -259
- package/fetch.cjs +0 -353
- package/fetch.d.cts +0 -58
- package/fetch.d.ts +0 -58
- package/fetch.js +0 -350
- package/http-client.cjs +0 -75
- package/http-client.d.cts +0 -39
- package/http-client.d.ts +0 -39
- package/http-client.js +0 -75
- package/index.cjs +0 -49
- package/index.d.cts +0 -14
- package/index.d.ts +0 -14
- package/index.js +0 -11
- package/io/_utils.cjs +0 -56
- package/io/_utils.d.cts +0 -10
- package/io/_utils.d.ts +0 -10
- package/io/_utils.js +0 -51
- package/io/buf-writer.cjs +0 -149
- package/io/buf-writer.d.cts +0 -13
- package/io/buf-writer.d.ts +0 -13
- package/io/buf-writer.js +0 -148
- package/io/io.cjs +0 -199
- package/io/io.d.cts +0 -5
- package/io/io.d.ts +0 -5
- package/io/io.js +0 -198
- package/io/readers.cjs +0 -337
- package/io/readers.d.cts +0 -69
- package/io/readers.d.ts +0 -69
- package/io/readers.js +0 -333
- package/io/writers.cjs +0 -196
- package/io/writers.d.cts +0 -22
- package/io/writers.d.ts +0 -22
- package/io/writers.js +0 -195
- package/types/agent.d.ts +0 -72
- package/types/dialer.d.ts +0 -30
- package/types/index.d.cts +0 -2
- package/types/index.d.ts +0 -2
package/src/errors.ts
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
export const ErrorType = {
|
|
2
|
+
ABORTED: "ABORTED",
|
|
3
|
+
NETWORK: "NETWORK",
|
|
4
|
+
TIMEOUT: "TIMEOUT",
|
|
5
|
+
HTTP_CLIENT_ERROR: "HTTP_CLIENT_ERROR",
|
|
6
|
+
HTTP_SERVER_ERROR: "HTTP_SERVER_ERROR",
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export type ErrorType = (typeof ErrorType)[keyof typeof ErrorType];
|
|
10
|
+
|
|
11
|
+
export const FetchErrorCode = {
|
|
12
|
+
ABORTED: "ERR_FETCH_ABORTED",
|
|
13
|
+
TIMEOUT: "ERR_FETCH_TIMEOUT",
|
|
14
|
+
CONNECTION: "ERR_FETCH_CONNECTION",
|
|
15
|
+
AGENT_CLOSED: "ERR_FETCH_AGENT_CLOSED",
|
|
16
|
+
AGENT_BUSY: "ERR_FETCH_AGENT_BUSY",
|
|
17
|
+
ORIGIN_MISMATCH: "ERR_FETCH_ORIGIN_MISMATCH",
|
|
18
|
+
UNSUPPORTED_PROTOCOL: "ERR_FETCH_UNSUPPORTED_PROTOCOL",
|
|
19
|
+
UNSUPPORTED_METHOD: "ERR_FETCH_UNSUPPORTED_METHOD",
|
|
20
|
+
TLS_ALPN: "ERR_FETCH_TLS_ALPN",
|
|
21
|
+
REQUEST_WRITE: "ERR_FETCH_REQUEST_WRITE",
|
|
22
|
+
RESPONSE_HEADERS: "ERR_FETCH_RESPONSE_HEADERS",
|
|
23
|
+
RESPONSE_BODY: "ERR_FETCH_RESPONSE_BODY",
|
|
24
|
+
RESPONSE_DECODE: "ERR_FETCH_RESPONSE_DECODE",
|
|
25
|
+
HTTP_STATUS: "ERR_FETCH_HTTP_STATUS",
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
export type FetchErrorCode =
|
|
29
|
+
(typeof FetchErrorCode)[keyof typeof FetchErrorCode];
|
|
30
|
+
|
|
31
|
+
export type FetchErrorPhase =
|
|
32
|
+
| "agent"
|
|
33
|
+
| "connect"
|
|
34
|
+
| "request"
|
|
35
|
+
| "response"
|
|
36
|
+
| "body"
|
|
37
|
+
| "decode"
|
|
38
|
+
| "policy";
|
|
39
|
+
|
|
40
|
+
export interface FetchErrorContext {
|
|
41
|
+
url?: string;
|
|
42
|
+
method?: string;
|
|
43
|
+
origin?: string;
|
|
44
|
+
scheme?: string;
|
|
45
|
+
host?: string;
|
|
46
|
+
port?: number;
|
|
47
|
+
status?: number;
|
|
48
|
+
alpn?: string | null;
|
|
49
|
+
details?: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface FetchErrorOptions {
|
|
53
|
+
message: string;
|
|
54
|
+
code: FetchErrorCode;
|
|
55
|
+
phase: FetchErrorPhase;
|
|
56
|
+
cause?: unknown;
|
|
57
|
+
context?: FetchErrorContext;
|
|
58
|
+
retryable?: boolean;
|
|
59
|
+
type?: ErrorType;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class FetchError extends Error {
|
|
63
|
+
readonly code: FetchErrorCode;
|
|
64
|
+
readonly phase: FetchErrorPhase;
|
|
65
|
+
readonly context?: FetchErrorContext;
|
|
66
|
+
readonly retryable: boolean;
|
|
67
|
+
readonly type?: ErrorType;
|
|
68
|
+
override readonly cause: unknown;
|
|
69
|
+
|
|
70
|
+
constructor(options: FetchErrorOptions) {
|
|
71
|
+
super(options.message, { cause: options.cause });
|
|
72
|
+
this.code = options.code;
|
|
73
|
+
this.phase = options.phase;
|
|
74
|
+
this.context = options.context;
|
|
75
|
+
this.retryable = options.retryable ?? false;
|
|
76
|
+
this.type = options.type;
|
|
77
|
+
this.cause = options.cause;
|
|
78
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
override get name(): string {
|
|
82
|
+
return (this.constructor as typeof Error).name;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get [Symbol.toStringTag](): string {
|
|
86
|
+
return this.name;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
toJSON() {
|
|
90
|
+
return {
|
|
91
|
+
name: this.name,
|
|
92
|
+
message: this.message,
|
|
93
|
+
code: this.code,
|
|
94
|
+
phase: this.phase,
|
|
95
|
+
retryable: this.retryable,
|
|
96
|
+
type: this.type,
|
|
97
|
+
context: this.context,
|
|
98
|
+
cause:
|
|
99
|
+
this.cause instanceof Error
|
|
100
|
+
? {
|
|
101
|
+
name: this.cause.name,
|
|
102
|
+
message: this.cause.message,
|
|
103
|
+
}
|
|
104
|
+
: this.cause,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export class RequestAbortedError extends FetchError {
|
|
110
|
+
constructor(
|
|
111
|
+
cause?: unknown,
|
|
112
|
+
context?: FetchErrorContext,
|
|
113
|
+
message?: string,
|
|
114
|
+
) {
|
|
115
|
+
super({
|
|
116
|
+
message: message ?? "The request was aborted",
|
|
117
|
+
code: FetchErrorCode.ABORTED,
|
|
118
|
+
phase: "request",
|
|
119
|
+
cause,
|
|
120
|
+
context,
|
|
121
|
+
retryable: false,
|
|
122
|
+
type: ErrorType.ABORTED,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export class ConnectTimeoutError extends FetchError {
|
|
128
|
+
constructor(
|
|
129
|
+
cause?: unknown,
|
|
130
|
+
context?: FetchErrorContext,
|
|
131
|
+
message?: string,
|
|
132
|
+
) {
|
|
133
|
+
super({
|
|
134
|
+
message: message ?? "Connection timed out",
|
|
135
|
+
code: FetchErrorCode.TIMEOUT,
|
|
136
|
+
phase: "connect",
|
|
137
|
+
cause,
|
|
138
|
+
context,
|
|
139
|
+
retryable: true,
|
|
140
|
+
type: ErrorType.TIMEOUT,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export class ConnectionError extends FetchError {
|
|
146
|
+
constructor(
|
|
147
|
+
cause?: unknown,
|
|
148
|
+
context?: FetchErrorContext,
|
|
149
|
+
message?: string,
|
|
150
|
+
) {
|
|
151
|
+
super({
|
|
152
|
+
message: message ?? "Network connection failed",
|
|
153
|
+
code: FetchErrorCode.CONNECTION,
|
|
154
|
+
phase: "connect",
|
|
155
|
+
cause,
|
|
156
|
+
context,
|
|
157
|
+
retryable: true,
|
|
158
|
+
type: ErrorType.NETWORK,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export class AgentClosedError extends FetchError {
|
|
164
|
+
constructor(context?: FetchErrorContext, cause?: unknown) {
|
|
165
|
+
super({
|
|
166
|
+
message: "Agent is closed",
|
|
167
|
+
code: FetchErrorCode.AGENT_CLOSED,
|
|
168
|
+
phase: "agent",
|
|
169
|
+
cause,
|
|
170
|
+
context,
|
|
171
|
+
retryable: false,
|
|
172
|
+
type: ErrorType.NETWORK,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export class AgentBusyError extends FetchError {
|
|
178
|
+
constructor(context?: FetchErrorContext, cause?: unknown) {
|
|
179
|
+
super({
|
|
180
|
+
message: "Agent is busy",
|
|
181
|
+
code: FetchErrorCode.AGENT_BUSY,
|
|
182
|
+
phase: "agent",
|
|
183
|
+
cause,
|
|
184
|
+
context,
|
|
185
|
+
retryable: true,
|
|
186
|
+
type: ErrorType.NETWORK,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export class OriginMismatchError extends FetchError {
|
|
192
|
+
constructor(
|
|
193
|
+
expectedOrigin: string,
|
|
194
|
+
actualOrigin: string,
|
|
195
|
+
context?: FetchErrorContext,
|
|
196
|
+
) {
|
|
197
|
+
super({
|
|
198
|
+
message: `Agent origin mismatch: expected ${expectedOrigin}, got ${actualOrigin}`,
|
|
199
|
+
code: FetchErrorCode.ORIGIN_MISMATCH,
|
|
200
|
+
phase: "policy",
|
|
201
|
+
context: {
|
|
202
|
+
...context,
|
|
203
|
+
details: {
|
|
204
|
+
...(context?.details ?? {}),
|
|
205
|
+
expectedOrigin,
|
|
206
|
+
actualOrigin,
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
retryable: false,
|
|
210
|
+
type: ErrorType.NETWORK,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export class UnsupportedProtocolError extends FetchError {
|
|
216
|
+
constructor(protocol: string, context?: FetchErrorContext) {
|
|
217
|
+
super({
|
|
218
|
+
message: `Unsupported protocol: ${protocol}`,
|
|
219
|
+
code: FetchErrorCode.UNSUPPORTED_PROTOCOL,
|
|
220
|
+
phase: "policy",
|
|
221
|
+
context,
|
|
222
|
+
retryable: false,
|
|
223
|
+
type: ErrorType.NETWORK,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export class UnsupportedMethodError extends FetchError {
|
|
229
|
+
constructor(method: string, context?: FetchErrorContext) {
|
|
230
|
+
super({
|
|
231
|
+
message: `Unsupported method: ${method}`,
|
|
232
|
+
code: FetchErrorCode.UNSUPPORTED_METHOD,
|
|
233
|
+
phase: "policy",
|
|
234
|
+
context,
|
|
235
|
+
retryable: false,
|
|
236
|
+
type: ErrorType.NETWORK,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export class UnsupportedAlpnProtocolError extends FetchError {
|
|
242
|
+
constructor(alpn: string, context?: FetchErrorContext, cause?: unknown) {
|
|
243
|
+
super({
|
|
244
|
+
message: `Unsupported ALPN protocol negotiated: ${alpn}`,
|
|
245
|
+
code: FetchErrorCode.TLS_ALPN,
|
|
246
|
+
phase: "connect",
|
|
247
|
+
cause,
|
|
248
|
+
context: {
|
|
249
|
+
...context,
|
|
250
|
+
alpn,
|
|
251
|
+
},
|
|
252
|
+
retryable: false,
|
|
253
|
+
type: ErrorType.NETWORK,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export class RequestWriteError extends FetchError {
|
|
259
|
+
constructor(
|
|
260
|
+
cause?: unknown,
|
|
261
|
+
context?: FetchErrorContext,
|
|
262
|
+
message?: string,
|
|
263
|
+
) {
|
|
264
|
+
super({
|
|
265
|
+
message: message ?? "Failed to write HTTP request",
|
|
266
|
+
code: FetchErrorCode.REQUEST_WRITE,
|
|
267
|
+
phase: "request",
|
|
268
|
+
cause,
|
|
269
|
+
context,
|
|
270
|
+
retryable: true,
|
|
271
|
+
type: ErrorType.NETWORK,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export class ResponseHeaderError extends FetchError {
|
|
277
|
+
constructor(
|
|
278
|
+
cause?: unknown,
|
|
279
|
+
context?: FetchErrorContext,
|
|
280
|
+
message?: string,
|
|
281
|
+
) {
|
|
282
|
+
super({
|
|
283
|
+
message: message ?? "Failed while reading response headers",
|
|
284
|
+
code: FetchErrorCode.RESPONSE_HEADERS,
|
|
285
|
+
phase: "response",
|
|
286
|
+
cause,
|
|
287
|
+
context,
|
|
288
|
+
retryable: true,
|
|
289
|
+
type: ErrorType.NETWORK,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export class ResponseBodyError extends FetchError {
|
|
295
|
+
constructor(
|
|
296
|
+
cause?: unknown,
|
|
297
|
+
context?: FetchErrorContext,
|
|
298
|
+
message?: string,
|
|
299
|
+
) {
|
|
300
|
+
super({
|
|
301
|
+
message: message ?? "Failed while reading response body",
|
|
302
|
+
code: FetchErrorCode.RESPONSE_BODY,
|
|
303
|
+
phase: "body",
|
|
304
|
+
cause,
|
|
305
|
+
context,
|
|
306
|
+
retryable: true,
|
|
307
|
+
type: ErrorType.NETWORK,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export class ResponseDecodeError extends FetchError {
|
|
313
|
+
constructor(
|
|
314
|
+
cause?: unknown,
|
|
315
|
+
context?: FetchErrorContext,
|
|
316
|
+
message?: string,
|
|
317
|
+
) {
|
|
318
|
+
super({
|
|
319
|
+
message: message ?? "Failed while decoding response body",
|
|
320
|
+
code: FetchErrorCode.RESPONSE_DECODE,
|
|
321
|
+
phase: "decode",
|
|
322
|
+
cause,
|
|
323
|
+
context,
|
|
324
|
+
retryable: false,
|
|
325
|
+
type: ErrorType.NETWORK,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export class HttpStatusError extends FetchError {
|
|
331
|
+
readonly statusCode: number;
|
|
332
|
+
|
|
333
|
+
constructor(
|
|
334
|
+
statusCode: number,
|
|
335
|
+
context?: FetchErrorContext,
|
|
336
|
+
cause?: unknown,
|
|
337
|
+
message?: string,
|
|
338
|
+
) {
|
|
339
|
+
super({
|
|
340
|
+
message: message ?? `HTTP ${statusCode}`,
|
|
341
|
+
code: FetchErrorCode.HTTP_STATUS,
|
|
342
|
+
phase: "response",
|
|
343
|
+
cause,
|
|
344
|
+
context: {
|
|
345
|
+
...context,
|
|
346
|
+
status: statusCode,
|
|
347
|
+
},
|
|
348
|
+
retryable: statusCode >= 500,
|
|
349
|
+
type:
|
|
350
|
+
statusCode < 500
|
|
351
|
+
? ErrorType.HTTP_CLIENT_ERROR
|
|
352
|
+
: ErrorType.HTTP_SERVER_ERROR,
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
this.statusCode = statusCode;
|
|
356
|
+
}
|
|
357
|
+
}
|