From bee509b4b65a492f63960a6453d5598acd80d071 Mon Sep 17 00:00:00 2001 From: Nik Barham Date: Tue, 14 Apr 2026 12:20:28 +0100 Subject: [PATCH] Updating Koa decorators --- package-lock.json | 1 + src/base/router.ts | 53 +++++++++++++++++------------------------- src/subsonic/router.ts | 4 ++-- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index a293052..5fff15f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -520,6 +520,7 @@ "resolved": "https://registry.npmjs.org/koa/-/koa-3.2.0.tgz", "integrity": "sha512-TrM4/tnNY7uJ1aW55sIIa+dqBvc4V14WRIAlGcWat9wV5pRS9Wr5Zk2ZTjQP1jtfIHDoHiSbPuV08P0fUZo2pg==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^1.3.8", "content-disposition": "~1.0.1", diff --git a/src/base/router.ts b/src/base/router.ts index 659f5bc..aec284c 100644 --- a/src/base/router.ts +++ b/src/base/router.ts @@ -9,30 +9,15 @@ type Route = { fn: any; }; -export class BaseRouter { - public router!: Router; - - processRoutes(routes: Route[]) { - for (const route of routes) 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.path, route.fn); break; - } - } - - injectInto(app: Koa) { - app.use(this.router.routes()).use(this.router.allowedMethods()); - } -} +const routeSymbol = Symbol("routeSymbol"); export function get(path: string) { return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) { if (context.metadata) { - if (!context.metadata.routes) { - context.metadata.routes = []; + if (!context.metadata[routeSymbol]) { + context.metadata[routeSymbol] = [] as Route[]; } - // @ts-ignore - context.metadata.routes.push({method: 'get', path, fn: originalMethod}); + context.metadata[routeSymbol].push({method: 'get', path, fn: originalMethod}); } return originalMethod; } @@ -41,11 +26,10 @@ export function get(path: string) { export function post(path: string) { return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) { if (context.metadata) { - if (!context.metadata.routes) { - context.metadata.routes = []; + if (!context.metadata[routeSymbol]) { + context.metadata[routeSymbol] = [] as Route; } - // @ts-ignore - context.metadata.routes.push({method: 'post', path, fn: originalMethod}); + context.metadata[routeSymbol].push({method: 'post', path, fn: originalMethod}); } return originalMethod; } @@ -54,11 +38,10 @@ export function post(path: string) { export function middleware(fn: any, path: string = '') { return function middlewareDecorator (constructor: any, context: ClassDecoratorContext) { if (context.metadata) { - if (!context.metadata.routes) { - context.metadata.routes = []; + if (!context.metadata[routeSymbol]) { + context.metadata[routeSymbol] = []; } - // @ts-ignore - context.metadata.routes.unshift({method: 'use', path, fn}); + context.metadata[routeSymbol].unshift({method: 'use', path, fn}); } return constructor; } @@ -66,15 +49,21 @@ export function middleware(fn: any, path: string = '') { export function router(prefix: string) { return function routerDecorator(constructor: T, context: ClassDecoratorContext) { - return class extends constructor { + return class KoaRouter extends constructor { + public router: Router; constructor(...args: any[]) { super(...args); - if (this instanceof BaseRouter) { - this.router = new Router({prefix}); - // @ts-ignore - this.processRoutes(context.metadata?.routes || [] satisfies Route[]); + 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()); + } } } } \ No newline at end of file diff --git a/src/subsonic/router.ts b/src/subsonic/router.ts index 39f7851..836079e 100644 --- a/src/subsonic/router.ts +++ b/src/subsonic/router.ts @@ -1,4 +1,4 @@ -import {BaseRouter, get, middleware, post, router} from "../base/router"; +import {get, middleware, post, router} from "../base/router"; import Koa from "koa"; import {extractSubsonicApiContext, subsonicErrorHandler} from "./middleware"; import {Renderer} from "./renderer"; @@ -6,7 +6,7 @@ import {Renderer} from "./renderer"; @router('/rest') @middleware(subsonicErrorHandler) @middleware(extractSubsonicApiContext) -export class SubsonicRouter extends BaseRouter { +export class SubsonicRouter { @get('/ping') ping(ctx: Koa.Context) { console.log('ping');