feat: initial project setup for AniKatoAPI

- Express.js server with Vercel deployment support
- Complete API endpoints for anikototv.to anime data
- Home, search, info, episodes, stream, schedule endpoints
- Category filtering and genre support
- Caching system with 5-minute TTL
- CORS configuration
- Public documentation page
- Docker and Render deployment configs
- MIT License
This commit is contained in:
Sʜɪɴᴇɪ Nᴏᴜᴢᴇɴ
2026-06-08 15:08:22 +05:30
commit 3815521b0d
47 changed files with 1846 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000;
const getCache = (key) => {
const item = cache.get(key);
if (item && Date.now() - item.timestamp < CACHE_TTL) {
return item.data;
}
cache.delete(key);
return null;
};
const setCache = (key, data) => {
cache.set(key, { data, timestamp: Date.now() });
};
const clearCache = () => {
cache.clear();
};
export { getCache, setCache, clearCache };
+12
View File
@@ -0,0 +1,12 @@
const countPages = ($) => {
const pages = [];
$(".pagination li a").each((i, el) => {
const text = $(el).text().trim();
if (!isNaN(text) && text !== "") {
pages.push(parseInt(text));
}
});
return pages.length > 0 ? Math.max(...pages) : 1;
};
export { countPages };
+16
View File
@@ -0,0 +1,16 @@
import * as cheerio from "cheerio";
import axios from "axios";
import { headers } from "../configs/header.config.js";
const extractPages = async (url, page = 1) => {
try {
const finalUrl = page > 1 ? `${url}?page=${page}` : url;
const { data } = await axios.get(finalUrl, { headers });
const $ = cheerio.load(data);
return $;
} catch (error) {
throw error;
}
};
export { extractPages };
+9
View File
@@ -0,0 +1,9 @@
const formatTitle = (title) => {
if (!title) return "";
return title
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
};
export { formatTitle };