69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import Router from "@koa/router";
|
|
import Koa from "koa";
|
|
|
|
type Constructor<T = {}> = new (...args: any[]) => T;
|
|
|
|
type Route = {
|
|
method: string;
|
|
path: string;
|
|
fn: any;
|
|
};
|
|
|
|
const routeSymbol = Symbol("routeSymbol");
|
|
|
|
export function get(path: string) {
|
|
return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) {
|
|
if (context.metadata) {
|
|
if (!context.metadata[routeSymbol]) {
|
|
context.metadata[routeSymbol] = [] as Route[];
|
|
}
|
|
context.metadata[routeSymbol].push({method: 'get', path, fn: originalMethod});
|
|
}
|
|
return originalMethod;
|
|
}
|
|
}
|
|
|
|
export function post(path: string) {
|
|
return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) {
|
|
if (context.metadata) {
|
|
if (!context.metadata[routeSymbol]) {
|
|
context.metadata[routeSymbol] = [] as Route;
|
|
}
|
|
context.metadata[routeSymbol].push({method: 'post', path, fn: originalMethod});
|
|
}
|
|
return originalMethod;
|
|
}
|
|
}
|
|
|
|
export function middleware(fn: any, path: string = '') {
|
|
return function middlewareDecorator (constructor: any, context: ClassDecoratorContext) {
|
|
if (context.metadata) {
|
|
if (!context.metadata[routeSymbol]) {
|
|
context.metadata[routeSymbol] = [];
|
|
}
|
|
context.metadata[routeSymbol].unshift({method: 'use', path, fn});
|
|
}
|
|
return constructor;
|
|
}
|
|
}
|
|
|
|
export function router(prefix: string) {
|
|
return function routerDecorator<T extends Constructor>(constructor: T, context: ClassDecoratorContext<T>) {
|
|
return class KoaRouter extends constructor {
|
|
public router: Router;
|
|
constructor(...args: any[]) {
|
|
super(...args);
|
|
this.router = new Router({prefix});
|
|
for (const route of context.metadata?.[routeSymbol] || [] satisfies Route[]) switch (route.method) {
|
|
case "get": this.router.get(route.path, route.fn); break;
|
|
case "post": this.router.post(route.path, route.fn); break;
|
|
case 'use': this.router.use(route.fn); break;
|
|
}
|
|
}
|
|
|
|
public injectInto(app: Koa) {
|
|
app.use(this.router.routes()).use(this.router.allowedMethods());
|
|
}
|
|
}
|
|
}
|
|
} |