class mangapark { constructor(fetchPath, cheerioPath, browser) { this.baseUrl = "https://mangapark.net/apo"; this.fetch = require(fetchPath) this.browser = browser; this.type = "book-board"; } async fetchSearchResult(query = "", page = 1) { const res = await this.fetch(`${this.baseUrl}/`, { method: "POST", headers: { "accept": "*/*", "content-type": "application/json", "x-apollo-operation-name": "get_searchComic", "sec-ch-ua": "\"Chromium\";v=\"139\", \"Not;A=Brand\";v=\"99\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", "Referer": `https://mangapark.net/search?word=${encodeURIComponent(query)}` }, body: JSON.stringify({ query: "query get_searchComic($select: SearchComic_Select) { get_searchComic(select: $select) { reqPage reqSize reqSort reqWord newPage paging { total pages page init size skip limit prev next } items { id data { id dbStatus name origLang tranLang urlPath urlCover600 urlCoverOri genres altNames authors artists is_hot is_new sfw_result score_val follows reviews comments_total max_chapterNode { id data { id dateCreate dbStatus isFinal sfw_result dname urlPath is_new userId userNode { id data { id name uniq avatarUrl urlPath } } } } } sser_follow sser_lastReadChap { date chapterNode { id data { id dbStatus isFinal sfw_result dname urlPath is_new userId userNode { id data { id name uniq avatarUrl urlPath } } } } } } } }", variables: { select: { word: query, size: 10, page: 1, sortby: "field_score" } } }) }); const data = await res.json(); const results = data.data.get_searchComic.items.map(m => ({ id: m.data.urlPath, title: m.data.name, image: `https://mangapark.net/${m.data.urlCoverOri}`, sampleImageUrl: `https://mangapark.net/${m.data.urlCoverOri}`, tags: m.data.genres, type: "book" })); return { results: results, hasNextPage: false, page }; } async findChapters(mangaId) { const comicId = mangaId.split('/title/')[1]?.split('-')[0]; if (!comicId) throw new Error('comicId inválido en mangaId'); const res = await this.fetch(this.baseUrl + "/", { method: "POST", headers: { "accept": "*/*", "content-type": "application/json", "x-apollo-operation-name": "get_comicChapterList", "sec-ch-ua": "\"Chromium\";v=\"139\", \"Not;A=Brand\";v=\"99\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", "Referer": `https://mangapark.net${mangaId}` }, body: JSON.stringify({ query: "query get_comicChapterList($comicId: ID!) { get_comicChapterList(comicId: $comicId){ id data { id comicId isFinal volume serial dname title urlPath sfw_result } } }\n", variables: { comicId } }) }); const json = await res.json(); let list = json.data.get_comicChapterList; list.sort((a, b) => a.data.serial - b.data.serial); let chapters = list.map((c, i) => ({ id: `https://mangapark.net${c.data.urlPath}`, title: c.data.dname || c.data.title || `Chapter ${c.data.serial}`, chapter: Number(c.data.serial), index: i, language: "en" })); return { chapters: chapters, }; } async findChapterPages(chapterUrl) { const res = await this.fetch(chapterUrl); const html = await res.text(); const scripts = html.match(/]*>[\s\S]*?<\/script>/gi) || []; let found = []; for (const s of scripts) { const matches = s.match(/https?:\/\/[^"' ]+\.(?:jpg|jpeg|png|webp)/gi); if (matches) found.push(...matches); } const urls = [...new Set(found)]; const clean = urls.filter(u => !u.includes("icon") && !u.includes("logo") && !u.includes("banner") && !u.includes("thumb") ); return clean.map((url, index) => ({ url, index })); } } module.exports = { mangapark };