import { Application , Context } from 'egg' ; import { join } from 'path' ; import assert from 'assert' ; import { GloablEvents , BotLogger , loggerWrapper } from './Utils' ; /**
 * Hypertrons app plugin base class
 * Provide basic functions:
 *   1. LoadToApp static function
 *   2. app hooks on start
 *   3. getConfig function to get config for certain repo
 */ export abstract class AppPluginBase < TConfig > { param name param constructor param app static LoadToApp < T extends AppPluginBase < TConfig > , TConfig > ( name , constructor , app ) { if ( ! Object . prototype . isPrototypeOf . call ( AppPluginBase , constructor ) ) { throw new Error ( `Invalid plugin type for ${ name }` ) ; } app . addSingleton ( name , ( config , app ) => { const plugin = new constructor ( config , app ) ; plugin . name = name ; plugin . logger . info ( 'Going to load' ) ; return plugin ; } ) ; } protected app : Application ; protected name : string ; protected config : TConfig ; public logger : BotLogger ; constructor ( config , app ) { this . app = app ; this . config = config ; this . logger = this . logger = loggerWrapper ( this . app . logger , ( ) => `[${ this . name }-app]` ) ; this . checkConfigFields ( ) . forEach ( f => this . checkConfig ( config , f ) ) ; this . app . messenger . on ( GloablEvents . READY , ( ) => { this . logger . info ( 'Bot ready, start to run onReady.' ) ; this . onReady ( ) ; } ) ; this . app . messenger . on ( GloablEvents . START , ( ) => { this . logger . info ( 'Bot start, start to run onStart.' ) ; this . onStart ( ) ; } ) ; this . app . messenger . on ( GloablEvents . CLOSE , ( ) => { this . logger . info ( 'Bot close, start to run onClose.' ) ; this . onClose ( ) ; } ) ; } param path param middlewares public get ( path , ... middlewares ) { this . app . router . get ( this . getRouterPath ( path ) , ... middlewares ) ; } param path param middlewares public post ( path , ... middlewares ) { this . app . router . post ( this . getRouterPath ( path ) , ... middlewares ) ; } param path param middlewares public put ( path , ... middlewares ) { this . app . router . put ( this . getRouterPath ( path ) , ... middlewares ) ; } param path param middlewares public delete ( path , ... middlewares ) { this . app . router . delete ( this . getRouterPath ( path ) , ... middlewares ) ; } private getRouterPath ( path ) { let x = join ( '/' , this . name , path ) ; while ( x !== x . replace ( '\\' , '/' ) ) { x = x . replace ( '\\' , '/' ) ; } return x ; } protected checkConfigFields ( ) { return [ ] ; } private checkConfig ( config , field ) { assert . notEqual ( config [ field ] , undefined ) ; } /**
     * When plugin ready
     */ public abstract async onReady ( ) ; /**
     * When server start
     */ public abstract async onStart ( ) ; /**
     * When app close
     */ public abstract async onClose ( ) ; } /**
 * Middleware of koa
 */ type Middleware = ( ctx : Context , next : any ) => Promise < void > ;