Spaces:
Paused
Paused
| import type { | |
| BrowserActionOk, | |
| BrowserActionPathResult, | |
| BrowserActionTabResult, | |
| } from "./client-actions-types.js"; | |
| import { fetchBrowserJson } from "./client-fetch.js"; | |
| function buildProfileQuery(profile?: string): string { | |
| return profile ? `?profile=${encodeURIComponent(profile)}` : ""; | |
| } | |
| function withBaseUrl(baseUrl: string | undefined, path: string): string { | |
| const trimmed = baseUrl?.trim(); | |
| if (!trimmed) { | |
| return path; | |
| } | |
| return `${trimmed.replace(/\/$/, "")}${path}`; | |
| } | |
| export type BrowserFormField = { | |
| ref: string; | |
| type: string; | |
| value?: string | number | boolean; | |
| }; | |
| export type BrowserActRequest = | |
| | { | |
| kind: "click"; | |
| ref: string; | |
| targetId?: string; | |
| doubleClick?: boolean; | |
| button?: string; | |
| modifiers?: string[]; | |
| timeoutMs?: number; | |
| } | |
| | { | |
| kind: "type"; | |
| ref: string; | |
| text: string; | |
| targetId?: string; | |
| submit?: boolean; | |
| slowly?: boolean; | |
| timeoutMs?: number; | |
| } | |
| | { kind: "press"; key: string; targetId?: string; delayMs?: number } | |
| | { kind: "hover"; ref: string; targetId?: string; timeoutMs?: number } | |
| | { | |
| kind: "scrollIntoView"; | |
| ref: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| } | |
| | { | |
| kind: "drag"; | |
| startRef: string; | |
| endRef: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| } | |
| | { | |
| kind: "select"; | |
| ref: string; | |
| values: string[]; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| } | |
| | { | |
| kind: "fill"; | |
| fields: BrowserFormField[]; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| } | |
| | { kind: "resize"; width: number; height: number; targetId?: string } | |
| | { | |
| kind: "wait"; | |
| timeMs?: number; | |
| text?: string; | |
| textGone?: string; | |
| selector?: string; | |
| url?: string; | |
| loadState?: "load" | "domcontentloaded" | "networkidle"; | |
| fn?: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| } | |
| | { kind: "evaluate"; fn: string; ref?: string; targetId?: string } | |
| | { kind: "close"; targetId?: string }; | |
| export type BrowserActResponse = { | |
| ok: true; | |
| targetId: string; | |
| url?: string; | |
| result?: unknown; | |
| }; | |
| export type BrowserDownloadPayload = { | |
| url: string; | |
| suggestedFilename: string; | |
| path: string; | |
| }; | |
| export async function browserNavigate( | |
| baseUrl: string | undefined, | |
| opts: { | |
| url: string; | |
| targetId?: string; | |
| profile?: string; | |
| }, | |
| ): Promise<BrowserActionTabResult> { | |
| const q = buildProfileQuery(opts.profile); | |
| return await fetchBrowserJson<BrowserActionTabResult>(withBaseUrl(baseUrl, `/navigate${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ url: opts.url, targetId: opts.targetId }), | |
| timeoutMs: 20000, | |
| }); | |
| } | |
| export async function browserArmDialog( | |
| baseUrl: string | undefined, | |
| opts: { | |
| accept: boolean; | |
| promptText?: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| profile?: string; | |
| }, | |
| ): Promise<BrowserActionOk> { | |
| const q = buildProfileQuery(opts.profile); | |
| return await fetchBrowserJson<BrowserActionOk>(withBaseUrl(baseUrl, `/hooks/dialog${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| accept: opts.accept, | |
| promptText: opts.promptText, | |
| targetId: opts.targetId, | |
| timeoutMs: opts.timeoutMs, | |
| }), | |
| timeoutMs: 20000, | |
| }); | |
| } | |
| export async function browserArmFileChooser( | |
| baseUrl: string | undefined, | |
| opts: { | |
| paths: string[]; | |
| ref?: string; | |
| inputRef?: string; | |
| element?: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| profile?: string; | |
| }, | |
| ): Promise<BrowserActionOk> { | |
| const q = buildProfileQuery(opts.profile); | |
| return await fetchBrowserJson<BrowserActionOk>(withBaseUrl(baseUrl, `/hooks/file-chooser${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| paths: opts.paths, | |
| ref: opts.ref, | |
| inputRef: opts.inputRef, | |
| element: opts.element, | |
| targetId: opts.targetId, | |
| timeoutMs: opts.timeoutMs, | |
| }), | |
| timeoutMs: 20000, | |
| }); | |
| } | |
| export async function browserWaitForDownload( | |
| baseUrl: string | undefined, | |
| opts: { | |
| path?: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| profile?: string; | |
| }, | |
| ): Promise<{ ok: true; targetId: string; download: BrowserDownloadPayload }> { | |
| const q = buildProfileQuery(opts.profile); | |
| return await fetchBrowserJson<{ | |
| ok: true; | |
| targetId: string; | |
| download: BrowserDownloadPayload; | |
| }>(withBaseUrl(baseUrl, `/wait/download${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| targetId: opts.targetId, | |
| path: opts.path, | |
| timeoutMs: opts.timeoutMs, | |
| }), | |
| timeoutMs: 20000, | |
| }); | |
| } | |
| export async function browserDownload( | |
| baseUrl: string | undefined, | |
| opts: { | |
| ref: string; | |
| path: string; | |
| targetId?: string; | |
| timeoutMs?: number; | |
| profile?: string; | |
| }, | |
| ): Promise<{ ok: true; targetId: string; download: BrowserDownloadPayload }> { | |
| const q = buildProfileQuery(opts.profile); | |
| return await fetchBrowserJson<{ | |
| ok: true; | |
| targetId: string; | |
| download: BrowserDownloadPayload; | |
| }>(withBaseUrl(baseUrl, `/download${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| targetId: opts.targetId, | |
| ref: opts.ref, | |
| path: opts.path, | |
| timeoutMs: opts.timeoutMs, | |
| }), | |
| timeoutMs: 20000, | |
| }); | |
| } | |
| export async function browserAct( | |
| baseUrl: string | undefined, | |
| req: BrowserActRequest, | |
| opts?: { profile?: string }, | |
| ): Promise<BrowserActResponse> { | |
| const q = buildProfileQuery(opts?.profile); | |
| return await fetchBrowserJson<BrowserActResponse>(withBaseUrl(baseUrl, `/act${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(req), | |
| timeoutMs: 20000, | |
| }); | |
| } | |
| export async function browserScreenshotAction( | |
| baseUrl: string | undefined, | |
| opts: { | |
| targetId?: string; | |
| fullPage?: boolean; | |
| ref?: string; | |
| element?: string; | |
| type?: "png" | "jpeg"; | |
| profile?: string; | |
| }, | |
| ): Promise<BrowserActionPathResult> { | |
| const q = buildProfileQuery(opts.profile); | |
| return await fetchBrowserJson<BrowserActionPathResult>(withBaseUrl(baseUrl, `/screenshot${q}`), { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| targetId: opts.targetId, | |
| fullPage: opts.fullPage, | |
| ref: opts.ref, | |
| element: opts.element, | |
| type: opts.type, | |
| }), | |
| timeoutMs: 20000, | |
| }); | |
| } | |