/** @format */ import { Middleware, MiddlewareObj } from './middleware' import Composer from './composer' import Context from './context' type NonemptyReadonlyArray = readonly [T, ...T[]] type RouteFn = (ctx: TContext) => { route: string context?: Partial state?: Partial } | null /** @deprecated in favor of {@link Composer.dispatch} */ export class Router implements MiddlewareObj { private otherwiseHandler: Middleware = Composer.passThru() constructor( private readonly routeFn: RouteFn, public handlers = new Map>() ) { if (typeof routeFn !== 'function') { throw new Error('Missing routing function') } } on(route: string, ...fns: NonemptyReadonlyArray>) { // siakinnik - removed, typescript guaranties fns.length !== 0 // if (fns.length === 0) { // throw new TypeError('At least one handler must be provided') // }; for (const fn of fns) { if ( typeof fn !== 'function' && !(typeof fn === 'object' && 'middleware' in fn) ) { throw new TypeError( ` Router.on handler for route "${route}" must be a function or MiddlewareObj` ) } } this.handlers.set(route, Composer.compose(fns)) return this } otherwise(...fns: NonemptyReadonlyArray>) { // siakinnik - removed, typescript guaranties fns.length !== 0 // if (fns.length === 0) { // throw new TypeError('At least one otherwise handler must be provided') // }; for (const fn of fns) { if ( typeof fn !== 'function' && !(typeof fn === 'object' && 'middleware' in fn) ) { throw new TypeError( 'Telegraf: Router.otherwise handler must be a function or MiddlewareObj' ) } } this.otherwiseHandler = Composer.compose(fns) return this } middleware() { return Composer.lazy((ctx) => { const result = this.routeFn(ctx) if (result == null) { return this.otherwiseHandler } if (result.context) { Object.assign(ctx, result.context) } if (result.state) { Object.assign(ctx.state, result.state) } return this.handlers.get(result.route) ?? this.otherwiseHandler }) } }