@npy/fetch 0.1.0 → 0.1.1
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/_internal/consts.cjs +4 -0
- package/_internal/consts.js +4 -0
- package/_internal/error-adapters.cjs +146 -0
- package/_internal/error-adapters.js +142 -0
- package/_internal/guards.cjs +24 -0
- package/_internal/guards.js +17 -0
- package/_internal/net.cjs +95 -0
- package/_internal/net.js +92 -0
- package/_internal/promises.cjs +18 -0
- package/_internal/promises.js +18 -0
- package/_internal/streams.cjs +37 -0
- package/_internal/streams.js +36 -0
- package/_virtual/_rolldown/runtime.cjs +23 -0
- package/agent-pool.cjs +78 -0
- package/agent-pool.js +77 -0
- package/agent.cjs +257 -0
- package/agent.js +256 -0
- package/body.cjs +154 -0
- package/body.js +151 -0
- package/dialers/proxy.cjs +49 -0
- package/dialers/proxy.js +48 -0
- package/dialers/tcp.cjs +70 -0
- package/dialers/tcp.js +67 -0
- package/encoding.cjs +95 -0
- package/encoding.js +91 -0
- package/errors.cjs +275 -0
- package/errors.js +259 -0
- package/fetch.cjs +117 -0
- package/fetch.js +115 -0
- package/http-client.cjs +33 -0
- package/http-client.js +33 -0
- package/index.cjs +45 -0
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/index.js +9 -0
- package/io/_utils.cjs +56 -0
- package/io/_utils.js +51 -0
- package/io/buf-writer.cjs +149 -0
- package/io/buf-writer.js +148 -0
- package/io/io.cjs +135 -0
- package/io/io.js +134 -0
- package/io/readers.cjs +377 -0
- package/io/readers.js +373 -0
- package/io/writers.cjs +191 -0
- package/io/writers.js +190 -0
- package/package.json +7 -10
- package/src/_internal/consts.d.cts +3 -0
- package/src/_internal/consts.d.ts +3 -0
- package/src/_internal/error-adapters.d.cts +22 -0
- package/src/_internal/error-adapters.d.ts +22 -0
- package/src/_internal/guards.d.cts +13 -0
- package/src/_internal/guards.d.ts +13 -0
- package/src/_internal/net.d.cts +12 -0
- package/src/_internal/net.d.ts +12 -0
- package/src/_internal/promises.d.cts +1 -0
- package/src/_internal/promises.d.ts +1 -0
- package/src/_internal/streams.d.cts +21 -0
- package/src/_internal/streams.d.ts +21 -0
- package/src/agent-pool.d.cts +2 -0
- package/src/agent-pool.d.ts +2 -0
- package/src/agent.d.cts +3 -0
- package/src/agent.d.ts +3 -0
- package/src/body.d.cts +23 -0
- package/src/body.d.ts +23 -0
- package/src/dialers/index.d.cts +3 -0
- package/src/dialers/index.d.ts +3 -0
- package/src/dialers/proxy.d.cts +19 -0
- package/src/dialers/proxy.d.ts +19 -0
- package/src/dialers/tcp.d.cts +36 -0
- package/src/dialers/tcp.d.ts +36 -0
- package/src/encoding.d.cts +24 -0
- package/src/encoding.d.ts +24 -0
- package/src/errors.d.cts +110 -0
- package/src/errors.d.ts +110 -0
- package/src/fetch.d.cts +36 -0
- package/src/fetch.d.ts +36 -0
- package/src/http-client.d.cts +23 -0
- package/src/http-client.d.ts +23 -0
- package/src/index.d.cts +7 -0
- package/src/index.d.ts +7 -0
- package/src/io/_utils.d.cts +10 -0
- package/src/io/_utils.d.ts +10 -0
- package/src/io/buf-writer.d.cts +13 -0
- package/src/io/buf-writer.d.ts +13 -0
- package/src/io/io.d.cts +5 -0
- package/src/io/io.d.ts +5 -0
- package/src/io/readers.d.cts +199 -0
- package/src/io/readers.d.ts +199 -0
- package/src/io/writers.d.cts +22 -0
- package/src/io/writers.d.ts +22 -0
- package/src/types/agent.d.cts +128 -0
- package/src/types/agent.d.ts +128 -0
- package/src/types/dialer.d.cts +27 -0
- package/src/types/dialer.d.ts +27 -0
- package/src/types/index.d.cts +2 -0
- package/src/types/index.d.ts +2 -0
- package/tests/test-utils.d.cts +8 -0
- package/tests/test-utils.d.ts +8 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const require_errors = require("../errors.cjs");
|
|
2
|
+
//#region src/_internal/error-adapters.ts
|
|
3
|
+
function getErrorChain(error, maxDepth = 8) {
|
|
4
|
+
const chain = [];
|
|
5
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6
|
+
let current = error;
|
|
7
|
+
let depth = 0;
|
|
8
|
+
while (current instanceof Error && depth < maxDepth && !seen.has(current)) {
|
|
9
|
+
const entry = current;
|
|
10
|
+
chain.push(entry);
|
|
11
|
+
seen.add(current);
|
|
12
|
+
current = entry.cause;
|
|
13
|
+
depth += 1;
|
|
14
|
+
}
|
|
15
|
+
return chain;
|
|
16
|
+
}
|
|
17
|
+
function unknownToError(error) {
|
|
18
|
+
if (error instanceof Error) return error;
|
|
19
|
+
if (typeof error === "string") return new Error(error);
|
|
20
|
+
return new Error("Unknown error", { cause: error });
|
|
21
|
+
}
|
|
22
|
+
function isAbortLike(error) {
|
|
23
|
+
if (!error || typeof error !== "object") return false;
|
|
24
|
+
const name = "name" in error ? error.name : void 0;
|
|
25
|
+
return name === "AbortError" || name === "TimeoutError";
|
|
26
|
+
}
|
|
27
|
+
function defaultAbortDomException() {
|
|
28
|
+
return new DOMException("This operation was aborted", "AbortError");
|
|
29
|
+
}
|
|
30
|
+
function getRawAbortReason(signal) {
|
|
31
|
+
return signal?.reason ?? defaultAbortDomException();
|
|
32
|
+
}
|
|
33
|
+
function toAbortCause(signal, fallback) {
|
|
34
|
+
return unknownToError(signal?.reason ?? fallback ?? defaultAbortDomException());
|
|
35
|
+
}
|
|
36
|
+
function isTimeoutReason(reason) {
|
|
37
|
+
return !!reason && typeof reason === "object" && "name" in reason && reason.name === "TimeoutError";
|
|
38
|
+
}
|
|
39
|
+
function looksLikeDecodeError(error) {
|
|
40
|
+
const chain = getErrorChain(error);
|
|
41
|
+
for (const entry of chain) {
|
|
42
|
+
const code = typeof entry.code === "string" ? entry.code.toLowerCase() : "";
|
|
43
|
+
const text = `${entry.name} ${entry.message} ${code}`.toLowerCase();
|
|
44
|
+
if (code === "z_data_error" || code === "z_buf_error" || code === "z_stream_error" || text.includes("decode") || text.includes("decompress") || text.includes("encoding") || text.includes("gzip") || text.includes("deflate") || text.includes("brotli") || text.includes("incorrect header check") || text.includes("invalid block type") || text.includes("invalid distance") || text.includes("invalid stored block") || text.includes("unexpected end of file") || text.includes("unexpected end of stream") || text.includes("header check")) return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
function mapAdvancedConnectError(error, { signal, context, timedOut }) {
|
|
49
|
+
if (error instanceof require_errors.FetchError) return error;
|
|
50
|
+
if (timedOut || isTimeoutReason(signal?.reason)) return new require_errors.ConnectTimeoutError(unknownToError(error), context, "Connection timeout");
|
|
51
|
+
if (signal?.aborted || isAbortLike(error)) return new require_errors.RequestAbortedError(toAbortCause(signal, error), context, "The request was aborted while connecting");
|
|
52
|
+
return new require_errors.ConnectionError(unknownToError(error), context, "Connection failed");
|
|
53
|
+
}
|
|
54
|
+
function mapAdvancedSendError(error, { signal, context, phase }) {
|
|
55
|
+
if (error instanceof require_errors.FetchError) return error;
|
|
56
|
+
if (signal?.aborted || isAbortLike(error)) return new require_errors.RequestAbortedError(toAbortCause(signal, error), context, phase === "body" ? "The request was aborted while reading the response body" : "The request was aborted");
|
|
57
|
+
const cause = unknownToError(error);
|
|
58
|
+
if (phase === "request") return new require_errors.RequestWriteError(cause, context);
|
|
59
|
+
if (phase === "response") return new require_errors.ResponseHeaderError(cause, context);
|
|
60
|
+
if (looksLikeDecodeError(cause)) return new require_errors.ResponseDecodeError(cause, context);
|
|
61
|
+
return new require_errors.ResponseBodyError(cause, context);
|
|
62
|
+
}
|
|
63
|
+
function wrapResponseBodyErrors(response, mapError) {
|
|
64
|
+
const source = response.body;
|
|
65
|
+
if (!source) return response;
|
|
66
|
+
const reader = source.getReader();
|
|
67
|
+
let pending = null;
|
|
68
|
+
const wrapped = new ReadableStream({
|
|
69
|
+
type: "bytes",
|
|
70
|
+
async pull(controller) {
|
|
71
|
+
try {
|
|
72
|
+
const byob = controller.byobRequest;
|
|
73
|
+
if (byob?.view) {
|
|
74
|
+
const target = new Uint8Array(byob.view.buffer, byob.view.byteOffset, byob.view.byteLength);
|
|
75
|
+
if (target.byteLength === 0) {
|
|
76
|
+
byob.respond(0);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let written = 0;
|
|
80
|
+
if (pending && pending.byteLength > 0) {
|
|
81
|
+
const n = Math.min(target.byteLength, pending.byteLength);
|
|
82
|
+
target.set(pending.subarray(0, n), written);
|
|
83
|
+
written += n;
|
|
84
|
+
pending = n === pending.byteLength ? null : pending.subarray(n);
|
|
85
|
+
}
|
|
86
|
+
while (written === 0) {
|
|
87
|
+
const { done, value } = await reader.read();
|
|
88
|
+
if (done) {
|
|
89
|
+
byob.respond(0);
|
|
90
|
+
controller.close();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (!value || value.byteLength === 0) continue;
|
|
94
|
+
const n = Math.min(target.byteLength - written, value.byteLength);
|
|
95
|
+
target.set(value.subarray(0, n), written);
|
|
96
|
+
written += n;
|
|
97
|
+
if (n < value.byteLength) pending = value.subarray(n);
|
|
98
|
+
}
|
|
99
|
+
byob.respond(written);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (pending && pending.byteLength > 0) {
|
|
103
|
+
const chunk = pending;
|
|
104
|
+
pending = null;
|
|
105
|
+
controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const { done, value } = await reader.read();
|
|
109
|
+
if (done) {
|
|
110
|
+
controller.close();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (value && value.byteLength > 0) controller.enqueue(value);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
controller.error(mapError(error));
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
async cancel(reason) {
|
|
119
|
+
pending = null;
|
|
120
|
+
await reader.cancel(reason);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return new Response(wrapped, {
|
|
124
|
+
status: response.status,
|
|
125
|
+
statusText: response.statusText,
|
|
126
|
+
headers: new Headers(response.headers)
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function toWebFetchError(error, signal) {
|
|
130
|
+
if (signal?.aborted) return getRawAbortReason(signal);
|
|
131
|
+
if (error instanceof DOMException || error instanceof TypeError) return error;
|
|
132
|
+
const cause = error instanceof Error ? error : unknownToError(error);
|
|
133
|
+
return new TypeError("fetch failed", { cause });
|
|
134
|
+
}
|
|
135
|
+
function toWebBodyReadError(error, signal) {
|
|
136
|
+
if (signal?.aborted) return getRawAbortReason(signal);
|
|
137
|
+
if (error instanceof DOMException || error instanceof TypeError || error instanceof RangeError) return error;
|
|
138
|
+
const cause = error instanceof Error ? error : unknownToError(error);
|
|
139
|
+
return new TypeError("Failed to read response body", { cause });
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
exports.mapAdvancedConnectError = mapAdvancedConnectError;
|
|
143
|
+
exports.mapAdvancedSendError = mapAdvancedSendError;
|
|
144
|
+
exports.toWebBodyReadError = toWebBodyReadError;
|
|
145
|
+
exports.toWebFetchError = toWebFetchError;
|
|
146
|
+
exports.wrapResponseBodyErrors = wrapResponseBodyErrors;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ConnectTimeoutError, ConnectionError, FetchError, RequestAbortedError, RequestWriteError, ResponseBodyError, ResponseDecodeError, ResponseHeaderError } from "../errors.js";
|
|
2
|
+
//#region src/_internal/error-adapters.ts
|
|
3
|
+
function getErrorChain(error, maxDepth = 8) {
|
|
4
|
+
const chain = [];
|
|
5
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6
|
+
let current = error;
|
|
7
|
+
let depth = 0;
|
|
8
|
+
while (current instanceof Error && depth < maxDepth && !seen.has(current)) {
|
|
9
|
+
const entry = current;
|
|
10
|
+
chain.push(entry);
|
|
11
|
+
seen.add(current);
|
|
12
|
+
current = entry.cause;
|
|
13
|
+
depth += 1;
|
|
14
|
+
}
|
|
15
|
+
return chain;
|
|
16
|
+
}
|
|
17
|
+
function unknownToError(error) {
|
|
18
|
+
if (error instanceof Error) return error;
|
|
19
|
+
if (typeof error === "string") return new Error(error);
|
|
20
|
+
return new Error("Unknown error", { cause: error });
|
|
21
|
+
}
|
|
22
|
+
function isAbortLike(error) {
|
|
23
|
+
if (!error || typeof error !== "object") return false;
|
|
24
|
+
const name = "name" in error ? error.name : void 0;
|
|
25
|
+
return name === "AbortError" || name === "TimeoutError";
|
|
26
|
+
}
|
|
27
|
+
function defaultAbortDomException() {
|
|
28
|
+
return new DOMException("This operation was aborted", "AbortError");
|
|
29
|
+
}
|
|
30
|
+
function getRawAbortReason(signal) {
|
|
31
|
+
return signal?.reason ?? defaultAbortDomException();
|
|
32
|
+
}
|
|
33
|
+
function toAbortCause(signal, fallback) {
|
|
34
|
+
return unknownToError(signal?.reason ?? fallback ?? defaultAbortDomException());
|
|
35
|
+
}
|
|
36
|
+
function isTimeoutReason(reason) {
|
|
37
|
+
return !!reason && typeof reason === "object" && "name" in reason && reason.name === "TimeoutError";
|
|
38
|
+
}
|
|
39
|
+
function looksLikeDecodeError(error) {
|
|
40
|
+
const chain = getErrorChain(error);
|
|
41
|
+
for (const entry of chain) {
|
|
42
|
+
const code = typeof entry.code === "string" ? entry.code.toLowerCase() : "";
|
|
43
|
+
const text = `${entry.name} ${entry.message} ${code}`.toLowerCase();
|
|
44
|
+
if (code === "z_data_error" || code === "z_buf_error" || code === "z_stream_error" || text.includes("decode") || text.includes("decompress") || text.includes("encoding") || text.includes("gzip") || text.includes("deflate") || text.includes("brotli") || text.includes("incorrect header check") || text.includes("invalid block type") || text.includes("invalid distance") || text.includes("invalid stored block") || text.includes("unexpected end of file") || text.includes("unexpected end of stream") || text.includes("header check")) return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
function mapAdvancedConnectError(error, { signal, context, timedOut }) {
|
|
49
|
+
if (error instanceof FetchError) return error;
|
|
50
|
+
if (timedOut || isTimeoutReason(signal?.reason)) return new ConnectTimeoutError(unknownToError(error), context, "Connection timeout");
|
|
51
|
+
if (signal?.aborted || isAbortLike(error)) return new RequestAbortedError(toAbortCause(signal, error), context, "The request was aborted while connecting");
|
|
52
|
+
return new ConnectionError(unknownToError(error), context, "Connection failed");
|
|
53
|
+
}
|
|
54
|
+
function mapAdvancedSendError(error, { signal, context, phase }) {
|
|
55
|
+
if (error instanceof FetchError) return error;
|
|
56
|
+
if (signal?.aborted || isAbortLike(error)) return new RequestAbortedError(toAbortCause(signal, error), context, phase === "body" ? "The request was aborted while reading the response body" : "The request was aborted");
|
|
57
|
+
const cause = unknownToError(error);
|
|
58
|
+
if (phase === "request") return new RequestWriteError(cause, context);
|
|
59
|
+
if (phase === "response") return new ResponseHeaderError(cause, context);
|
|
60
|
+
if (looksLikeDecodeError(cause)) return new ResponseDecodeError(cause, context);
|
|
61
|
+
return new ResponseBodyError(cause, context);
|
|
62
|
+
}
|
|
63
|
+
function wrapResponseBodyErrors(response, mapError) {
|
|
64
|
+
const source = response.body;
|
|
65
|
+
if (!source) return response;
|
|
66
|
+
const reader = source.getReader();
|
|
67
|
+
let pending = null;
|
|
68
|
+
const wrapped = new ReadableStream({
|
|
69
|
+
type: "bytes",
|
|
70
|
+
async pull(controller) {
|
|
71
|
+
try {
|
|
72
|
+
const byob = controller.byobRequest;
|
|
73
|
+
if (byob?.view) {
|
|
74
|
+
const target = new Uint8Array(byob.view.buffer, byob.view.byteOffset, byob.view.byteLength);
|
|
75
|
+
if (target.byteLength === 0) {
|
|
76
|
+
byob.respond(0);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let written = 0;
|
|
80
|
+
if (pending && pending.byteLength > 0) {
|
|
81
|
+
const n = Math.min(target.byteLength, pending.byteLength);
|
|
82
|
+
target.set(pending.subarray(0, n), written);
|
|
83
|
+
written += n;
|
|
84
|
+
pending = n === pending.byteLength ? null : pending.subarray(n);
|
|
85
|
+
}
|
|
86
|
+
while (written === 0) {
|
|
87
|
+
const { done, value } = await reader.read();
|
|
88
|
+
if (done) {
|
|
89
|
+
byob.respond(0);
|
|
90
|
+
controller.close();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (!value || value.byteLength === 0) continue;
|
|
94
|
+
const n = Math.min(target.byteLength - written, value.byteLength);
|
|
95
|
+
target.set(value.subarray(0, n), written);
|
|
96
|
+
written += n;
|
|
97
|
+
if (n < value.byteLength) pending = value.subarray(n);
|
|
98
|
+
}
|
|
99
|
+
byob.respond(written);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (pending && pending.byteLength > 0) {
|
|
103
|
+
const chunk = pending;
|
|
104
|
+
pending = null;
|
|
105
|
+
controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const { done, value } = await reader.read();
|
|
109
|
+
if (done) {
|
|
110
|
+
controller.close();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (value && value.byteLength > 0) controller.enqueue(value);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
controller.error(mapError(error));
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
async cancel(reason) {
|
|
119
|
+
pending = null;
|
|
120
|
+
await reader.cancel(reason);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return new Response(wrapped, {
|
|
124
|
+
status: response.status,
|
|
125
|
+
statusText: response.statusText,
|
|
126
|
+
headers: new Headers(response.headers)
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function toWebFetchError(error, signal) {
|
|
130
|
+
if (signal?.aborted) return getRawAbortReason(signal);
|
|
131
|
+
if (error instanceof DOMException || error instanceof TypeError) return error;
|
|
132
|
+
const cause = error instanceof Error ? error : unknownToError(error);
|
|
133
|
+
return new TypeError("fetch failed", { cause });
|
|
134
|
+
}
|
|
135
|
+
function toWebBodyReadError(error, signal) {
|
|
136
|
+
if (signal?.aborted) return getRawAbortReason(signal);
|
|
137
|
+
if (error instanceof DOMException || error instanceof TypeError || error instanceof RangeError) return error;
|
|
138
|
+
const cause = error instanceof Error ? error : unknownToError(error);
|
|
139
|
+
return new TypeError("Failed to read response body", { cause });
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
export { mapAdvancedConnectError, mapAdvancedSendError, toWebBodyReadError, toWebFetchError, wrapResponseBodyErrors };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let node_stream = require("node:stream");
|
|
3
|
+
//#region src/_internal/guards.ts
|
|
4
|
+
var isReadable = (object) => node_stream.Readable.isReadable(object);
|
|
5
|
+
var isIterable = (object) => typeof object?.[Symbol.asyncIterator] === "function" || typeof object?.[Symbol.iterator] === "function";
|
|
6
|
+
var isMultipartFormDataStream = (object) => typeof object?.getBoundary === "function" && typeof object?.hasKnownLength === "function" && typeof object?.getLengthSync === "function" && node_stream.Readable.isReadable(object);
|
|
7
|
+
var isFormData = (object) => typeof object === "object" && typeof object?.append === "function" && typeof object?.set === "function" && typeof object?.get === "function" && typeof object?.getAll === "function" && typeof object?.delete === "function" && typeof object?.keys === "function" && typeof object?.values === "function" && typeof object?.entries === "function" && typeof object?.constructor === "function" && object?.[Symbol.toStringTag] === "FormData";
|
|
8
|
+
var isURLSearchParameters = (object) => typeof object === "object" && typeof object?.append === "function" && typeof object?.delete === "function" && typeof object?.get === "function" && typeof object?.getAll === "function" && typeof object?.has === "function" && typeof object?.set === "function" && typeof object?.sort === "function" && object?.[Symbol.toStringTag] === "URLSearchParams";
|
|
9
|
+
var isReadableStream = (object) => typeof object === "object" && typeof object?.getReader === "function" && typeof object?.cancel === "function" && typeof object?.tee === "function";
|
|
10
|
+
var isBlob = (object) => {
|
|
11
|
+
if (typeof object === "object" && typeof object?.arrayBuffer === "function" && typeof object?.type === "string" && typeof object?.stream === "function" && typeof object?.constructor === "function") {
|
|
12
|
+
const tag = object[Symbol.toStringTag];
|
|
13
|
+
return typeof tag === "string" && (tag.startsWith("Blob") || tag.startsWith("File"));
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.isBlob = isBlob;
|
|
19
|
+
exports.isFormData = isFormData;
|
|
20
|
+
exports.isIterable = isIterable;
|
|
21
|
+
exports.isMultipartFormDataStream = isMultipartFormDataStream;
|
|
22
|
+
exports.isReadable = isReadable;
|
|
23
|
+
exports.isReadableStream = isReadableStream;
|
|
24
|
+
exports.isURLSearchParameters = isURLSearchParameters;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
//#region src/_internal/guards.ts
|
|
3
|
+
var isReadable = (object) => Readable.isReadable(object);
|
|
4
|
+
var isIterable = (object) => typeof object?.[Symbol.asyncIterator] === "function" || typeof object?.[Symbol.iterator] === "function";
|
|
5
|
+
var isMultipartFormDataStream = (object) => typeof object?.getBoundary === "function" && typeof object?.hasKnownLength === "function" && typeof object?.getLengthSync === "function" && Readable.isReadable(object);
|
|
6
|
+
var isFormData = (object) => typeof object === "object" && typeof object?.append === "function" && typeof object?.set === "function" && typeof object?.get === "function" && typeof object?.getAll === "function" && typeof object?.delete === "function" && typeof object?.keys === "function" && typeof object?.values === "function" && typeof object?.entries === "function" && typeof object?.constructor === "function" && object?.[Symbol.toStringTag] === "FormData";
|
|
7
|
+
var isURLSearchParameters = (object) => typeof object === "object" && typeof object?.append === "function" && typeof object?.delete === "function" && typeof object?.get === "function" && typeof object?.getAll === "function" && typeof object?.has === "function" && typeof object?.set === "function" && typeof object?.sort === "function" && object?.[Symbol.toStringTag] === "URLSearchParams";
|
|
8
|
+
var isReadableStream = (object) => typeof object === "object" && typeof object?.getReader === "function" && typeof object?.cancel === "function" && typeof object?.tee === "function";
|
|
9
|
+
var isBlob = (object) => {
|
|
10
|
+
if (typeof object === "object" && typeof object?.arrayBuffer === "function" && typeof object?.type === "string" && typeof object?.stream === "function" && typeof object?.constructor === "function") {
|
|
11
|
+
const tag = object[Symbol.toStringTag];
|
|
12
|
+
return typeof tag === "string" && (tag.startsWith("Blob") || tag.startsWith("File"));
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { isBlob, isFormData, isIterable, isMultipartFormDataStream, isReadable, isReadableStream, isURLSearchParameters };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let node_net = require("node:net");
|
|
3
|
+
let node_tls = require("node:tls");
|
|
4
|
+
let _fuman_node = require("@fuman/node");
|
|
5
|
+
//#region src/_internal/net.ts
|
|
6
|
+
function toAbortError(reason) {
|
|
7
|
+
if (reason instanceof Error && reason.name === "AbortError") return reason;
|
|
8
|
+
const message = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "The operation was aborted";
|
|
9
|
+
if (typeof DOMException !== "undefined") return new DOMException(message, "AbortError");
|
|
10
|
+
const error = new Error(message);
|
|
11
|
+
error.name = "AbortError";
|
|
12
|
+
return error;
|
|
13
|
+
}
|
|
14
|
+
function throwIfAborted(signal) {
|
|
15
|
+
if (signal?.aborted) throw toAbortError(signal.reason);
|
|
16
|
+
}
|
|
17
|
+
async function withSocketSignal(createSocket, wrapConnection, signal, readyEvent = "connect", onFailureCleanup) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
throwIfAborted(signal);
|
|
20
|
+
const socket = createSocket();
|
|
21
|
+
let settled = false;
|
|
22
|
+
const cleanup = () => {
|
|
23
|
+
socket.removeListener("error", onError);
|
|
24
|
+
socket.removeListener("timeout", onError);
|
|
25
|
+
socket.removeListener(readyEvent, onReady);
|
|
26
|
+
signal?.removeEventListener("abort", onAbort);
|
|
27
|
+
};
|
|
28
|
+
const safeCleanup = () => {
|
|
29
|
+
try {
|
|
30
|
+
onFailureCleanup?.();
|
|
31
|
+
} catch {}
|
|
32
|
+
};
|
|
33
|
+
const resolveOnce = (value) => {
|
|
34
|
+
if (settled) return;
|
|
35
|
+
settled = true;
|
|
36
|
+
cleanup();
|
|
37
|
+
resolve(value);
|
|
38
|
+
};
|
|
39
|
+
const rejectOnce = (error) => {
|
|
40
|
+
if (settled) return;
|
|
41
|
+
settled = true;
|
|
42
|
+
cleanup();
|
|
43
|
+
reject(error);
|
|
44
|
+
};
|
|
45
|
+
const onError = (error) => {
|
|
46
|
+
safeCleanup();
|
|
47
|
+
rejectOnce(error);
|
|
48
|
+
};
|
|
49
|
+
const onAbort = () => {
|
|
50
|
+
const error = toAbortError(signal?.reason);
|
|
51
|
+
safeCleanup();
|
|
52
|
+
rejectOnce(error);
|
|
53
|
+
try {
|
|
54
|
+
socket.destroy(error);
|
|
55
|
+
} catch {}
|
|
56
|
+
};
|
|
57
|
+
const onReady = () => {
|
|
58
|
+
resolveOnce(wrapConnection(socket));
|
|
59
|
+
};
|
|
60
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
61
|
+
socket.on("error", onError);
|
|
62
|
+
socket.on("timeout", onError);
|
|
63
|
+
socket.on(readyEvent, onReady);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
var connectTcp = async ({ address, port, signal }) => {
|
|
67
|
+
return withSocketSignal(() => (0, node_net.createConnection)({
|
|
68
|
+
host: address,
|
|
69
|
+
port
|
|
70
|
+
}), (socket) => new _fuman_node.TcpConnection(socket), signal);
|
|
71
|
+
};
|
|
72
|
+
var connectTls = async (options) => {
|
|
73
|
+
const { address, port, signal, sni, caCerts, alpnProtocols, extraOptions } = options;
|
|
74
|
+
return withSocketSignal(() => (0, node_tls.connect)({
|
|
75
|
+
host: address,
|
|
76
|
+
port,
|
|
77
|
+
ca: caCerts,
|
|
78
|
+
ALPNProtocols: alpnProtocols,
|
|
79
|
+
servername: sni,
|
|
80
|
+
...extraOptions
|
|
81
|
+
}), (socket) => new _fuman_node.TlsConnection(socket), signal, "secureConnect");
|
|
82
|
+
};
|
|
83
|
+
var upgradeTls = async (conn, options) => {
|
|
84
|
+
return withSocketSignal(() => (0, node_tls.connect)({
|
|
85
|
+
socket: conn.socket,
|
|
86
|
+
ca: options.caCerts,
|
|
87
|
+
ALPNProtocols: options.alpnProtocols,
|
|
88
|
+
servername: options.sni,
|
|
89
|
+
...options.extraOptions
|
|
90
|
+
}), (socket) => new _fuman_node.TlsConnection(socket), options.signal, "secureConnect", () => conn.close());
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
exports.connectTcp = connectTcp;
|
|
94
|
+
exports.connectTls = connectTls;
|
|
95
|
+
exports.upgradeTls = upgradeTls;
|
package/_internal/net.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createConnection } from "node:net";
|
|
2
|
+
import { connect } from "node:tls";
|
|
3
|
+
import { TcpConnection, TlsConnection } from "@fuman/node";
|
|
4
|
+
//#region src/_internal/net.ts
|
|
5
|
+
function toAbortError(reason) {
|
|
6
|
+
if (reason instanceof Error && reason.name === "AbortError") return reason;
|
|
7
|
+
const message = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "The operation was aborted";
|
|
8
|
+
if (typeof DOMException !== "undefined") return new DOMException(message, "AbortError");
|
|
9
|
+
const error = new Error(message);
|
|
10
|
+
error.name = "AbortError";
|
|
11
|
+
return error;
|
|
12
|
+
}
|
|
13
|
+
function throwIfAborted(signal) {
|
|
14
|
+
if (signal?.aborted) throw toAbortError(signal.reason);
|
|
15
|
+
}
|
|
16
|
+
async function withSocketSignal(createSocket, wrapConnection, signal, readyEvent = "connect", onFailureCleanup) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
throwIfAborted(signal);
|
|
19
|
+
const socket = createSocket();
|
|
20
|
+
let settled = false;
|
|
21
|
+
const cleanup = () => {
|
|
22
|
+
socket.removeListener("error", onError);
|
|
23
|
+
socket.removeListener("timeout", onError);
|
|
24
|
+
socket.removeListener(readyEvent, onReady);
|
|
25
|
+
signal?.removeEventListener("abort", onAbort);
|
|
26
|
+
};
|
|
27
|
+
const safeCleanup = () => {
|
|
28
|
+
try {
|
|
29
|
+
onFailureCleanup?.();
|
|
30
|
+
} catch {}
|
|
31
|
+
};
|
|
32
|
+
const resolveOnce = (value) => {
|
|
33
|
+
if (settled) return;
|
|
34
|
+
settled = true;
|
|
35
|
+
cleanup();
|
|
36
|
+
resolve(value);
|
|
37
|
+
};
|
|
38
|
+
const rejectOnce = (error) => {
|
|
39
|
+
if (settled) return;
|
|
40
|
+
settled = true;
|
|
41
|
+
cleanup();
|
|
42
|
+
reject(error);
|
|
43
|
+
};
|
|
44
|
+
const onError = (error) => {
|
|
45
|
+
safeCleanup();
|
|
46
|
+
rejectOnce(error);
|
|
47
|
+
};
|
|
48
|
+
const onAbort = () => {
|
|
49
|
+
const error = toAbortError(signal?.reason);
|
|
50
|
+
safeCleanup();
|
|
51
|
+
rejectOnce(error);
|
|
52
|
+
try {
|
|
53
|
+
socket.destroy(error);
|
|
54
|
+
} catch {}
|
|
55
|
+
};
|
|
56
|
+
const onReady = () => {
|
|
57
|
+
resolveOnce(wrapConnection(socket));
|
|
58
|
+
};
|
|
59
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
60
|
+
socket.on("error", onError);
|
|
61
|
+
socket.on("timeout", onError);
|
|
62
|
+
socket.on(readyEvent, onReady);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
var connectTcp = async ({ address, port, signal }) => {
|
|
66
|
+
return withSocketSignal(() => createConnection({
|
|
67
|
+
host: address,
|
|
68
|
+
port
|
|
69
|
+
}), (socket) => new TcpConnection(socket), signal);
|
|
70
|
+
};
|
|
71
|
+
var connectTls = async (options) => {
|
|
72
|
+
const { address, port, signal, sni, caCerts, alpnProtocols, extraOptions } = options;
|
|
73
|
+
return withSocketSignal(() => connect({
|
|
74
|
+
host: address,
|
|
75
|
+
port,
|
|
76
|
+
ca: caCerts,
|
|
77
|
+
ALPNProtocols: alpnProtocols,
|
|
78
|
+
servername: sni,
|
|
79
|
+
...extraOptions
|
|
80
|
+
}), (socket) => new TlsConnection(socket), signal, "secureConnect");
|
|
81
|
+
};
|
|
82
|
+
var upgradeTls = async (conn, options) => {
|
|
83
|
+
return withSocketSignal(() => connect({
|
|
84
|
+
socket: conn.socket,
|
|
85
|
+
ca: options.caCerts,
|
|
86
|
+
ALPNProtocols: options.alpnProtocols,
|
|
87
|
+
servername: options.sni,
|
|
88
|
+
...options.extraOptions
|
|
89
|
+
}), (socket) => new TlsConnection(socket), options.signal, "secureConnect", () => conn.close());
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
export { connectTcp, connectTls, upgradeTls };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/_internal/promises.ts
|
|
2
|
+
function raceSignal(promise, signal) {
|
|
3
|
+
return Promise.race([promise, new Promise((_, reject) => {
|
|
4
|
+
function onAbort() {
|
|
5
|
+
reject(signal.reason);
|
|
6
|
+
}
|
|
7
|
+
if (signal.aborted) onAbort();
|
|
8
|
+
else {
|
|
9
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
10
|
+
function cleanup() {
|
|
11
|
+
signal.removeEventListener("abort", onAbort);
|
|
12
|
+
}
|
|
13
|
+
promise.then(cleanup, cleanup);
|
|
14
|
+
}
|
|
15
|
+
})]);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.raceSignal = raceSignal;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/_internal/promises.ts
|
|
2
|
+
function raceSignal(promise, signal) {
|
|
3
|
+
return Promise.race([promise, new Promise((_, reject) => {
|
|
4
|
+
function onAbort() {
|
|
5
|
+
reject(signal.reason);
|
|
6
|
+
}
|
|
7
|
+
if (signal.aborted) onAbort();
|
|
8
|
+
else {
|
|
9
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
10
|
+
function cleanup() {
|
|
11
|
+
signal.removeEventListener("abort", onAbort);
|
|
12
|
+
}
|
|
13
|
+
promise.then(cleanup, cleanup);
|
|
14
|
+
}
|
|
15
|
+
})]);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { raceSignal };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/_internal/streams.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create a ReadableStream from a Uint8Array.
|
|
4
|
+
*
|
|
5
|
+
* The stream will emit the entire byte array as a single chunk,
|
|
6
|
+
* then close immediately.
|
|
7
|
+
*
|
|
8
|
+
* @param bytes - The byte array to wrap.
|
|
9
|
+
* @returns A ReadableStream that emits the bytes.
|
|
10
|
+
*/
|
|
11
|
+
function bytesToStream(bytes) {
|
|
12
|
+
return new ReadableStream({ start(controller) {
|
|
13
|
+
controller.enqueue(bytes);
|
|
14
|
+
controller.close();
|
|
15
|
+
} });
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A TransformStream that limits the total number of bytes passed through.
|
|
19
|
+
*
|
|
20
|
+
* It accumulates the byte count from incoming chunks and enqueues them
|
|
21
|
+
* if the total remains within the limit; otherwise, it errors.
|
|
22
|
+
*
|
|
23
|
+
* @param maxBytes - The maximum allowed bytes before erroring.
|
|
24
|
+
*/
|
|
25
|
+
var MaxBytesTransformStream = class extends TransformStream {
|
|
26
|
+
constructor(maxBytes) {
|
|
27
|
+
if (!(maxBytes >= 0)) throw new TypeError("maxBytes must be a non-negative number");
|
|
28
|
+
let bytesRead = 0;
|
|
29
|
+
super({ transform: (chunk, ctrl) => {
|
|
30
|
+
if ((bytesRead += chunk.length) <= maxBytes) ctrl.enqueue(chunk);
|
|
31
|
+
else ctrl.error(/* @__PURE__ */ new Error("Response too large"));
|
|
32
|
+
} });
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.MaxBytesTransformStream = MaxBytesTransformStream;
|
|
37
|
+
exports.bytesToStream = bytesToStream;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/_internal/streams.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create a ReadableStream from a Uint8Array.
|
|
4
|
+
*
|
|
5
|
+
* The stream will emit the entire byte array as a single chunk,
|
|
6
|
+
* then close immediately.
|
|
7
|
+
*
|
|
8
|
+
* @param bytes - The byte array to wrap.
|
|
9
|
+
* @returns A ReadableStream that emits the bytes.
|
|
10
|
+
*/
|
|
11
|
+
function bytesToStream(bytes) {
|
|
12
|
+
return new ReadableStream({ start(controller) {
|
|
13
|
+
controller.enqueue(bytes);
|
|
14
|
+
controller.close();
|
|
15
|
+
} });
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A TransformStream that limits the total number of bytes passed through.
|
|
19
|
+
*
|
|
20
|
+
* It accumulates the byte count from incoming chunks and enqueues them
|
|
21
|
+
* if the total remains within the limit; otherwise, it errors.
|
|
22
|
+
*
|
|
23
|
+
* @param maxBytes - The maximum allowed bytes before erroring.
|
|
24
|
+
*/
|
|
25
|
+
var MaxBytesTransformStream = class extends TransformStream {
|
|
26
|
+
constructor(maxBytes) {
|
|
27
|
+
if (!(maxBytes >= 0)) throw new TypeError("maxBytes must be a non-negative number");
|
|
28
|
+
let bytesRead = 0;
|
|
29
|
+
super({ transform: (chunk, ctrl) => {
|
|
30
|
+
if ((bytesRead += chunk.length) <= maxBytes) ctrl.enqueue(chunk);
|
|
31
|
+
else ctrl.error(/* @__PURE__ */ new Error("Response too large"));
|
|
32
|
+
} });
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { MaxBytesTransformStream, bytesToStream };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.__toESM = __toESM;
|