UNPKG

browse

Version:

Unified Browserbase CLI for browser automation and cloud APIs.

136 lines (135 loc) 4.97 kB
import { isDeepStrictEqual } from "node:util"; import { fail } from "../errors.js"; import { getRemote } from "./remote-binding.js"; import { resolveWsTarget } from "./resolve-ws.js"; function resolveHeadless(flags) { if (flags.headed && flags.headless) { fail("Pass either --headed or --headless, not both."); } if (flags.headed) return false; if (flags.headless) return true; return true; } export function hasChromeArgFlags(flags) { return chromeArgFlagsInUse(flags).length > 0; } function chromeArgFlagsInUse(flags) { const names = []; if (flags["chrome-arg"]?.length) names.push("--chrome-arg"); if (flags["ignore-default-chrome-arg"]?.length) names.push("--ignore-default-chrome-arg"); if (flags["no-default-chrome-args"]) names.push("--no-default-chrome-args"); return names; } export async function resolveConnectionTarget(flags) { const chromeArgFlags = chromeArgFlagsInUse(flags); if (flags.cdp) { failOnConflictingFlags("--cdp", [ flags["auto-connect"] ? "--auto-connect" : null, ...chromeArgFlags, flags.local ? "--local" : null, flags.remote ? "--remote" : null, flags.headed ? "--headed" : null, flags.headless ? "--headless" : null, ]); return { kind: "cdp", endpoint: await resolveWsTarget(flags.cdp), targetId: flags["target-id"], }; } if (flags["target-id"]) { fail("--target-id requires --cdp."); } if (flags["auto-connect"]) { failOnConflictingFlags("--auto-connect", [ ...chromeArgFlags, flags.local ? "--local" : null, flags.remote ? "--remote" : null, flags.headed ? "--headed" : null, flags.headless ? "--headless" : null, ]); return { kind: "auto-connect" }; } if (flags.local && flags.remote) { fail("Pass either --local or --remote, not both."); } if (flags.remote) { failOnConflictingFlags("--remote", [ ...chromeArgFlags, flags.headed ? "--headed" : null, flags.headless ? "--headless" : null, ]); return (await getRemote()).resolveExplicitRemoteTarget(flags); } if (flags.local) { return managedLocalTarget(resolveHeadless(flags), resolveChromeArgs(flags)); } const autoRemote = (await getRemote()).autoSelectRemoteTarget(); if (autoRemote) { failOnConflictingFlags("remote mode", [ ...chromeArgFlags, flags.headed ? "--headed" : null, flags.headless ? "--headless" : null, ]); return autoRemote; } return managedLocalTarget(resolveHeadless(flags), resolveChromeArgs(flags)); } function managedLocalTarget(headless, chromeArgs) { return { ...(chromeArgs.args?.length ? { chromeArgs: chromeArgs.args } : {}), ...(chromeArgs.ignoreDefaultArgs !== undefined ? { ignoreDefaultArgs: chromeArgs.ignoreDefaultArgs } : {}), kind: "managed-local", headless, }; } function failOnConflictingFlags(flag, candidates) { const conflicts = candidates.filter((candidate) => Boolean(candidate)); if (conflicts.length > 0) fail(`${flag} cannot be combined with ${conflicts.join(", ")}.`); } function resolveChromeArgs(flags) { const args = flags["chrome-arg"]?.filter((arg) => arg.length > 0); const ignoreDefaults = flags["ignore-default-chrome-arg"]?.filter((arg) => arg.length > 0); const noDefaults = flags["no-default-chrome-args"] === true; if (noDefaults && ignoreDefaults?.length) { fail("--no-default-chrome-args cannot be combined with --ignore-default-chrome-arg."); } const resolved = {}; if (args?.length) resolved.args = args; if (noDefaults) { resolved.ignoreDefaultArgs = true; } else if (ignoreDefaults?.length) { resolved.ignoreDefaultArgs = ignoreDefaults; } return resolved; } export function targetsCompatible(left, right) { if (left.kind !== right.kind) return false; if (left.kind === "managed-local" && right.kind === "managed-local") return (left.headless === right.headless && chromeArgsEqual(left.chromeArgs, right.chromeArgs) && ignoreDefaultArgsEqual(left.ignoreDefaultArgs, right.ignoreDefaultArgs)); if (left.kind === "cdp" && right.kind === "cdp") { return left.endpoint === right.endpoint && left.targetId === right.targetId; } return true; } function chromeArgsEqual(left, right) { return isDeepStrictEqual(left ?? [], right ?? []); } function ignoreDefaultArgsEqual(left, right) { if (left === true || right === true) return left === right; return chromeArgsEqual(Array.isArray(left) ? left : undefined, Array.isArray(right) ? right : undefined); }