feat: add creator info middleware from MiruroAPI

- Add src/middleware/creatorInfo.js (ESM adapted)
- Injects creator attribution (name, GitHub, Telegram, timestamp) into every JSON response
- Updates server.js to use addCreatorInfo middleware
- Updates CHANGELOG.md, README.md, and docs/architecture.md
This commit is contained in:
Shinei Nouzen
2026-07-04 15:31:59 +05:30
parent 5cf908fb1e
commit 5ca688ab45
5 changed files with 95 additions and 1 deletions
+1
View File
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.0.0] - 2026-07-04
### Added
- **Creator Info Middleware**: Injects creator attribution (name, GitHub, Telegram, timestamp) into every JSON response
- **Multi-Mirror Fallback System**: Automatic failover across 5 mirror domains (anikototv.to, anikoto.cz, anikoto.me, anikoto.net, anikototv.se)
- **LRU Cache with Configurable TTL**: Replaced basic Map cache with LRU cache supporting per-endpoint TTL (3min to 60min)
- **Response Compression**: Added gzip compression middleware (level 6, 1024 byte threshold)
+3
View File
@@ -339,6 +339,9 @@ AniKotoAPI/
│ │ ├── 📄 extractPages.helper.js # 📃 Page fetcher
│ │ └── 📄 formatTitle.helper.js # 🔤 Title formatter
│ │
│ ├── 📂 middleware/ # 🔧 Express middleware
│ │ └── 📄 creatorInfo.js # ✍️ Creator attribution injection
│ │
│ └── 📂 routes/ # 🛤️ Express routes
│ ├── 📄 apiRoutes.js # 🌐 Main API routes (33 endpoints)
│ └── 📄 category.route.js # 🏷️ Category routes
+13 -1
View File
@@ -84,6 +84,9 @@ AniKotoAPI/
│ ├── mirror.helper.js # Multi-mirror fallback (5 domains)
│ └── extractPages.helper.js # Page fetching with mirror fallback
│
│ └── middleware/
│ └── creatorInfo.js # Creator attribution injection
│
├── test.js # Test suite (27 tests)
├── agents/ # AI agent prompts (6 agents)
└── CHANGELOG.md # Version history
@@ -100,6 +103,7 @@ AniKotoAPI/
| Caching | LRU cache with configurable TTL |
| Compression | gzip (level 6, 1024 byte threshold) |
| Mirror Fallback | 5 mirror domains with health checks |
| Middleware | Creator info attribution injection |
| Static Files | Express static middleware |
## Request Flow
@@ -109,6 +113,14 @@ Client Request
↓
Vercel Routes (/api/* → server.js)
↓
Express Middleware
↓
├── CORS
├── Security Headers
├── Compression (gzip)
├── Rate Limiting
├── Creator Info Injection
↓
Express Router (apiRoutes.js)
↓
Controller (e.g., search.controller.js)
@@ -119,7 +131,7 @@ HTTP Request to anikototv.to (with headers)
↓
Cheerio parses HTML response
↓
Returns structured JSON
Returns structured JSON with Creator Attribution
↓
Client Response
```
+4
View File
@@ -26,6 +26,7 @@ import { fileURLToPath } from "url";
import { dirname } from "path";
import { createApiRoutes } from "./src/routes/apiRoutes.js";
import { getCacheStats } from "./src/helper/cache.helper.js";
import { addCreatorInfo } from "./src/middleware/creatorInfo.js";
dotenv.config();
@@ -160,6 +161,9 @@ app.get("/api/cache/stats", (req, res) => {
res.json({ success: true, results: getCacheStats() });
});
// ---- FEATURE: Creator info middleware (injects attribution into all responses) ----
app.use(addCreatorInfo);
createApiRoutes(app, jsonResponse, jsonError);
// ══════════════════════════════════════════════════════════════
+74
View File
@@ -0,0 +1,74 @@
/*
* ======= • ======= • ======= • ======= • =======• =======
* AniKotoAPI — creatorInfo.js
* Repository: https://github.com/Shineii86/AniKotoAPI
*
* @description
* Express middleware that injects creator attribution metadata
* into every JSON API response. Overrides res.json() to append
* author details and a server-side timestamp, unless the
* response already contains creator information.
*
* @exports
* addCreatorInfo — Express middleware function
* creatorInfo — Static creator metadata object
*
* @author Shinei Nouzen
* @license MIT
* ======= • ======= • ======= • ======= • =======• =======
*/
// ══════════════════════════════════════════════════════════════
// CREATOR METADATA
// ══════════════════════════════════════════════════════════════
// NOTE: Injected into every response unless `data.creator` already exists
const creatorInfo = {
creator: "Shinei Nouzen",
github: "https://github.com/Shineii86",
telegram: "https://telegram.me/Shineii86",
message: "Built with ❤️ by Shinei Nouzen",
};
// ══════════════════════════════════════════════════════════════
// MIDDLEWARE
// ══════════════════════════════════════════════════════════════
/**
* Express middleware that enriches every JSON response with
* creator attribution and an IN-formatted timestamp.
*
* @param {import('express').Request} req - Express request object
* @param {import('express').Response} res - Express response object
* @param {import('express').NextFunction} next - Passes control forward
* @returns {void}
*
* @example
* app.use(addCreatorInfo);
* res.json({ anime: [...] });
* // Response includes creator, github, telegram, message, and timestamp
*/
const addCreatorInfo = (req, res, next) => {
// NOTE: Preserve the original json method so we can wrap it
const originalJson = res.json.bind(res);
// NOTE: Monkey-patch res.json to inject creator info
res.json = (data) => {
// NOTE: Only inject if data is a plain object and missing creator field
if (typeof data === "object" && data !== null && !data.creator) {
data = {
...data,
creator: creatorInfo.creator,
github: creatorInfo.github,
telegram: creatorInfo.telegram,
timestamp: new Date().toLocaleString("en-IN", { timeZone: "Asia/Kolkata", hour12: true }),
};
}
return originalJson(data);
};
next();
};
export { addCreatorInfo, creatorInfo };
// ══════════════════════════════════════════════════════════════ END: creatorInfo.js