diff --git a/ts/typedrequest.classes.typedrouter.ts b/ts/typedrequest.classes.typedrouter.ts index 9894c66..4ee4c35 100644 --- a/ts/typedrequest.classes.typedrouter.ts +++ b/ts/typedrequest.classes.typedrouter.ts @@ -8,24 +8,82 @@ import { TypedHandler } from './typedrequest.classes.typedhandler'; * This is thought for reusing the same url endpoint for different methods */ export class TypedRouter { + public upstreamTypedRouter: TypedRouter; + + public routerMap = new plugins.lik.Objectmap< + TypedRouter + >(); + public handlerMap = new plugins.lik.Objectmap< TypedHandler >(); /** * adds the handler to the routing map - * @param handlerArg + * @param typedHandlerArg */ public addTypedHandler( - handlerArg: TypedHandler + typedHandlerArg: TypedHandler ) { - this.handlerMap.add(handlerArg); + // lets check for deduplication + const existingTypedHandler = this.getTypedHandlerForMethod(typedHandlerArg.method); + if (existingTypedHandler) { + throw new Error(`a TypedHandler for ${typedHandlerArg.method} alredy exists! Can't add another one.`); + } + + this.handlerMap.add(typedHandlerArg); } - public async addResponse(typedRequest: plugins.typedRequestInterfaces.ITypedRequest) { - const typedHandler = this.handlerMap.find(handler => { - return handler.method === typedRequest.method; - }); + /** + * adds another sub typedRouter + * @param typedRequest + */ + public addTypedRouter(typedRouterArg: TypedRouter) { + this.routerMap.add(typedRouterArg); + } + + public setUpstreamTypedRouter(typedRouterArg: TypedRouter) { + this.upstreamTypedRouter = typedRouterArg; + } + + public checkForTypedHandler(methodArg: string): boolean { + return !! this.getTypedHandlerForMethod(methodArg); + } + + /** + * gets a typed Router from the router chain, upstream and downstream + * @param methodArg + * @param checkUpstreamRouter + */ + public getTypedHandlerForMethod(methodArg: string, checkUpstreamRouter = true): TypedHandler { + let typedHandler: TypedHandler; + + if (this.upstreamTypedRouter && checkUpstreamRouter) { + typedHandler = this.upstreamTypedRouter.getTypedHandlerForMethod(methodArg); + } else { + typedHandler = this.handlerMap.find(handler => { + return handler.method === methodArg; + }); + + if (!typedHandler) { + this.routerMap.getArray().forEach(typedRouter => { + if (!typedHandler) { + typedHandler = typedRouter.getTypedHandlerForMethod(methodArg, false); + } + }); + } + } + + return typedHandler; + } + + + /** + * routes a typed request to a handler + * @param typedRequestArg + */ + public async routeAndAddResponse(typedRequestArg: plugins.typedRequestInterfaces.ITypedRequest) { + const typedHandler = this.getTypedHandlerForMethod(typedRequestArg.method); if (!typedHandler) { const availableMethods: string[] = []; @@ -35,14 +93,14 @@ export class TypedRouter { console.log(`Cannot find method for ${typedHandler}`); console.log(`Available methods are:`); console.log(availableMethods); - typedRequest.error = { + typedRequestArg.error = { text: 'There is no available method for this call on the server side', data: {} }; - return typedRequest; + return typedRequestArg; } - typedRequest = await typedHandler.addResponse(typedRequest); - return typedRequest; + typedRequestArg = await typedHandler.addResponse(typedRequestArg); + return typedRequestArg; } }