import type { Job, Profile } from "@prisma/client"; export type RunResult = { submitted: boolean; lines: string[] }; export type AdapterCtx = { job: Job; profile: Profile; submit: boolean }; export type Adapter = { name: string; matches: (url: string) => boolean; run: (ctx: AdapterCtx) => Promise; }; /** Shared helper: launch a headed chromium page (human can intervene on CAPTCHAs). */ export async function launchPage() { // Playwright is an optional dependency — installed only where the worker runs. const { chromium } = await import("playwright"); const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); return { browser, page }; } export async function fillIfPresent( page: import("playwright").Page, selectors: string[], value: string | null | undefined, log: string[], ) { if (!value) return; for (const sel of selectors) { const el = page.locator(sel).first(); if (await el.count()) { await el.fill(value); log.push(`filled ${sel}`); return; } } } import { dataAnnotationAdapter } from "./dataannotation"; import { genericGreenhouseAdapter } from "./greenhouse"; export const adapters: Adapter[] = [dataAnnotationAdapter, genericGreenhouseAdapter];