/*** @ Base: https://play.google.com/store/apps/details?id=com.streamx.nontonanimex @ Author: Shannz @ Note: Wrapper from AnimeXNonton apk ***/ import axios from 'axios'; import qs from 'qs'; const CONFIG = { BASE_URL: "https://animeku.my.id/nontonanime-x/phalcon/api/", HEADERS: { 'User-Agent': 'okhttp/3.12.13', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'Content-Type': 'application/x-www-form-urlencoded', 'Cache-Control': 'max-age=0', 'Data-Agent': 'AnimeXNonton 2026.1.12/12' } }; function cleanHtml(html) { if (!html) return ""; return html .replace(//gi, '\n') .replace(/<\/p>/gi, '\n\n') .replace(/ /g, ' ') .replace(/<[^>]*>?/gm, '') .replace(/\n\s*\n/g, '\n\n') .trim(); } async function request(endpoint, data = {}, method = 'POST') { try { if (method === 'POST') { data.isAPKvalid = 'true'; } const options = { method: method, url: CONFIG.BASE_URL + endpoint, headers: CONFIG.HEADERS, data: method === 'POST' ? qs.stringify(data) : undefined }; const response = await axios.request(options); return response.data; } catch (error) { console.error(`[AnimeKu Error] ${endpoint}:`, error.message); return { status: "error", message: error.message }; } } export const animeku = { latest: async (page = 1, count = 20) => { return await request('get_posts/', { 'page': page.toString(), 'count': count.toString() }); }, ongoing: async (page = 1, count = 100) => { return await request('get_category_ongoing/', { 'page': page.toString(), 'count': count.toString(), 'lang': 'All' }); }, search: async (query, page = 1) => { return await request('search_category_collection/', { 'search': query, 'page': page.toString(), 'count': '20', 'lang': 'All' }); }, detail: async (categoryId) => { try { const episodeData = await request('get_category_posts_secure/', { 'id': categoryId.toString() }); if (episodeData.status !== 'ok' || !episodeData.posts || episodeData.posts.length === 0) { return { status: 'error', message: 'Episodes not found or invalid Category ID' }; } const firstEpisode = episodeData.posts[0]; const channelId = firstEpisode.channel_id; const descData = await request('get_post_description/', { 'channel_id': channelId.toString() }); let cleanDescription = ""; let info = {}; if (descData.status === 'ok') { cleanDescription = cleanHtml(descData.channel_description); info = { title: descData.category_name || descData.channel_name, genres: descData.genre, rating: descData.rating, status: descData.status, synopsis: cleanDescription, image: descData.img_url, year: descData.years }; } return { status: 'ok', series_info: info, category_id: categoryId, total_episodes: episodeData.count_total, episodes: episodeData.posts }; } catch (error) { console.error("[Detail Error]", error); return { status: "error", message: error.message }; } }, byGenre: async (genre1, genre2 = '', sort = 'ASC', page = 1) => { return await request('get_anime_by_genre/', { 'genre1': genre1, 'genre2': genre2, 'lang': 'All', 'sort': sort, 'page': page.toString(), 'count': '20' }); }, getGenreList: async () => { return await request('get_anime_genre_list/', {}, 'GET'); } };