import { promises as fs, existsSync } from "node:fs";
import { chromium } from "playwright";
const { ANCHOR_API_KEY } = process.env;
/**
* Save a download to disk.
* Handles three possible formats:
* 1. Playwright Download object
* 2. Base‑64 string
* 3. Fallback text scraped from the page
*/
async function saveDownload(download, filePath, page) {
// 1. Playwright Download object
if (download && typeof download.path === "function") {
try {
const tmpPath = await download.path();
if (tmpPath && existsSync(tmpPath)) {
await download.saveAs(filePath);
return filePath;
}
} catch {
/* ignore and fall through */
}
}
// 2. Raw base64 string
if (typeof download === "string") {
try {
await fs.writeFile(filePath, Buffer.from(download, "base64"));
return filePath;
} catch {
/* ignore and fall through */
}
}
// 3. Fallback – ask the page for data or capture visible text
if (page) {
try {
const blob = await page.evaluate(() => window._anchorExtractDownloadData());
return saveDownload(blob, filePath);
} catch {
/* ignore and fall through */
}
const fallbackText = await page.evaluate(() => {
const el = document.querySelector("main") || document.body;
return el.innerText || "";
});
await fs.writeFile(filePath, fallbackText, "utf8");
return filePath;
}
throw new Error("Failed to save download");
}
const downloadHandler = (filePath) => async (page, info) => {
if (info?.value) {
try {
return await saveDownload(info.value, filePath);
} catch {
/* ignore and fall through */
}
}
return saveDownload(null, filePath, page);
};
async function createSession() {
const res = await fetch("https://api.anchorbrowser.io/v1/sessions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"anchor-api-key": ANCHOR_API_KEY,
},
body: JSON.stringify({ browser: { p2p_download: { active: true } } }),
});
if (!res.ok) throw new Error(`Anchor API error ${res.status}: ${await res.text()}`);
const { data } = await res.json();
return data;
}
(async () => {
const session = await createSession();
if (!session?.cdp_url) throw new Error("No CDP URL in session");
const browser = await chromium.connectOverCDP(session.cdp_url);
const context = browser.contexts()[0];
const page = context.pages()[0];
await page.goto("https://v0-download-and-upload-text.vercel.app/");
await page.waitForSelector("button");
const [download] = await Promise.all([
page.waitForEvent("download", { timeout: 5000 }),
page.click("button"),
page.waitForTimeout(500), // allow JS to finish
]);
const filename = download.suggestedFilename();
await downloadHandler(filename)(page, { value: download });
const content = await fs.readFile(filename, "utf8");
console.log(`Downloaded '${filename}', content:\n${content}`);
await browser.close();
})();