feat(types): centralize BrowserHandle, BrowserFingerprint, SupportedMethod

This commit is contained in:
germondai
2026-07-08 20:06:24 +02:00
parent d873e2662c
commit 25fe9d739a
3 changed files with 39 additions and 21 deletions
+3 -6
View File
@@ -1,3 +1,5 @@
import type { BrowserFingerprint } from "@trawl/types"
// The HTTP-level fingerprint sent with every request. Must match the actual browser
// engine (Camoufox = Firefox) or anti-bot services do UA-vs-engine cross-checks and
// flag the mismatch. Per-request the orchestrator picks one of these UAs at random
@@ -15,12 +17,7 @@ export const FINGERPRINT = {
// Picked from by the pool per browser-instance so HTTP headers + browser
// fingerprint (OS, navigator.platform) stay consistent.
export const FINGERPRINT_POOL: ReadonlyArray<{
userAgent: string
platform: "Win32" | "MacIntel" | "Linux x86_64" | "Linux armv8"
locale: string
timezone: string
}> = [
export const FINGERPRINT_POOL: ReadonlyArray<BrowserFingerprint> = [
{
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:150.0) Gecko/20100101 Firefox/150.0",
platform: "Win32",
+4 -11
View File
@@ -1,4 +1,4 @@
import type { PoolBrowser, PoolStats } from "@trawl/types"
import type { BrowserHandle, PoolBrowser, PoolStats } from "@trawl/types"
import { Camoufox } from "camoufox-js"
import { FINGERPRINT_POOL } from "./fingerprint"
@@ -18,16 +18,9 @@ export class PoolExhaustedError extends Error {
}
}
export interface BrowserHandle {
id: number
context: BrowserContext
browser: Browser
// Per-instance HTTP-level fingerprint (User-Agent + matching navigator.platform /
// locale / timezone). Set at init from FINGERPRINT_POOL so the orchestrator can
// send a UA that matches this browser's actual Camoufox-generated platform.
fingerprint: (typeof FINGERPRINT_POOL)[number]
noteTemporaryContext?: (reason: string) => void
}
// BrowserHandle now lives in @trawl/types (shared cross-package); re-exported here
// for backward compat so existing `import type { BrowserHandle } from "@trawl/browser"` keeps working.
export type { BrowserHandle } from "@trawl/types"
interface PoolEntry extends PoolBrowser {
browser: Browser | null
+32 -4
View File
@@ -9,6 +9,13 @@ export interface Cookie {
sameSite?: string
}
// CONNECT is intentionally excluded — it's a tunneling verb, not a normal
// request body, and would let a caller establish arbitrary TCP tunnels.
// QUERY (RFC 9341) is included — safe verb, body carries the query params.
// Single source of truth for the request-method union — @trawl/tiers derives its
// runtime SUPPORTED_METHODS array from this same literal set (see sanitize.ts).
export type SupportedMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY"
export interface ScrapeRequest {
url: string
maxTimeout?: number
@@ -16,10 +23,7 @@ export interface ScrapeRequest {
maxTier?: 1 | 2 | 3 | 4
sessionId?: string
headers?: Record<string, string>
// CONNECT is intentionally excluded — it's a tunneling verb, not a normal
// request body, and would let a caller establish arbitrary TCP tunnels.
// QUERY (RFC 9341) is included — safe verb, body carries the query params.
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "QUERY"
method?: SupportedMethod
body?: string
// Per-request proxy override — bypasses the server-configured proxy pool for this call.
proxy?: string
@@ -69,6 +73,30 @@ export interface PoolStats {
avgRestarts: number
}
// Per-instance HTTP-level fingerprint (User-Agent + matching navigator.platform /
// locale / timezone) — @trawl/browser's FINGERPRINT_POOL is typed against this shape.
export interface BrowserFingerprint {
userAgent: string
platform: "Win32" | "MacIntel" | "Linux x86_64" | "Linux armv8"
locale: string
timezone: string
}
// A leased browser+context pair handed to a tier by @trawl/browser's BrowserPool.
// `context`/`browser` are `any` — camoufox-js doesn't export Playwright's
// Browser/BrowserContext types, and browsers from Playwright vs patchright aren't
// structurally assignable to each other, so `any` is the pragmatic escape hatch
// (consumers call .newPage()/.newContext()/.cookies() etc directly on these fields).
export interface BrowserHandle {
id: number
// biome-ignore lint/suspicious/noExplicitAny: see comment above
context: any
// biome-ignore lint/suspicious/noExplicitAny: see comment above
browser: any
fingerprint: BrowserFingerprint
noteTemporaryContext?: (reason: string) => void
}
// Per-request proxy override as it arrives at the API. Prowlarr's Cardigann flow
// serializes this as an object (its FlareSolverrProxy class: {url, username, password}).
// Other callers may send a plain URL string. The API boundary normalizes both forms