import axios from "axios"; import { wrapper } from "axios-cookiejar-support"; import * as cheerio from "cheerio"; import { CookieJar } from "tough-cookie"; const jar = new CookieJar(); const client = wrapper(axios.create({ jar })); const HEADERS = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "accept-language": "en-US,en;q=0.9,id;q=0.8", }; function normalizeUrl(input) { if (!/mediafire\.com/.test(input)) throw new Error("URL MediaFire tidak valid"); return input.replace("://mediafire.com", "://www.mediafire.com").replace(/^http:/, "https:"); } /** * MediaFire Direct Download Link & Metadata Scraper * Extracts filename, size, extension, mimeType, and direct CDN download URL. */ async function mediafire(url) { try { const { data: html } = await client.get(normalizeUrl(url), { headers: HEADERS }); const $ = cheerio.load(html); const $btn = $("#downloadButton"); if (!$btn.length) throw new Error("Tombol download tidak ditemukan (file dihapus / private?)"); let downloadUrl = $btn.attr("href"); const scrambled = $btn.attr("data-scrambled-url"); if ((!downloadUrl || downloadUrl === "#") && scrambled) { downloadUrl = Buffer.from(scrambled, "base64").toString("utf8"); } if (!downloadUrl || !/^https?:/.test(downloadUrl)) { throw new Error("Link download tidak bisa di-resolve"); } // metadata const filename = $(".dl-btn-label").attr("title") || $(".filename").first().text().trim() || (downloadUrl.split("/").pop() || "").split("?")[0]; const details = {}; $(".details li").each((_, li) => { const text = $(li).text(); const idx = text.indexOf(":"); if (idx === -1) return; details[text.slice(0, idx).trim().toLowerCase()] = text.slice(idx + 1).trim(); }); let mimeType = null; let sizeBytes = null; try { const probe = await client.get(downloadUrl, { headers: { ...HEADERS, range: "bytes=0-0" }, responseType: "stream", validateStatus: () => true, }); mimeType = probe.headers["content-type"] || null; const cr = probe.headers["content-range"]; sizeBytes = cr ? Number(cr.split("/")[1]) : Number(probe.headers["content-length"]) || null; probe.data.destroy(); } catch {} const cookies = await jar.getCookieString("https://www.mediafire.com"); return { filename, size: details["file size"] || null, sizeBytes, uploaded: details["uploaded"] || null, extension: (filename.match(/\.(\w+)$/) || [])[1] || null, mimeType, downloadUrl, cookies: cookies || null, }; } catch (error) { throw new Error(`Mediafire Scraper Error: ${error.message}`); } } export { mediafire }; export default mediafire;