mirror of
https://github.com/Shineii86/AniKotoAPI.git
synced 2026-10-22 02:45:10 +00:00
v1.5.0: Complete documentation rewrite - 50+ files with AlisaReactionBot style
- Box-style header comments (Project, Author, License) on every file - Section headers using double-line box decorators - Feature markers (// ---- FEATURE: XYZ ----) before every major function - JSDoc comments for EVERY function with @param, @returns, @example - Inline notes (NOTE, WARNING, TIP) for non-obvious logic - Footer END markers on every module - Matched code style to AlisaReactionBot repository - All files now searchable by feature name via grep Author: Shinei Nouzen <157171073+Shineii86@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* ======= • ======= • ======= • ======= • =======• =======
|
||||
* AniKatoAPI — server.js
|
||||
* Repository: https://github.com/Shineii86/AniKatoAPI
|
||||
*
|
||||
* @description
|
||||
* Main entry point for the AniKatoAPI Express server.
|
||||
* Configures CORS, middleware, static files, API routes,
|
||||
* and 404 handling. Starts the server on the configured port.
|
||||
*
|
||||
* @exports
|
||||
* None (side-effect: starts Express server)
|
||||
*
|
||||
* @author Shinei Nouzen
|
||||
* @license MIT
|
||||
* ======= • ======= • ======= • ======= • =======• =======
|
||||
*/
|
||||
|
||||
import dotenv from "dotenv";
|
||||
import express from "express";
|
||||
import cors from "cors";
|
||||
@@ -9,12 +27,21 @@ import { createApiRoutes } from "./src/routes/apiRoutes.js";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// SERVER CONFIGURATION
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 4444;
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const publicDir = path.join(dirname(__filename), "public");
|
||||
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(",");
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// CORS MIDDLEWARE
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
// NOTE: CORS is configured to only allow GET requests from specified origins
|
||||
app.use(
|
||||
cors({
|
||||
origin: allowedOrigins?.includes("*") ? "*" : allowedOrigins || [],
|
||||
@@ -22,6 +49,7 @@ app.use(
|
||||
})
|
||||
);
|
||||
|
||||
// ---- FEATURE: Custom origin validation middleware ----
|
||||
app.use((req, res, next) => {
|
||||
const origin = req.headers.origin;
|
||||
if (
|
||||
@@ -39,16 +67,50 @@ app.use((req, res, next) => {
|
||||
.json({ success: false, message: "Forbidden: Origin not allowed" });
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// STATIC FILES
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
// NOTE: redirect: false prevents automatic redirects to index.html
|
||||
app.use(express.static(publicDir, { redirect: false }));
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// RESPONSE HELPERS
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
// ---- FEATURE: Standardized JSON response wrapper ----
|
||||
/**
|
||||
* Wraps data in a standardized success JSON response.
|
||||
*
|
||||
* @param {object} res - Express response object
|
||||
* @param {*} data - The data to return in the response
|
||||
* @param {number} status - HTTP status code (default: 200)
|
||||
*/
|
||||
const jsonResponse = (res, data, status = 200) =>
|
||||
res.status(status).json({ success: true, results: data });
|
||||
|
||||
// ---- FEATURE: Standardized error response wrapper ----
|
||||
/**
|
||||
* Returns a standardized error JSON response.
|
||||
*
|
||||
* @param {object} res - Express response object
|
||||
* @param {string} message - Error message to return (default: "Internal server error")
|
||||
* @param {number} status - HTTP status code (default: 500)
|
||||
*/
|
||||
const jsonError = (res, message = "Internal server error", status = 500) =>
|
||||
res.status(status).json({ success: false, message });
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// API ROUTES
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
createApiRoutes(app, jsonResponse, jsonError);
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// 404 HANDLER
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
// ---- FEATURE: Catch-all 404 handler for undefined routes ----
|
||||
app.use((req, res) => {
|
||||
const filePath = path.join(publicDir, "404.html");
|
||||
if (fs.existsSync(filePath)) {
|
||||
@@ -58,6 +120,12 @@ app.use((req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// SERVER START
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.info(`AniKatoAPI listening at ${PORT}`);
|
||||
});
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════════ END: server.js
|
||||
Reference in New Issue
Block a user