UNPKG

nb-scraper

Version:

Community scraper library by Newbie Scrape

1,556 lines (1,541 loc) 118 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // app/index.ts var index_exports = {}; __export(index_exports, { CREATOR: () => CREATOR, DEFAULT_CONFIG: () => DEFAULT_CONFIG, INFO: () => INFO, VERSION: () => VERSION, WeatherMaster: () => WeatherMaster, Ytdl: () => Ytdl, analyzeDream: () => analyzeDream, animeIndo: () => animeIndo, anyDownloader: () => anyDownloader, blackboxAi: () => blackboxAi, createErrorResponse: () => createErrorResponse, createExomlMessage: () => createExomlMessage, createSuccessResponse: () => createSuccessResponse, extractDomain: () => extractDomain, facebookDownloader: () => facebookDownloader, ffstalk: () => ffstalk, formatBytes: () => formatBytes, generateDeepInfraResponse: () => generateDeepInfraResponse, generateExomlResponse: () => generateExomlResponse, generateLyrics: () => generateLyrics, generatePollinationsImage: () => generatePollinationsImage, getPollinationsDirectUrl: () => getPollinationsDirectUrl, getSoundCloudCacheInfo: () => getSoundCloudCacheInfo, getTurnstileToken: () => getTurnstileToken, getYoutubePost: () => getYoutubePost, groupdaSearch: () => groupdaSearch, isValidUrl: () => isValidUrl, laraTranslate: () => laraTranslate, lemonWrite: () => lemonWrite, liputan6: () => liputan6, periksadata: () => periksadata, pinterest: () => pinterest, premiumDreamAnalysis: () => premiumDreamAnalysis, quickDreamAnalysis: () => quickDreamAnalysis, sanitizeString: () => sanitizeString, savegram: () => savegram, searchApk: () => searchApk, searchComics: () => searchComics, searchSoundCloud: () => searchSoundCloud, ssyoutube: () => ssyoutube, teraboxSearch: () => teraboxSearch, textcraft: () => textcraft, threads: () => threads, tiktok: () => tiktok, translateEcommerceImageFromUrl: () => translateEcommerceImageFromUrl, translateImage: () => translateImage, translateManga: () => translateManga, tutwuriBypass: () => tutwuriBypass, unaimytextHumanize: () => unaimytextHumanize, uploadImage: () => uploadImage, ytmp3cc: () => ytmp3cc, ytmp3mobi: () => ytmp3mobi }); module.exports = __toCommonJS(index_exports); // app/utils.ts var import_axios = __toESM(require("axios")); var DEFAULT_CONFIG = { timeout: 3e4, retries: 3, retryDelay: 1e3, userAgent: "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36" }; var CREATOR = "nb-scraper"; var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); function isValidUrl(url2) { try { new URL(url2); return true; } catch { return false; } } function sanitizeString(input) { return input.replace(/[<>'"]/g, "").trim().slice(0, 1e4); } function createErrorResponse(error, context) { let errorMessage; let errorType = "UNKNOWN_ERROR" /* UNKNOWN_ERROR */; if (typeof error === "string") { errorMessage = error; } else if (error instanceof Error) { errorMessage = error.message; if (error.name === "AxiosError" || error.message.includes("network")) { errorType = "NETWORK_ERROR" /* NETWORK_ERROR */; } else if (error.message.includes("timeout")) { errorType = "NETWORK_ERROR" /* NETWORK_ERROR */; } else if (error.message.includes("rate") || error.message.includes("limit")) { errorType = "RATE_LIMITED" /* RATE_LIMITED */; } } else { errorMessage = error.message; errorType = error.type; } return { creator: CREATOR, status: false, error: `[${errorType}] ${errorMessage}${context ? ` | Context: ${JSON.stringify(context)}` : ""}` }; } function createSuccessResponse(data) { return { creator: CREATOR, status: true, data }; } async function makeRequest(config, options = {}) { const { timeout = DEFAULT_CONFIG.timeout, retries = DEFAULT_CONFIG.retries, retryDelay = DEFAULT_CONFIG.retryDelay, headers = {} } = options; const requestConfig = { ...config, timeout, headers: { "User-Agent": DEFAULT_CONFIG.userAgent, "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "id-ID,id;q=0.9,en;q=0.8", ...headers, ...config.headers } }; let lastError; for (let attempt = 0; attempt <= retries; attempt++) { try { const response2 = await (0, import_axios.default)(requestConfig); return response2; } catch (error) { lastError = error; if (import_axios.default.isAxiosError(error)) { const axiosError = error; if (axiosError.response?.status && axiosError.response.status >= 400 && axiosError.response.status < 500 && axiosError.response.status !== 429) { throw error; } } if (attempt === retries) { throw lastError; } await sleep(retryDelay * (attempt + 1)); } } throw lastError; } function validateRequiredParams(params, required) { for (const param of required) { const value = params[param]; if (value === void 0 || value === null || value === "") { throw new Error(`Parameter '${param}' is required and cannot be empty`); } if (typeof value === "string" && value.trim() === "") { throw new Error(`Parameter '${param}' cannot be an empty string`); } } } function safeJsonParse(jsonString) { try { return JSON.parse(jsonString); } catch { return null; } } function extractDomain(url2) { try { const urlObj = new URL(url2); return urlObj.hostname; } catch { return null; } } function formatBytes(bytes, decimals = 2) { if (bytes === 0) return "0 Bytes"; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; } // app/scrapers/blackbox.ts var DEFAULT_BLACKBOX_CONFIG = { maxTokens: 1024, temperature: null, webSearchMode: false, memoryEnabled: false }; async function blackboxAi(query, options = {}) { try { validateRequiredParams({ query }, ["query"]); const sanitizedQuery = query.trim(); if (sanitizedQuery.length === 0) { return createErrorResponse("Query cannot be empty", { query }); } if (sanitizedQuery.length > 1e4) { return createErrorResponse("Query too long (max 10,000 characters)", { queryLength: sanitizedQuery.length }); } const config = { ...DEFAULT_BLACKBOX_CONFIG, ...options }; const headers = { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "id-ID,id;q=0.9", "Content-Type": "application/json", "Origin": "https://www.blackbox.ai", "Referer": "https://www.blackbox.ai/", "Sec-Ch-Ua": '"Chromium";v="137", "Not/A)Brand";v="24"', "Sec-Ch-Ua-Mobile": "?1", "Sec-Ch-Ua-Platform": '"Android"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", ...options.headers }; const payload = { messages: [{ role: "user", content: sanitizedQuery, id: generateRandomId() }], id: generateRandomId(), previewToken: null, userId: null, codeModelMode: true, trendingAgentMode: {}, isMicMode: false, userSystemPrompt: null, maxTokens: config.maxTokens, playgroundTopP: null, playgroundTemperature: config.temperature, isChromeExt: false, githubToken: "", clickedAnswer2: false, clickedAnswer3: false, clickedForceWebSearch: config.webSearchMode, visitFromDelta: false, isMemoryEnabled: config.memoryEnabled, mobileClient: false, userSelectedModel: null, validated: generateUUID(), imageGenerationMode: false, webSearchModePrompt: config.webSearchMode, deepSearchMode: false, domains: null, vscodeClient: false, codeInterpreterMode: false, customProfile: { name: "", occupation: "", traits: [], additionalInfo: "", enableNewChats: false }, webSearchModeOption: { autoMode: true, webMode: config.webSearchMode, offlineMode: !config.webSearchMode }, session: null, isPremium: false, subscriptionCache: null, beastMode: false, reasoningMode: false, designerMode: false, workspaceId: "", asyncMode: false, isTaskPersistent: false }; const response2 = await makeRequest( { method: "POST", url: "https://www.blackbox.ai/api/chat", data: payload, headers }, { timeout: options.timeout, retries: options.retries, retryDelay: options.retryDelay } ); if (!response2.data || typeof response2.data !== "string") { return createErrorResponse("Invalid response format from BlackBox AI", { responseType: typeof response2.data, status: response2.status }); } const rawResponse = response2.data; const parsedData = parseBlackBoxResponse(rawResponse); if (!parsedData) { return createErrorResponse("Failed to parse BlackBox AI response", { rawResponse: rawResponse.substring(0, 100) + "..." }); } return createSuccessResponse(parsedData); } catch (error) { return createErrorResponse(error, { query: query.substring(0, 100), options: { ...options, headers: void 0 } // Don't log headers for security }); } } function parseBlackBoxResponse(rawResponse) { try { const parsed = rawResponse.split("$~~~$"); if (parsed.length === 1) { const response2 = parsed[0]?.trim(); if (!response2) { return null; } return { response: response2, source: [] }; } else if (parsed.length >= 3) { const response2 = parsed[2]?.trim(); const sourcesData = parsed[1]; if (!response2 || !sourcesData) { return null; } const sources = safeJsonParse(sourcesData); if (!Array.isArray(sources)) { return { response: response2, source: [] }; } const validSources = sources.filter( (source) => source && typeof source === "object" && typeof source.link === "string" && typeof source.title === "string" ).map((source) => ({ link: source.link, title: source.title, snippet: source.snippet || "", position: typeof source.position === "number" ? source.position : 0 })); return { response: response2, source: validSources }; } return null; } catch { return null; } } function generateRandomId() { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let result = ""; for (let i = 0; i < 7; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } function generateUUID() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === "x" ? r : r & 3 | 8; return v.toString(16); }); } // app/scrapers/threads.ts async function threads(url2, options = {}) { try { validateRequiredParams({ url: url2 }, ["url"]); const sanitizedUrl = url2.trim(); if (!isValidUrl(sanitizedUrl)) { return createErrorResponse("Invalid URL format", { url: sanitizedUrl }); } const domain = extractDomain(sanitizedUrl); if (!domain?.includes("threads.net")) { return createErrorResponse("URL must be from threads.net", { domain, url: sanitizedUrl }); } const apiUrl = `https://api.threadsphotodownloader.com/v2/media?url=${encodeURIComponent(sanitizedUrl)}`; const headers = { "User-Agent": "5.0", "Accept": "application/json", "Accept-Language": "id-ID,id;q=0.9,en;q=0.8", ...options.headers }; const response2 = await makeRequest( { method: "GET", url: apiUrl, headers }, { timeout: options.timeout, retries: options.retries, retryDelay: options.retryDelay } ); if (!response2.data || typeof response2.data !== "object") { return createErrorResponse("Invalid response format from Threads API", { responseType: typeof response2.data, status: response2.status }); } const rawData = response2.data; const imageUrls = parseMediaUrls(rawData.image_urls); const videoUrls = parseMediaUrls(rawData.video_urls); let filteredData = { image_urls: imageUrls, video_urls: videoUrls }; if (options.imagesOnly) { filteredData.video_urls = []; } else if (options.videosOnly) { filteredData.image_urls = []; } if (filteredData.image_urls.length === 0 && filteredData.video_urls.length === 0) { return createErrorResponse("No media found in the Threads post", { url: sanitizedUrl, rawImageCount: imageUrls.length, rawVideoCount: videoUrls.length }); } return createSuccessResponse(filteredData); } catch (error) { return createErrorResponse(error, { url: url2.substring(0, 100), options: { ...options, headers: void 0 } }); } } function parseMediaUrls(urls) { if (!Array.isArray(urls)) { return []; } return urls.filter( (url2) => typeof url2 === "string" && url2.trim().length > 0 && isValidUrl(url2.trim()) ).map((url2) => url2.trim()).slice(0, 50); } // app/scrapers/pinterest.ts async function pinterest(query, options) { try { validateRequiredParams({ query }, ["query"]); const searchUrl = "https://www.pinterest.com/resource/BaseSearchResource/get/"; const params = new URLSearchParams({ data: JSON.stringify({ options: { query } }) }); const response2 = await makeRequest({ url: `${searchUrl}?${params.toString()}`, method: "HEAD", headers: { "screen-dpr": "4", "x-pinterest-pws-handler": "www/search/[scope].js", ...options?.headers } }, options); const linkHeader = response2.headers.link; if (!linkHeader) { return createErrorResponse("No results found for the query", { type: "INVALID_RESPONSE" /* INVALID_RESPONSE */, context: { query } }); } const links = [...linkHeader.matchAll(/<(.*?)>/gm)].map((v) => v[1]); return createSuccessResponse({ result: links }); } catch (error) { return createErrorResponse(error, { type: "NETWORK_ERROR" /* NETWORK_ERROR */, context: { query } }); } } // app/scrapers/exomlapi.ts var BASE_URL = "https://exomlapi.com/api/chat"; var EXOML_MODELS = [ "llama", "gemma", "qwen-3-235b", "gpt-4.1", "gpt-4o", "gpt-4o-mini", "llama-4-scout", "llama-4-maverick", "deepseek-r1", "qwq-32b" ]; function generateRandomIds() { const gen = (length, charSet = {}) => { const l = "abcdefghijklmnopqrstuvwxyz"; const u = l.toUpperCase(); const s = "-_"; const n = "0123456789"; const { lowerCase = false, upperCase = false, symbol = false, number = false } = charSet; let cs = ""; if (!lowerCase && !upperCase && !symbol && !number) { cs = l + u + s + n; } else { if (lowerCase) cs += l; if (upperCase) cs += u; if (symbol) cs += s; if (number) cs += n; } return Array.from( { length }, () => cs[Math.floor(Math.random() * cs.length)] ).join(""); }; const id = gen(16, { upperCase: true, lowerCase: true, number: true }); const timestamp = (/* @__PURE__ */ new Date()).getTime(); const chatId = `chat-${timestamp}-${gen(9, { lowerCase: true, number: true })}`; const userId = `local-user-${timestamp}-${gen(9, { lowerCase: true, number: true })}`; const antiBotId = `${gen(32)}-${gen(8, { number: true, lowerCase: true })}`; return { id, chatId, userId, antiBotId }; } function createExomlMessage(role, content) { return { role, content }; } async function generateExomlResponse(options) { try { validateRequiredParams(options, ["messages"]); const { messages, systemPrompt = "", model = "gpt-4.1" } = options; if (!EXOML_MODELS.includes(model)) { return createErrorResponse( `Invalid model. Available models: ${EXOML_MODELS.join(", ")}`, { type: "INVALID_PARAMETER" /* INVALID_PARAMETER */, context: { model } } ); } const body = JSON.stringify({ messages, systemPrompt, model, isAuthenticated: true, ...generateRandomIds() }); const response2 = await makeRequest({ url: BASE_URL, method: "POST", headers: { "Content-Type": "application/json" }, data: body }); if (typeof response2.data !== "string") { return createErrorResponse("Invalid response format from server", { type: "INVALID_RESPONSE" /* INVALID_RESPONSE */, context: { rawResponse: response2.data } }); } const data = response2.data; const content = [...data.matchAll(/^0:"(.*?)"$/gm)].map((v) => v[1]).join("").replaceAll("\\n", "\n").replaceAll('\\"', '"'); if (!content) { return createErrorResponse("Failed to parse message from server", { type: "PARSE_ERROR" /* PARSE_ERROR */, context: { rawResponse: data } }); } return createSuccessResponse({ content }); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "ExomlAPI" } }); } } // app/scrapers/dreamanalysis.ts var BASE_URL2 = "https://safe-coast-53976-cd772af9b056.herokuapp.com/"; function parseDreamResponse(raw) { if (typeof raw !== "string") return null; try { const data = JSON.parse(raw); return { analysis: data.analysis, interpretation: data.interpretation, symbols: data.symbols || [], emotions: data.emotions || [], themes: data.themes || [], metadata: data.metadata || {} }; } catch { return null; } } async function analyzeDream(options) { try { validateRequiredParams(options, ["text"]); const { text, isPremium = true } = options; const response2 = await makeRequest({ url: BASE_URL2, method: "POST", headers: { "Accept-Encoding": "gzip", "Connection": "Keep-Alive", "Content-Type": "application/json", "Host": "safe-coast-53976-cd772af9b056.herokuapp.com", "User-Agent": "okhttp/4.9.2" }, data: JSON.stringify({ text, isPremium }) }); const rawResponse = response2.data; if (typeof rawResponse !== "string") { return createErrorResponse("Invalid response format", { type: "INVALID_RESPONSE" /* INVALID_RESPONSE */, context: { service: "DreamAnalysis", rawResponse: String(rawResponse).substring(0, 100) + "..." } }); } const parsedData = parseDreamResponse(rawResponse); if (!parsedData) { return createErrorResponse("Failed to parse Dream response", { type: "PARSE_ERROR" /* PARSE_ERROR */, context: { rawResponse: rawResponse.substring(0, 100) + "..." } }); } return createSuccessResponse(parsedData); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "DreamAnalysis" } }); } } async function quickDreamAnalysis(text) { return analyzeDream({ text, isPremium: false }); } async function premiumDreamAnalysis(text) { return analyzeDream({ text, isPremium: true }); } // app/scrapers/pollinations.ts var import_stream = require("stream"); var import_form_data = __toESM(require("form-data")); var import_fs = __toESM(require("fs")); var import_path = __toESM(require("path")); var import_os = __toESM(require("os")); var BASE_URL3 = "https://image.pollinations.ai/prompt/"; var UPLOAD_URL = "https://catbox.moe/user/api.php"; async function generatePollinationsImage(options) { try { validateRequiredParams(options, ["prompt"]); const { prompt, nologo = true } = options; const encodedPrompt = encodeURIComponent(prompt); const imageUrl = `${BASE_URL3}${encodedPrompt}${nologo ? "?nologo=true" : ""}`; const tempPath = import_path.default.join(import_os.default.tmpdir(), `pollinations_${Date.now()}.jpg`); const response2 = await makeRequest({ url: imageUrl, responseType: "arraybuffer" }); const buffer = Buffer.from(response2.data); const readable = new import_stream.Readable(); readable.push(buffer); readable.push(null); const writer = import_fs.default.createWriteStream(tempPath); readable.pipe(writer); await new Promise((resolve, reject) => { writer.on("finish", () => resolve()); writer.on("error", (err) => reject(err)); }); const form = new import_form_data.default(); form.append("reqtype", "fileupload"); form.append("fileToUpload", import_fs.default.createReadStream(tempPath)); const upload = await makeRequest({ method: "POST", url: UPLOAD_URL, data: form, headers: form.getHeaders() }); import_fs.default.unlinkSync(tempPath); if (typeof upload.data !== "string") { throw new Error("Invalid upload response"); } return createSuccessResponse({ url: upload.data, directUrl: imageUrl }); } catch (error) { return createErrorResponse(error, { type: "IMAGE_GENERATION_ERROR" /* IMAGE_GENERATION_ERROR */, context: { service: "Pollinations" } }); } } function getPollinationsDirectUrl(options) { validateRequiredParams(options, ["prompt"]); const { prompt, nologo = true } = options; const encodedPrompt = encodeURIComponent(prompt); return `${BASE_URL3}${encodedPrompt}${nologo ? "?nologo=true" : ""}`; } // app/scrapers/soundcloud.ts var BASE_URL4 = "https://soundcloud.com/"; var API_URL = "https://api-v2.soundcloud.com/search/tracks"; var cache = { version: "", id: "" }; function formatDuration(ms) { const sec = Math.floor(ms / 1e3); const min = Math.floor(sec / 60); const remainder = sec % 60; return `${min}:${remainder.toString().padStart(2, "0")}`; } function formatNumber(n) { if (n >= 1e6) return (n / 1e6).toFixed(1).replace(/\.0$/, "") + "M"; if (n >= 1e3) return (n / 1e3).toFixed(1).replace(/\.0$/, "") + "K"; return n.toString(); } function formatDate(dateStr) { if (!dateStr) return null; const d = new Date(dateStr); return d.toISOString().split("T")[0]; } async function getClientID() { try { const response2 = await makeRequest({ url: BASE_URL4, method: "GET" }); if (typeof response2.data !== "string") { throw new Error("invalid html data"); } const html2 = response2.data; const version = html2.match( /<script>window\.__sc_version="(\d{10})"<\/script>/ )?.[1]; if (!version) return null; if (cache.version === version) return cache.id; const scriptMatches = [...html2.matchAll( /<script.*?src="(https:\/\/a-v2\.sndcdn\.com\/assets\/[^"]+)"/g )]; for (const [, scriptUrl] of scriptMatches) { const { data: js } = await makeRequest({ url: scriptUrl, method: "GET" }); if (typeof js !== "string") { continue; } const idMatch = js.match(/client_id:"([a-zA-Z0-9]{32})"/); if (idMatch) { cache = { version, id: idMatch[1] }; return idMatch[1]; } } } catch (error) { throw new Error( `Failed to get client_id: ${error instanceof Error ? error.message : "Unknown error"}` ); } return null; } async function searchSoundCloud(options) { const { query, limit = 3 } = options; let clientId = null; try { validateRequiredParams(options, ["query"]); const clientId2 = await getClientID(); if (!clientId2) { return createErrorResponse("Failed to obtain client_id", { type: "AUTH_ERROR" /* AUTH_ERROR */, context: { service: "SoundCloud" } }); } const response2 = await makeRequest({ url: API_URL, method: "GET", params: { q: query, client_id: clientId2, limit } }); if (!response2.data?.collection) { return createErrorResponse("Invalid SoundCloud API response", { type: "INVALID_RESPONSE" /* INVALID_RESPONSE */ }); } const tracks = response2.data.collection.map((track) => { const durationMs = track.duration; const duration = formatDuration(durationMs); const likeCount = formatNumber(track.likes_count); const playCount = formatNumber(track.playback_count); const downloadCount = formatNumber(track.download_count); const releaseDate = track.release_date || track.created_at; return { id: track.id, title: track.title, url: track.permalink_url, duration, thumbnail: track.artwork_url, author: { name: track.user.username, url: track.user.permalink_url }, like_count: likeCount, download_count: downloadCount, play_count: playCount, release_date: formatDate(releaseDate) }; }); return createSuccessResponse({ tracks }); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "SoundCloud", query, clientId: clientId ? "*****" : "null" } }); } } function getSoundCloudCacheInfo() { return { ...cache }; } // app/scrapers/deepinfra.ts var BASE_URL5 = "https://ai-sdk-starter-deepinfra.vercel.app/api/chat"; async function generateDeepInfraResponse(options) { try { validateRequiredParams(options, ["prompt"]); const { prompt, model = "meta-llama/Llama-3.3-70B-Instruct-Turbo" } = options; const body = { id: Math.random().toString(36).slice(2), selectedModel: model, messages: [{ role: "user", content: prompt, parts: [{ type: "text", text: prompt }] }] }; const response2 = await makeRequest({ url: BASE_URL5, method: "POST", headers: { "Content-Type": "application/json" }, data: body }); const parts = []; const responseData = response2.data; if (responseData && typeof responseData === "object") { const data = responseData; if (data.g) { parts.push(...Array.isArray(data.g) ? data.g : [data.g]); } if (data.f) { parts.push(...Array.isArray(data.f) ? data.f : [data.f]); } if (data["0"]) { parts.push(...Array.isArray(data["0"]) ? data["0"] : [data["0"]]); } } else if (typeof responseData === "string") { parts.push(responseData); } const result = parts.join("").trim() || "No response generated"; return createSuccessResponse({ response: result }); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "DeepInfraAI", model: options.model } }); } } // app/scrapers/animeindo.ts var import_url = require("url"); var cheerio = __toESM(require("cheerio")); var BASE_URL6 = "https://anime-indo.lol"; var animeIndo = { /** * Search anime * * @example * ```typescript * const result = await animeIndo.search("Naruto"); * if (result.status) { * console.log(result.data); * } * ``` * @author Jul */ async search(query) { try { validateRequiredParams({ query }, ["query"]); const url2 = `${BASE_URL6}/search/${encodeURIComponent(query)}/`; const response2 = await makeRequest({ url: url2 }); const $ = cheerio.load(response2.data); const results = []; $("table.otable").each((_index, el) => { const element = $(el); const title = element.find(".videsc a").text().trim(); const link = BASE_URL6 + element.find(".videsc a").attr("href"); const image = BASE_URL6 + element.find("img").attr("src"); const description = element.find("p.des").text().trim(); const labelEls = element.find(".label"); const year = labelEls.last().text().trim(); results.push({ title, link, image, year, description }); }); return createSuccessResponse(results); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "AnimeIndo", query } }); } }, /** * Get anime details * * @example * ```typescript * const result = await animeIndo.detail("https://anime-indo.lol/anime/naruto"); * if (result.status) { * console.log(result.data); * } * ``` * @author Jul */ async detail(url2) { try { validateRequiredParams({ url: url2 }, ["url"]); const response2 = await makeRequest({ url: url2 }); const $ = cheerio.load(response2.data); const title = $("h1.title").text().trim(); let imageSrc = $(".detail img").attr("src") || ""; if (imageSrc.startsWith("/")) { imageSrc = BASE_URL6 + imageSrc; } const genres = []; $(".detail li a").each((_index, el) => { genres.push($(el).text().trim()); }); const description = $(".detail p").text().trim(); const episodes = []; $(".ep a").each((_index, el) => { let epLink = $(el).attr("href"); if (epLink && epLink.startsWith("/")) { epLink = BASE_URL6 + epLink; } episodes.push({ episode: $(el).text().trim(), link: epLink || "" }); }); return createSuccessResponse({ title, image: imageSrc, genres, description, episodes }); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "AnimeIndo", url: url2 } }); } }, /** * Download episode * * @example * ```typescript * const result = await animeIndo.download("https://anime-indo.lol/episode/naruto-1"); * if (result.status) { * console.log(result.data.downloadUrl); * } * ``` * @author Jul */ async download(episodeUrl) { try { validateRequiredParams({ episodeUrl }, ["episodeUrl"]); const { data: episodeHtml } = await makeRequest({ url: episodeUrl, headers: { "User-Agent": "Mozilla/5.0" } }); const $ = cheerio.load(episodeHtml); const title = $("h1.title").first().text().trim(); const description = $(".detail p").text().trim(); const videoLinks = []; $(".servers a.server").each((_index, el) => { const label = $(el).text().trim(); let videoUrl = $(el).attr("data-video") || ""; if (videoUrl.startsWith("//")) { videoUrl = "https:" + videoUrl; } videoLinks.push({ label, videoUrl }); }); const gdriveHdLinkObj = videoLinks.find( (v) => v.label.toLowerCase().includes("gdrive") && v.label.toLowerCase().includes("hd") ); if (!gdriveHdLinkObj) { return createErrorResponse("HD quality not available", { type: "QUALITY_NOT_AVAILABLE" /* QUALITY_NOT_AVAILABLE */, context: { episodeUrl, availableQualities: videoLinks.map((v) => v.label) } }); } const { data: gdriveHtml } = await makeRequest({ url: gdriveHdLinkObj.videoUrl, headers: { "User-Agent": "Mozilla/5.0" } }); const $$ = cheerio.load(gdriveHtml); const gdriveRawLink = $$("#subtitlez").text().trim(); if (!gdriveRawLink) { throw new Error("Google Drive raw link not found in embed page"); } const parsedUrl = new import_url.URL(gdriveRawLink); const allowedHosts = ["drive.google.com"]; if (!allowedHosts.includes(parsedUrl.host)) { throw new Error("Invalid host for Google Drive raw link"); } const idMatch = gdriveRawLink.match(/\/d\/([^\/]+)\//) || gdriveRawLink.match(/id=([^&]+)/); if (!idMatch) throw new Error("Google Drive file ID not found"); const fileId = idMatch[1]; const driveApiUrl = `https://drive.google.com/uc?id=${fileId}&authuser=0&export=download`; const driveResponse = await makeRequest({ method: "POST", url: driveApiUrl, headers: { "accept-encoding": "gzip, deflate, br", "content-length": "0", "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", "origin": "https://drive.google.com", "user-agent": "Mozilla/5.0", "x-client-data": "CKG1yQEIkbbJAQiitskBCMS2yQEIqZ3KAQioo8oBGLeYygE=", "x-drive-first-party": "DriveWebUi", "x-json-requested": "true" } }); const jsonStr = driveResponse.data.slice(4); const json = JSON.parse(jsonStr); if (!json.downloadUrl || !json.fileName || !json.sizeBytes) { throw new Error("Invalid Google Drive response"); } const fileDownloadUrl = json.downloadUrl; const fileName = json.fileName; const fileSize = json.sizeBytes; const headResponse = await makeRequest({ method: "HEAD", url: fileDownloadUrl, headers: { "User-Agent": "Mozilla/5.0" } }); return createSuccessResponse({ title, description, videoLinks, gdriveHdLink: gdriveHdLinkObj.videoUrl, downloadUrl: fileDownloadUrl, fileName, fileSize, mimetype: headResponse.headers["content-type"] || "application/octet-stream" }); } catch (error) { return createErrorResponse(error, { type: "DOWNLOAD_ERROR" /* DOWNLOAD_ERROR */, context: { service: "AnimeIndo", episodeUrl } }); } } }; // app/scrapers/facebook.ts var cheerio2 = __toESM(require("cheerio")); var import_qs = __toESM(require("qs")); async function facebookDownloader(url2) { try { validateRequiredParams({ url: url2 }, ["url"]); const allowedHosts = ["facebook.com", "www.facebook.com"]; const parsedHost = new URL(url2).host; if (!allowedHosts.includes(parsedHost)) { return createErrorResponse("Invalid Facebook video URL format", { type: "INVALID_INPUT" /* INVALID_INPUT */, context: { url: url2 } }); } const verifyPayload = import_qs.default.stringify({ url: url2 }); const verifyConfig = { method: "POST", url: "https://fdownloader.net/api/userverify", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Accept": "*/*", "X-Requested-With": "XMLHttpRequest" }, data: verifyPayload }; const verifyRes = await makeRequest(verifyConfig); if (verifyRes.status !== 200 || !verifyRes.data?.token) { return createErrorResponse("Failed to get verification token", { type: "AUTH_ERROR" /* AUTH_ERROR */, context: { service: "FacebookDownloader" } }); } const cftoken = verifyRes.data.token; const ajaxPayload = import_qs.default.stringify({ k_exp: Math.floor(Date.now() / 1e3) + 1800, k_token: "4901a847f621da898b5429bf38df6f3a0959738cd4eb52a2bf0cf44b3eb44cad", q: url2, lang: "id", web: "fdownloader.net", v: "v2", w: "", cftoken }); const ajaxConfig = { method: "POST", url: "https://v3.fdownloader.net/api/ajaxSearch", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Accept": "*/*" }, data: ajaxPayload }; const ajaxRes = await makeRequest(ajaxConfig); if (ajaxRes.status !== 200 || typeof ajaxRes.data !== "string" && ajaxRes.data?.status !== "ok") { return createErrorResponse("Failed to fetch video data", { type: "API_ERROR" /* API_ERROR */, context: { service: "FacebookDownloader" } }); } const html2 = typeof ajaxRes.data === "string" ? ajaxRes.data : ajaxRes.data?.data || ""; if (!html2) { return createErrorResponse("No HTML content found in response", { type: "API_ERROR" /* API_ERROR */, context: { service: "FacebookDownloader" } }); } const $ = cheerio2.load(html2); const thumbnail = $(".image-fb img").attr("src") || ""; const duration = $(".content p").text().trim(); const title = $(".content h3").text().trim(); const links = []; $("a.download-link-fb").each((_index, el) => { const link = $(el).attr("href"); const quality = $(el).attr("title")?.replace("Download ", "") || "Unknown"; const format = link?.includes(".mp4") ? "mp4" : "unknown"; if (link) { links.push({ quality, format, link }); } }); if (links.length === 0) { return createErrorResponse("No download links found", { type: "NOT_FOUND" /* NOT_FOUND */, context: { service: "FacebookDownloader" } }); } return createSuccessResponse({ title, duration, thumbnail, links }); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */, context: { service: "FacebookDownloader" } }); } } // app/scrapers/anydownloader.ts var cheerio3 = __toESM(require("cheerio")); async function getToken() { try { const config = { method: "GET", url: "https://anydownloader.com/en/xiaohongshu-videos-and-photos-downloader", headers: { "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36" } }; const response2 = await makeRequest(config); if (!response2.status || !response2.data) { return createErrorResponse("Failed to fetch token page", { type: "AUTH_ERROR" /* AUTH_ERROR */ }); } const $ = cheerio3.load(response2.data); const token = $("#token").val(); if (!token) { return createErrorResponse("Token not found in page", { type: "NOT_FOUND" /* NOT_FOUND */ }); } return createSuccessResponse({ token }); } catch (error) { return createErrorResponse(error, { type: "NETWORK_ERROR" /* NETWORK_ERROR */ }); } } function calculateHash(url2, salt) { return Buffer.from(url2).toString("base64") + (url2.length + 1e3) + Buffer.from(salt).toString("base64"); } async function anyDownloader(url2) { try { validateRequiredParams({ url: url2 }, ["url"]); const tokenResponse = await getToken(); if (!tokenResponse.status || !tokenResponse.data?.token) { return createErrorResponse( tokenResponse.error ?? "Failed to obtain token", { type: "AUTH_ERROR" /* AUTH_ERROR */ } ); } const { token } = tokenResponse.data; const hash = calculateHash(url2, "aio-dl"); const data = new URLSearchParams(); data.append("url", url2); data.append("token", token); data.append("hash", hash); const config = { method: "POST", url: "https://anydownloader.com/wp-json/aio-dl/video-data/", headers: { "Accept": "*/*", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Origin": "https://anydownloader.com", "Referer": "https://anydownloader.com/en/xiaohongshu-videos-and-photos-downloader", "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", "X-Requested-With": "XMLHttpRequest" }, data: data.toString() }; const response2 = await makeRequest(config); if (!response2.status || !response2.data) { return createErrorResponse("Failed to fetch video data", { type: "API_ERROR" /* API_ERROR */ }); } if (response2.data.error) { return createErrorResponse(response2.data.error, { type: "API_ERROR" /* API_ERROR */ }); } return createSuccessResponse(response2.data); } catch (error) { return createErrorResponse(error, { type: "API_ERROR" /* API_ERROR */ }); } } // app/scrapers/youtube.ts var import_axios2 = __toESM(require("axios")); var import_form_data2 = __toESM(require("form-data")); var validQualities = { "480": 480, "1080": 1080, "720": 720, "360": 360, "audio": "mp3" }; var YOUTUBE_DOMAINS = /* @__PURE__ */ new Set([ "youtube.com", "www.youtube.com", "youtu.be", "m.youtube.com" ]); function validateYouTubeUrl(url2) { if (!isValidUrl(url2)) { return createErrorResponse("Invalid YouTube URL", { type: "INVALID_INPUT" /* INVALID_INPUT */ }); } const domain = extractDomain(url2); if (!domain || !YOUTUBE_DOMAINS.has(domain.replace(/^www\./, ""))) { return createErrorResponse("URL must be from YouTube domain", { type: "INVALID_INPUT" /* INVALID_INPUT */, context: { validDomains: Array.from(YOUTUBE_DOMAINS) } }); } try { return createSuccessResponse(new URL(url2)); } catch (error) { return createErrorResponse(error, { type: "INVALID_INPUT" /* INVALID_INPUT */ }); } } var waitForDownloadUrl = async (progressUrl) => { const maxAttempts = 40; let attempts = 0; while (attempts < maxAttempts) { await new Promise((resolve) => setTimeout(resolve, 3e3)); try { const progressResponse = await import_axios2.default.get( progressUrl, { timeout: 15e3, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } } ); if (progressResponse.data?.download_url) { return progressResponse.data.download_url; } } catch (pollError) { if (import_axios2.default.isAxiosError(pollError) && pollError.response?.status !== void 0 && pollError.response.status >= 400) { throw new Error( `Remote server responded with ${pollError.response.status}` ); } } attempts++; } throw new Error("Timeout: please try again"); }; var Ytdl = { /** * @beta * * Download YouTube video as MP3 * @param url - YouTube video URL * @example * ```ts * import { Ytdl } from 'nb-scraper'; * * const result = await Ytdl.mp3("https://youtube.com/.../"); * console.log(result) * ``` * @author YogikId */ mp3: async (url2) => { const urlValidation = validateYouTubeUrl(url2); if (!urlValidation.status) { return createErrorResponse({ message: "Invalid YouTube URL", type: "INVALID_INPUT" /* INVALID_INPUT */ }); } const ds = new import_form_data2.default(); ds.append("url", url2); try { const config = { method: "post", url: "https://www.youtubemp3.ltd/convert", headers: { ...ds.getHeaders(), "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, data: ds, timeout: 45e3 }; const response2 = await (0, import_axios2.default)(config); const data = response2.data; if (!data?.link) { return createErrorResponse("Failed to get download link", { type: "API_ERROR" /* API_ERROR */ }); } return createSuccessResponse({ title: data.filename || "Unknown Title", downloadUrl: data.link, type: "mp3" }); } catch (error) { if (import_axios2.default.isAxiosError(error) && error.code === "ECONNABORTED") { return createErrorResponse("Request timeout", { type: "NETWORK_ERROR" /* NETWORK_ERROR */ }); } const ax = error; const serverMsg = typeof ax.response?.data === "object" && ax.response?.data !== null && "message" in ax.response.data ? ax.response.data.message : void 0; return createErrorResponse( serverMsg ?? ax.message ?? "Audio Download Failed", { type: "API_ERROR" /* API_ERROR */ } ); } }, /** * @beta * * Download YouTube video in specified quality * @param url - YouTube video URL * @param quality - Quality option (480, 720, 1080, 360, audio) * @example * ```ts * import { Ytdl } from 'nb-scraper'; * * const result = await Ytdl.mp4("https://youtube.com/.../"); * console.log(result) * ``` * @author YogikId */ mp4: async (url2, quality = "720") => { const urlValidation = validateYouTubeUrl(url2); if (!urlValidation.status) { return createErrorResponse({ message: "Invalid YouTube URL", type: "INVALID_INPUT" /* INVALID_INPUT */ }); } if (!Object.keys(validQualities).includes(quality)) { return createErrorResponse( { message: "Quality not valid!", type: "INVALID_INPUT" /* INVALID_INPUT */ }, { availableQuality: Object.keys(validQualities) } ); } const qualityParam = validQualities[quality]; const initialUrl = `https://p.oceansaver.in/ajax/download.php?button=1&start=1&end=1&format=${qualityParam}&iframe_source=https://allinonetools.com/&url=${encodeURIComponent(url2)}`; try { const firstResponse = await import_axios2.default.get( initialUrl, { timeout: 3e4, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } } ); if (!firstResponse.data?.progress_url) { return createErrorResponse("Failed to proceed download", { type: "API_ERROR" /* API_ERROR */ }); } const metadata = { title: firstResponse.data.info?.title || "Unknown Title", thumbnail: firstResponse.data.info?.image, quality: quality === "audio" ? void 0 : quality, type: quality === "audio" ? "mp3" : "mp4" }; try { const downloadUrl = await waitForDownloadUrl(firstResponse.data.progress_url); metadata.downloadUrl = downloadUrl; return createSuccessResponse(metadata); } catch (timeoutError) { const msg = timeoutError instanceof Error ? timeoutError.message : String(timeoutError); return createErrorResponse(msg, { type: "NETWORK_ERROR" /* NETWORK_ERROR */ }); } } catch (error) { if (error.code === "ECONNABORTED") { return createErrorResponse("Request timeout", { type: "NETWORK_ERROR" /* NETWORK_ERROR */ }); } const ax = error; const serverMsg = typeof ax.response?.data === "object" && ax.response?.data !== null && "message" in ax.response.data ? ax.response.data.message : void 0; return createErrorResponse( serverMsg ?? ax.message ?? "Video Download Failed", { type: "API_ERROR" /* API_ERROR */ } ); } } }; var HEADERS = { "Referer": "https://ytmp3.cc/", "Origin": "https://ytmp3.cc/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0" }; async function hit(url2, description, returnType = "text") { const listReturnType = ["text", "json"]; if (!listReturnType.includes(returnType)) { throw new Error(`${returnType} invalid. `); } let result; let response2; try { response2 = await fetch(url2, { headers: HEADERS }); const data = await response2.text(); result = data; try { if (returnType === "json") { result = JSON.parse(data); } } catch (error) { throw new Error(`Failed to change return type to ${returnType}. ${error.message}`); } return { result, response: response2 }; } catch (error) { throw new Error( `Fetch failed at ${description} Reason: ${error.message} Status: ${response2?.status || "N/A"} ${response2?.statusText || "N/A"} Response body: ${result || "N/A"}` ); } } async function getAuthCode() { const { result: html, response } = await hit("https://ytmp3.cc", "hit homepage ytmp3cc"); const valueOnHtmlMatch = html.match(/<script[^>]*>(.*?)<\/script>/i)?.[1]; if (!valueOnHtmlMatch) { throw new Error(`Failed to get regex match for code value in html`); }