Updating Koa decorators

This commit is contained in:
2026-04-14 12:20:28 +01:00
parent 8e5a8d073f
commit bee509b4b6
3 changed files with 24 additions and 34 deletions
+1
View File
@@ -520,6 +520,7 @@
"resolved": "https://registry.npmjs.org/koa/-/koa-3.2.0.tgz", "resolved": "https://registry.npmjs.org/koa/-/koa-3.2.0.tgz",
"integrity": "sha512-TrM4/tnNY7uJ1aW55sIIa+dqBvc4V14WRIAlGcWat9wV5pRS9Wr5Zk2ZTjQP1jtfIHDoHiSbPuV08P0fUZo2pg==", "integrity": "sha512-TrM4/tnNY7uJ1aW55sIIa+dqBvc4V14WRIAlGcWat9wV5pRS9Wr5Zk2ZTjQP1jtfIHDoHiSbPuV08P0fUZo2pg==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"accepts": "^1.3.8", "accepts": "^1.3.8",
"content-disposition": "~1.0.1", "content-disposition": "~1.0.1",
+21 -32
View File
@@ -9,30 +9,15 @@ type Route = {
fn: any; fn: any;
}; };
export class BaseRouter { const routeSymbol = Symbol("routeSymbol");
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());
}
}
export function get(path: string) { export function get(path: string) {
return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) { return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) {
if (context.metadata) { if (context.metadata) {
if (!context.metadata.routes) { if (!context.metadata[routeSymbol]) {
context.metadata.routes = []; context.metadata[routeSymbol] = [] as Route[];
} }
// @ts-ignore context.metadata[routeSymbol].push({method: 'get', path, fn: originalMethod});
context.metadata.routes.push({method: 'get', path, fn: originalMethod});
} }
return originalMethod; return originalMethod;
} }
@@ -41,11 +26,10 @@ export function get(path: string) {
export function post(path: string) { export function post(path: string) {
return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) { return function getDecorator (originalMethod: any, context: ClassMethodDecoratorContext) {
if (context.metadata) { if (context.metadata) {
if (!context.metadata.routes) { if (!context.metadata[routeSymbol]) {
context.metadata.routes = []; context.metadata[routeSymbol] = [] as Route;
} }
// @ts-ignore context.metadata[routeSymbol].push({method: 'post', path, fn: originalMethod});
context.metadata.routes.push({method: 'post', path, fn: originalMethod});
} }
return originalMethod; return originalMethod;
} }
@@ -54,11 +38,10 @@ export function post(path: string) {
export function middleware(fn: any, path: string = '') { export function middleware(fn: any, path: string = '') {
return function middlewareDecorator (constructor: any, context: ClassDecoratorContext) { return function middlewareDecorator (constructor: any, context: ClassDecoratorContext) {
if (context.metadata) { if (context.metadata) {
if (!context.metadata.routes) { if (!context.metadata[routeSymbol]) {
context.metadata.routes = []; context.metadata[routeSymbol] = [];
} }
// @ts-ignore context.metadata[routeSymbol].unshift({method: 'use', path, fn});
context.metadata.routes.unshift({method: 'use', path, fn});
} }
return constructor; return constructor;
} }
@@ -66,14 +49,20 @@ export function middleware(fn: any, path: string = '') {
export function router(prefix: string) { export function router(prefix: string) {
return function routerDecorator<T extends Constructor>(constructor: T, context: ClassDecoratorContext<T>) { return function routerDecorator<T extends Constructor>(constructor: T, context: ClassDecoratorContext<T>) {
return class extends constructor { return class KoaRouter extends constructor {
public router: Router;
constructor(...args: any[]) { constructor(...args: any[]) {
super(...args); super(...args);
if (this instanceof BaseRouter) {
this.router = new Router({prefix}); this.router = new Router({prefix});
// @ts-ignore for (const route of context.metadata?.[routeSymbol] || [] satisfies Route[]) switch (route.method) {
this.processRoutes(context.metadata?.routes || [] satisfies Route[]); 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());
} }
} }
} }
+2 -2
View File
@@ -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 Koa from "koa";
import {extractSubsonicApiContext, subsonicErrorHandler} from "./middleware"; import {extractSubsonicApiContext, subsonicErrorHandler} from "./middleware";
import {Renderer} from "./renderer"; import {Renderer} from "./renderer";
@@ -6,7 +6,7 @@ import {Renderer} from "./renderer";
@router('/rest') @router('/rest')
@middleware(subsonicErrorHandler) @middleware(subsonicErrorHandler)
@middleware(extractSubsonicApiContext) @middleware(extractSubsonicApiContext)
export class SubsonicRouter extends BaseRouter { export class SubsonicRouter {
@get('/ping') @get('/ping')
ping(ctx: Koa.Context) { ping(ctx: Koa.Context) {
console.log('ping'); console.log('ping');