Spaces:
Running
Running
File size: 3,771 Bytes
1628025 fe17679 1628025 433085e e9affa5 67bacb2 fe17679 1628025 e9affa5 1628025 721abf7 1628025 e9affa5 721abf7 e9affa5 1628025 e9affa5 1628025 e9affa5 433085e 721abf7 fe17679 5d056c4 fe17679 721abf7 e9affa5 721abf7 e9affa5 1628025 e9affa5 67bacb2 1628025 e9affa5 1628025 e9affa5 3787f0d fe4d244 8b3449a 96594d4 1628025 e9affa5 1628025 8b3449a fda6ff3 1628025 ac9dbd5 8b3449a ac9dbd5 1628025 fda6ff3 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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import { Router, Express } from "express";
import * as glob from "glob";
import path from "path";
import swaggerUi from "swagger-ui-express";
import { BaseController } from "./lib/controllers/controller.base";
import { validationErrorHandler } from "./helpers/validation.helper";
import { JsonResponse } from "@lib/responses/json-response";
import { errorHandlerMiddleware } from "middlewares/error-handler.middleware";
import { swaggerRegistry } from "@lib/swagger/swagger";
/**
* Sets the routes for the Express app.
*
* @param app - The Express app.
*/
export const setAppRoutes = async (app: Express) => {
const mainRouter = Router();
await importControllers(mainRouter);
await 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 = async (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);
// docs
router.use(
"/docs",
swaggerUi.serve,
swaggerUi.setup(swaggerRegistry.generateSwaggerDocument(), {
customCss: ".swagger-ui .topbar { display: none }",
customSiteTitle: "API Documentation",
swaggerOptions: {
layout: "StandaloneLayout",
deepLinking: true,
docExpansion: "none",
filter: true,
tagsSorter: "alpha",
operationsSorter: "alpha",
showMutatedRequest: true,
showMutatedResponse: true,
showRequestDuration: true,
persistAuthorization: true,
displayRequestDuration: true,
withCredentials: true,
},
})
);
// Invalid URL handler
router.all("*", (req: any, res: any) => {
JsonResponse.error(
{
error: "Invalid URL!",
status: 404,
},
res
);
});
// Error handler
router.use(errorHandlerMiddleware);
};
/* 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();
console.log("importing controllers...");
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);
})
);
console.log("controllers imported!");
};
/**
* 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;
};
|