Spaces:
Sleeping
Sleeping
File size: 3,118 Bytes
1628025 433085e e9affa5 1628025 e9affa5 1628025 e9affa5 1628025 e9affa5 1628025 e9affa5 1628025 e9affa5 433085e e9affa5 1628025 e9affa5 1628025 e9affa5 3787f0d e9affa5 3787f0d e9affa5 3787f0d 1628025 e9affa5 1628025 e9affa5 3787f0d fe4d244 8b3449a 96594d4 1628025 e9affa5 1628025 8b3449a 1628025 ac9dbd5 8b3449a ac9dbd5 1628025 e9affa5 1628025 ac9dbd5 1628025 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
import { Router, Express } from "express";
import * as glob from "glob";
import path from "path";
import { BaseController } from "./lib/controllers/controller.base";
import { validationErrorHandler } from "./helpers/validation.helper";
import { JsonResponse } from "@lib/responses/json-response";
/**
* Sets the routes for the Express app.
*
* @param app - The Express app.
*/
export const setAppRoutes = async (app: Express) => {
const mainRouter = Router();
await importControllers(mainRouter);
setCustomRoutes(mainRouter);
app.use("/api/v1", mainRouter);
};
/* custom routes */
/**
* Sets custom routes for the router.
*
* @param router - The router object to set the routes on.
*/
const setCustomRoutes = (router: Router) => {
// Health check route
router.get("/health", (_req: any, res: any) => {
JsonResponse.success(
{
message: "Server is up!",
data: { success: true },
},
res
);
});
// Validation error handler
router.use(validationErrorHandler);
// Invalid URL handler
router.all("*", (_req: any, res: any) => {
JsonResponse.error(
{
error: "Invalid URL!",
status: 404,
},
res
);
});
// Error handler
router.use((err, req, res, next) => {
try {
err.message = JSON.parse(err.message);
} catch (error) {}
JsonResponse.error(
{
error: err.message || "Internal Server Error",
status: err.status || 500,
},
res
);
console.error(err.message, err.stack);
});
};
/* importing all controllers */
/**
* Finds all controller files in the project.
* @returns An array of strings representing the absolute paths of the controller files.
*/
const findControllerFiles = (): string[] => {
const controllersPath = path
.relative(process.cwd(), path.join(__dirname, "**/*.controller.{ts,js}"))
.replace(/\\/g, "/");
return glob.sync(controllersPath, {}).map((file) => {
return path.resolve(file);
});
};
/**
* Imports controller classes from files, sets up routes for each controller,
* and adds them to the provided router.
*
* @param router - The router to add the routes to.
*/
const importControllers = async (router: Router) => {
const files = findControllerFiles();
await Promise.all(
files.map(async (file) => {
const controllerClass = await importController(file);
if (!controllerClass) return;
const controller: BaseController = new (controllerClass as any)();
controller.setRoutes();
router.use(controller.prefix, controller.router);
})
);
};
/**
* Imports a module from a file and returns the first controller that extends BaseController.
* @param file - The path to the file containing the module.
* @returns The first controller that extends BaseController.
*/
const importController = async (file: string) => {
const controllers = Object.values(await import(file));
return controllers.find(
(controller: { prototype: typeof BaseController }) =>
controller.prototype instanceof BaseController
) as typeof BaseController;
};
|