refactor(core): migrate to Bun and converge acquisition policies and Agent boundaries

This commit is contained in:
root committed 2026-10-13 14:37:03 +08:00
1 parent 3f1c6d02f6
commit 27c0f27434
268 files changed
+7468 -7852

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@ export interface BraveClientOptions {
baseUrl?: string;
/** 缺省 10s */
timeoutMs?: number;
fetch?: typeof fetch;
fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
}
export interface BraveSearchParams {
+1 -1
View File
@@ -18,7 +18,7 @@ export interface FetchPageOptions {
/** 最多跟随几次重定向,缺省 3 */
maxRedirects?: number;
userAgent?: string;
fetch?: typeof fetch;
fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
resolve?: HostResolver;
signal?: AbortSignal;
}
@@ -41,7 +41,7 @@ describe("Brave 客户端", () => {
fetch: (async (url: string, init: RequestInit) => {
seen = { url, headers: new Headers(init.headers) };
return jsonRes(BRAVE_BODY);
}) as typeof fetch,
}) as (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>,
});
const r = await c.search({
q: "MoviePilot v3",
@@ -85,8 +85,10 @@ describe("Brave 客户端", () => {
])("HTTP %i → %s,错误信息不含 Key", async (status, kind) => {
const c = createBraveClient({
apiKey: KEY,
fetch: (async () =>
jsonRes({ error: `bad token ${KEY}` }, status, { "x-ratelimit-reset": "1, 1000" })) as typeof fetch,
fetch: (async () => jsonRes({ error: `bad token ${KEY}` }, status, { "x-ratelimit-reset": "1, 1000" })) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
});
const err = (await c.search({ q: "x", count: 1 }).catch((e) => e)) as WebSearchError;
expect(err).toBeInstanceOf(WebSearchError);
@@ -100,7 +102,7 @@ describe("Brave 客户端", () => {
apiKey: KEY,
fetch: (async () => {
throw new TypeError(`connect fail ${KEY}`);
}) as typeof fetch,
}) as (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>,
});
const e1 = (await net.search({ q: "x", count: 1 }).catch((e) => e)) as WebSearchError;
expect(e1.kind).toBe("network");
@@ -109,9 +111,10 @@ describe("Brave 客户端", () => {
apiKey: KEY,
timeoutMs: 50,
fetch: ((_u: string, init: RequestInit) =>
new Promise((_r, rej) =>
init.signal?.addEventListener("abort", () => rej(new Error("aborted"))),
)) as typeof fetch,
new Promise((_r, rej) => init.signal?.addEventListener("abort", () => rej(new Error("aborted"))))) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
});
expect(((await slow.search({ q: "x", count: 1 }).catch((e) => e)) as WebSearchError).kind).toBe("timeout");
});
@@ -164,8 +167,10 @@ describe("读取网页", () => {
it("HTML 转纯文本:去脚本样式表单,保留标题与段落,URL 凭证脱敏", async () => {
const p = await fetchPage("https://example.org/notice", {
resolve: publicDns,
fetch: (async () =>
new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } })) as typeof fetch,
fetch: (async () => new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } })) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
});
expect(p.title).toBe("站点公告");
expect(p.text).toContain("9 月 20 日维护。");
@@ -180,7 +185,10 @@ describe("读取网页", () => {
const big = "a".repeat(600 * 1024);
const p = await fetchPage("https://example.org/big.txt", {
resolve: publicDns,
fetch: (async () => new Response(big, { headers: { "content-type": "text/plain" } })) as typeof fetch,
fetch: (async () => new Response(big, { headers: { "content-type": "text/plain" } })) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
});
expect(p.bytes).toBe(512 * 1024);
expect(p.truncated).toBe(true);
@@ -190,22 +198,28 @@ describe("读取网页", () => {
it("非文本类型拒绝;重定向到内网拒绝;超时", async () => {
const pdf = await fetchPage("https://example.org/a.pdf", {
resolve: publicDns,
fetch: (async () => new Response("%PDF", { headers: { "content-type": "application/pdf" } })) as typeof fetch,
fetch: (async () => new Response("%PDF", { headers: { "content-type": "application/pdf" } })) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
}).catch((e) => e);
expect((pdf as WebSearchError).kind).toBe("unsupported");
const redir = await fetchPage("https://example.org/r", {
resolve: publicDns,
fetch: (async () =>
new Response(null, { status: 302, headers: { location: "http://192.168.1.1/admin" } })) as typeof fetch,
fetch: (async () => new Response(null, { status: 302, headers: { location: "http://192.168.1.1/admin" } })) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
}).catch((e) => e);
expect((redir as WebSearchError).kind).toBe("blocked");
const slow = await fetchPage("https://example.org/slow", {
resolve: publicDns,
timeoutMs: 50,
fetch: ((_u: string, init: RequestInit) =>
new Promise((_r, rej) =>
init.signal?.addEventListener("abort", () => rej(new Error("aborted"))),
)) as typeof fetch,
new Promise((_r, rej) => init.signal?.addEventListener("abort", () => rej(new Error("aborted"))))) as (
input: RequestInfo | URL,
init?: RequestInit,
) => Promise<Response>,
}).catch((e) => e);
expect((slow as WebSearchError).kind).toBe("timeout");
});