mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 11:04:06 +00:00
refactor: share browser client request helpers
This commit is contained in:
@@ -15,6 +15,54 @@ export type { BrowserDoctorCheck, BrowserDoctorReport } from "./doctor.js";
|
||||
const BROWSER_STATUS_REQUEST_TIMEOUT_MS = 7_500;
|
||||
const BROWSER_DOCTOR_REQUEST_TIMEOUT_MS = 7_500;
|
||||
const BROWSER_DEEP_DOCTOR_REQUEST_TIMEOUT_MS = 10_000;
|
||||
const JSON_HEADERS = { "Content-Type": "application/json" };
|
||||
|
||||
type BrowserClientTimeoutOptions = {
|
||||
timeoutMs?: number;
|
||||
};
|
||||
|
||||
type BrowserClientProfileOptions = BrowserClientTimeoutOptions & {
|
||||
profile?: string;
|
||||
};
|
||||
|
||||
function resolveBrowserClientTimeoutMs(
|
||||
opts: BrowserClientTimeoutOptions | undefined,
|
||||
fallbackMs: number,
|
||||
): number {
|
||||
return typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: fallbackMs;
|
||||
}
|
||||
|
||||
function withProfilePath(baseUrl: string | undefined, path: string, profile?: string): string {
|
||||
return withBaseUrl(baseUrl, `${path}${buildProfileQuery(profile)}`);
|
||||
}
|
||||
|
||||
async function sendProfilePost(
|
||||
baseUrl: string | undefined,
|
||||
path: string,
|
||||
opts: BrowserClientProfileOptions | undefined,
|
||||
fallbackTimeoutMs: number,
|
||||
): Promise<void> {
|
||||
await fetchBrowserJson(withProfilePath(baseUrl, path, opts?.profile), {
|
||||
method: "POST",
|
||||
timeoutMs: resolveBrowserClientTimeoutMs(opts, fallbackTimeoutMs),
|
||||
});
|
||||
}
|
||||
|
||||
async function sendTabTargetRequest(params: {
|
||||
baseUrl: string | undefined;
|
||||
path: string;
|
||||
method: "POST" | "DELETE";
|
||||
opts: BrowserClientProfileOptions | undefined;
|
||||
body?: object;
|
||||
}): Promise<void> {
|
||||
await fetchBrowserJson(withProfilePath(params.baseUrl, params.path, params.opts?.profile), {
|
||||
method: params.method,
|
||||
...(params.body ? { headers: JSON_HEADERS, body: JSON.stringify(params.body) } : {}),
|
||||
timeoutMs: resolveBrowserClientTimeoutMs(params.opts, 5000),
|
||||
});
|
||||
}
|
||||
|
||||
export type ProfileStatus = {
|
||||
name: string;
|
||||
@@ -75,12 +123,8 @@ export async function browserStatus(
|
||||
baseUrl?: string,
|
||||
opts?: { profile?: string; timeoutMs?: number },
|
||||
): Promise<BrowserStatus> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
return await fetchBrowserJson<BrowserStatus>(withBaseUrl(baseUrl, `/${q}`), {
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: BROWSER_STATUS_REQUEST_TIMEOUT_MS,
|
||||
return await fetchBrowserJson<BrowserStatus>(withProfilePath(baseUrl, "/", opts?.profile), {
|
||||
timeoutMs: resolveBrowserClientTimeoutMs(opts, BROWSER_STATUS_REQUEST_TIMEOUT_MS),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,10 +154,7 @@ export async function browserProfiles(
|
||||
const res = await fetchBrowserJson<{ profiles: ProfileStatus[] }>(
|
||||
withBaseUrl(baseUrl, `/profiles`),
|
||||
{
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 3000,
|
||||
timeoutMs: resolveBrowserClientTimeoutMs(opts, 3000),
|
||||
},
|
||||
);
|
||||
return res.profiles ?? [];
|
||||
@@ -123,28 +164,14 @@ export async function browserStart(
|
||||
baseUrl?: string,
|
||||
opts?: { profile?: string; timeoutMs?: number },
|
||||
): Promise<void> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
await fetchBrowserJson(withBaseUrl(baseUrl, `/start${q}`), {
|
||||
method: "POST",
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 15000,
|
||||
});
|
||||
await sendProfilePost(baseUrl, "/start", opts, 15000);
|
||||
}
|
||||
|
||||
export async function browserStop(
|
||||
baseUrl?: string,
|
||||
opts?: { profile?: string; timeoutMs?: number },
|
||||
): Promise<void> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
await fetchBrowserJson(withBaseUrl(baseUrl, `/stop${q}`), {
|
||||
method: "POST",
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 15000,
|
||||
});
|
||||
await sendProfilePost(baseUrl, "/stop", opts, 15000);
|
||||
}
|
||||
|
||||
export async function browserResetProfile(
|
||||
@@ -186,7 +213,7 @@ export async function browserCreateProfile(
|
||||
withBaseUrl(baseUrl, `/profiles/create`),
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: JSON_HEADERS,
|
||||
body: JSON.stringify({
|
||||
name: opts.name,
|
||||
color: opts.color,
|
||||
@@ -222,14 +249,10 @@ export async function browserTabs(
|
||||
baseUrl?: string,
|
||||
opts?: { profile?: string; timeoutMs?: number },
|
||||
): Promise<BrowserTab[]> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
const res = await fetchBrowserJson<{ running: boolean; tabs: BrowserTab[] }>(
|
||||
withBaseUrl(baseUrl, `/tabs${q}`),
|
||||
withProfilePath(baseUrl, "/tabs", opts?.profile),
|
||||
{
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 3000,
|
||||
timeoutMs: resolveBrowserClientTimeoutMs(opts, 3000),
|
||||
},
|
||||
);
|
||||
return res.tabs ?? [];
|
||||
@@ -240,15 +263,11 @@ export async function browserOpenTab(
|
||||
url: string,
|
||||
opts?: { profile?: string; label?: string; timeoutMs?: number },
|
||||
): Promise<BrowserTab> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
return await fetchBrowserJson<BrowserTab>(withBaseUrl(baseUrl, `/tabs/open${q}`), {
|
||||
return await fetchBrowserJson<BrowserTab>(withProfilePath(baseUrl, "/tabs/open", opts?.profile), {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: JSON_HEADERS,
|
||||
body: JSON.stringify({ url, ...(opts?.label ? { label: opts.label } : {}) }),
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 15000,
|
||||
timeoutMs: resolveBrowserClientTimeoutMs(opts, 15000),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,16 +276,8 @@ export async function browserFocusTab(
|
||||
targetId: string,
|
||||
opts?: { profile?: string; timeoutMs?: number },
|
||||
): Promise<void> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
await fetchBrowserJson(withBaseUrl(baseUrl, `/tabs/focus${q}`), {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ targetId }),
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 5000,
|
||||
});
|
||||
const body = { targetId };
|
||||
await sendTabTargetRequest({ baseUrl, path: "/tabs/focus", method: "POST", opts, body });
|
||||
}
|
||||
|
||||
export async function browserCloseTab(
|
||||
@@ -274,14 +285,8 @@ export async function browserCloseTab(
|
||||
targetId: string,
|
||||
opts?: { profile?: string; timeoutMs?: number },
|
||||
): Promise<void> {
|
||||
const q = buildProfileQuery(opts?.profile);
|
||||
await fetchBrowserJson(withBaseUrl(baseUrl, `/tabs/${encodeURIComponent(targetId)}${q}`), {
|
||||
method: "DELETE",
|
||||
timeoutMs:
|
||||
typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(1, Math.floor(opts.timeoutMs))
|
||||
: 5000,
|
||||
});
|
||||
const path = `/tabs/${encodeURIComponent(targetId)}`;
|
||||
await sendTabTargetRequest({ baseUrl, path, method: "DELETE", opts });
|
||||
}
|
||||
|
||||
export async function browserTabAction(
|
||||
|
||||
Reference in New Issue
Block a user