diff --git a/index.ts b/index.ts index b9e2e38..390fe3a 100644 --- a/index.ts +++ b/index.ts @@ -1,11 +1,12 @@ -import { apiMessage, errorMessage, otherMessage } from "./src/logger"; -import fileUpload, { UploadedFile } from "express-fileupload"; -import express, { Request, Response } from "express"; -import { url, key, PORT } from "./config.json"; +import { errorMessage, otherMessage } from "./src/logger"; +import { loadEndpoints } from "./src/helper"; +import fileUpload from "express-fileupload"; import { existsSync, mkdirSync } from "fs"; +import { PORT } from "./config.json"; +import express from "express"; import { join } from "path"; -const filesDir = join(__dirname, "src", "files"); +const filesDir = join(__dirname, "src", "files"); if (!existsSync(filesDir)) { mkdirSync(filesDir); } @@ -15,70 +16,15 @@ const app = express(); try { app.use(fileUpload()); - app.post("/save/:name", async (req: Request, res: Response) => { - try { - const apiKey = req.headers["API-KEY"]; - if (apiKey !== key) { - errorMessage("Invalid API key provided"); - return res - .status(400) - .send({ sucsess: false, message: "Invalid API key" }); - } - apiMessage(req.path, "User is trying to save a file"); - - const file = req.files?.file as UploadedFile; - if (!file) { - errorMessage("No file provided for upload"); - return res - .status(400) - .send({ sucsess: false, message: "No file provided" }); - } - - const fileName = req.params.name; - const filePath = join(__dirname, "src", "files", fileName); - if (existsSync(filePath)) { - errorMessage(`File ${fileName} already exists`); - return res - .status(400) - .json({ sucsess: false, message: `File ${fileName} already exists` }); - } - - await file.mv(filePath); - - apiMessage(req.path, `File ${fileName} saved successfully`); - return res.status(200).json({ - sucsess: true, - message: `File has been saved at ${url}/${fileName}`, - }); - } catch (err) { - errorMessage(err as string); - return res - .status(500) - .json({ sucsess: false, message: "Internal server error" }); - } - }); - - app.get("/:name", async (req: Request, res: Response) => { - try { - const fileName = req.params.name; - apiMessage(req.path, `User is trying to get a file - ${fileName}`); - const filePath = join(__dirname, "src", "files", fileName); - if (!existsSync(filePath)) { - errorMessage(`File ${fileName} not found`); - return res - .status(404) - .send({ sucsess: false, message: `File ${fileName} not found` }); - } - - apiMessage(req.path, `File ${fileName} found`); - return res.sendFile(filePath); - } catch (err) { - errorMessage(err as string); - return res - .status(500) - .send({ sucsess: false, message: "Internal server error" }); - } - }); + const endpointsDir = join(__dirname, "src", "endpoints"); + const result = loadEndpoints(endpointsDir, app); + if (result !== undefined) { + otherMessage( + `Loaded ${result.loaded} endpoints, skipped ${result.skipped} endpoints` + ); + } else { + otherMessage(`No endpoints found in ${endpointsDir}`); + } app.listen(PORT, () => { otherMessage(`Server started on port ${PORT} @ http://localhost:${PORT}`); diff --git a/src/endpoints/file.ts b/src/endpoints/file.ts new file mode 100644 index 0000000..85ce05d --- /dev/null +++ b/src/endpoints/file.ts @@ -0,0 +1,28 @@ +import { Application, Request, Response } from "express"; +import { apiMessage, errorMessage } from "../logger"; +import { existsSync } from "fs"; +import { join } from "path"; + +export default (app: Application) => { + app.get("/:name", async (req: Request, res: Response) => { + try { + const fileName = req.params.name; + apiMessage(req.path, `User is trying to get a file - ${fileName}`); + const filePath = join(__dirname, "../", "files", fileName); + if (!existsSync(filePath)) { + errorMessage(`File ${fileName} not found`); + return res + .status(404) + .send({ sucsess: false, message: `File ${fileName} not found` }); + } + + apiMessage(req.path, `File ${fileName} found`); + return res.sendFile(filePath); + } catch (err) { + errorMessage(err as string); + return res + .status(500) + .send({ sucsess: false, message: "Internal server error" }); + } + }); +}; diff --git a/src/endpoints/save.ts b/src/endpoints/save.ts new file mode 100644 index 0000000..c855d8b --- /dev/null +++ b/src/endpoints/save.ts @@ -0,0 +1,51 @@ +import { Application, Request, Response } from "express"; +import { apiMessage, errorMessage } from "../logger"; +import { UploadedFile } from "express-fileupload"; +import { url, key } from "../../config.json"; +import { existsSync } from "fs"; +import { join } from "path"; + +export default (app: Application) => { + app.post("/save/:name", async (req: Request, res: Response) => { + try { + const apiKey = req.headers["API-KEY"]; + if (apiKey !== key) { + errorMessage("Invalid API key provided"); + return res + .status(400) + .send({ sucsess: false, message: "Invalid API key" }); + } + apiMessage(req.path, "User is trying to save a file"); + + const file = req.files?.file as UploadedFile; + if (!file) { + errorMessage("No file provided for upload"); + return res + .status(400) + .send({ sucsess: false, message: "No file provided" }); + } + + const fileName = req.params.name; + const filePath = join(__dirname, "../", "files", fileName); + if (existsSync(filePath)) { + errorMessage(`File ${fileName} already exists`); + return res + .status(400) + .json({ sucsess: false, message: `File ${fileName} already exists` }); + } + + await file.mv(filePath); + + apiMessage(req.path, `File ${fileName} saved successfully`); + return res.status(200).json({ + sucsess: true, + message: `File has been saved at ${url}/${fileName}`, + }); + } catch (err) { + errorMessage(err as string); + return res + .status(500) + .json({ sucsess: false, message: "Internal server error" }); + } + }); +}; diff --git a/src/helper.ts b/src/helper.ts index e69de29..a75971d 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -0,0 +1,38 @@ +import { otherMessage, errorMessage } from './logger'; +import { readdirSync, statSync } from 'fs'; +import { Application } from 'express'; +import { join } from 'path'; + +export const loadEndpoints = (directory: string, app: Application) => { + try { + const items = readdirSync(directory); + + let skipped = 0; + let loaded = 0; + + for (const item of items) { + const itemPath = join(directory, item); + const stats = statSync(itemPath); + if (stats.isDirectory()) { + const result = loadEndpoints(itemPath, app); + if (result) { + skipped += result.skipped; + loaded += result.loaded; + } + } else if (item.toLowerCase().endsWith('.ts')) { + if (item.toLowerCase().includes('disabled')) { + skipped++; + continue; + } + loaded++; + // eslint-disable-next-line + const route = require(itemPath).default; + route(app); + otherMessage(`Loaded ${itemPath.split('/src/endpoints/')[1].split('.ts')[0]} endpoint`); + } + } + return { loaded, skipped }; + } catch (error: any) { + errorMessage(`Error loading endpoints: ${error}`); + } +}; \ No newline at end of file