Add cubetiq express server module for nodejs

This commit is contained in:
2021-09-16 17:49:43 +07:00
parent 2e80a89398
commit 59572c774c
9 changed files with 194 additions and 112 deletions

53
src/application.ts Normal file
View File

@@ -0,0 +1,53 @@
import express, { Application as ExpressApp, Handler } from "express"
import MetadataKeys from "./constants/metadata.keys"
import { RouteHandler } from "./decorators/handlers.decorator"
export abstract class Application {
private readonly _instance: ExpressApp
get instance(): ExpressApp {
return this._instance
}
constructor() {
this._instance = express()
this._instance.use(express.json())
this._instance.use(express.urlencoded({ extended: false }))
this.registerRoutes()
}
private registerRoutes(): void {
const info: Array<{ api: string; handler: string }> = []
this.controllers.forEach((controller) => {
const controllerInstance: { [handlerName: string]: Handler } =
new controller() as any
const basePath: string = Reflect.getMetadata(
MetadataKeys.BASE_PATH,
controller
)
const routers: RouteHandler[] = Reflect.getMetadata(
MetadataKeys.ROUTERS,
controller
)
const exRouter = express.Router()
routers.forEach(({ method, path, handlerName }) => {
exRouter[method](
path,
controllerInstance[String(handlerName)]
).bind(controllerInstance)
info.push({
api: `${method.toLocaleUpperCase()} ${basePath + path}`,
handler: `${controller.name}.${String(handlerName)}`,
})
})
this._instance.use(basePath, exRouter)
})
console.table(info)
}
abstract get controllers(): Array<any>
}

View File

@@ -0,0 +1,6 @@
enum MetadataKeys {
BASE_PATH = "base_path",
ROUTERS = "routers",
}
export default MetadataKeys

View File

@@ -0,0 +1,7 @@
import MetadataKeys from "../constants/metadata.keys"
export const Controller = (basePath: string): ClassDecorator => {
return (target: any) => {
Reflect.defineMetadata(MetadataKeys.BASE_PATH, basePath, target)
}
}

View File

@@ -0,0 +1,47 @@
import MetadataKeys from "../constants/metadata.keys"
export enum Method {
GET = "get",
POST = "post",
PUT = "put",
DELETE = "delete",
PATCH = "patch",
}
export interface RouteHandler {
method: Method
path: string
handlerName: string | symbol
}
const methodDecoratorFactory = (method: Method) => {
return (path: string = ""): MethodDecorator => {
return (target: any, propertyKey: string | symbol): void => {
const controllerClass = target.constructor
const routers: RouteHandler[] = Reflect.hasMetadata(
MetadataKeys.ROUTERS,
controllerClass
)
? Reflect.getMetadata(MetadataKeys.ROUTERS, controllerClass)
: []
routers.push({
method,
path,
handlerName: propertyKey,
})
Reflect.defineMetadata(
MetadataKeys.ROUTERS,
routers,
controllerClass
)
}
}
}
export const Get = methodDecoratorFactory(Method.GET)
export const Post = methodDecoratorFactory(Method.POST)
export const Put = methodDecoratorFactory(Method.PUT)
export const Delete = methodDecoratorFactory(Method.DELETE)
export const Patch = methodDecoratorFactory(Method.PATCH)

2
src/decorators/index.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./controller.decorator"
export * from "./handlers.decorator"

View File

@@ -1 +1,4 @@
console.log('Welcome to TS Project!');
import "reflect-metadata"
import { Application } from "./application"
export default Application