animex.mjs

javascriptCreated 8 Feb 2026, 04:4836 views
Wrapper from AnimeXNonton apk
#anime#search#fun
javascript
/***
  @ 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(/<br\s*\/?>/gi, '\n')
        .replace(/<\/p>/gi, '\n\n')
        .replace(/&nbsp;/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');
    }
};