import "reflect-metadata" ; import * as Koa from "koa" ; import * as mount from "koa-mount" ; import { Container } from "typedi" ; import { Server } from "http" ; import { loadController } from "./class/controller" ; import { loadService } from "./class/service" ; import Middleware , { Middleware$ , resolveMiddleware , isValidMiddleware } from "./class/middleware" ; import { Config$ , BodyParserConfig$ , ViewConfig$ , CorsConfig$ , StaticFileServerConfig$ , loadConfig } from "./config" ; import Context from "./class/context" ; import { paths } from "./path" ; import { CONTEXT , APP_MIDDLEWARE } from "./const" ; export interface Application$ { start ( port ? ) : Promise < Server > ; } class Application extends Koa { constructor ( private options = { } ) { super ( ) ; this [ CONTEXT ] = Container . get ( Context ) ; this [ APP_MIDDLEWARE ] = [ ] ; } private async init ( ) { const context = this [ CONTEXT ] ; const config = await loadConfig ( ) ; context . config = config ; context . options = this . options ; if ( this . options . enabled ) { const { bodyParser , proxy , view , cors } = this . options . enabled ; const staticServer = this . options . enabled . static ; if ( bodyParser ) { let bodyParserConfig = { } ; if ( typeof bodyParser === "object" ) { bodyParserConfig = bodyParser ; } super . use ( require ( "koa-bodyparser" ) ( bodyParserConfig ) ) ; } if ( staticServer ) { const FileServer = require ( "koa-static" ) ; let StaticFileServerConfig = { mount : "/static" } ; if ( typeof staticServer === "object" ) { StaticFileServerConfig = Object . assign ( StaticFileServerConfig , staticServer ) ; } super . use ( mount ( StaticFileServerConfig . mount , FileServer ( paths . static , StaticFileServerConfig ) ) ) ; } if ( proxy ) { const proxyServer = require ( "koa-proxies" ) ; const options = proxy . options ; if ( ! options . rewrite ) { options . rewrite = path => { return path . replace ( new RegExp ( "^\\" + proxy . mount ) , "" ) ; } ; } super . use ( proxyServer ( proxy . mount , proxy . options ) ) ; } if ( view ) { let viewConfig = { } ; if ( typeof view === "object" ) { viewConfig = view ; } const views = require ( "koa-views" ) ; super . use ( views ( paths . view , viewConfig ) ) ; } if ( cors ) { let corsConfig = { } ; if ( typeof cors === "object" ) { corsConfig = cors ; } const corsMiddleware = require ( "koa-cors" ) ; super . use ( corsMiddleware ( corsConfig ) ) ; } } await loadService ( ) ; const globalMiddleware = this [ APP_MIDDLEWARE ] ; globalMiddleware . forEach ( element => { const { middlewareName , options } = element ; const MiddlewareFactory = resolveMiddleware ( middlewareName ) ; const middleware = new MiddlewareFactory ( ) ; if ( ! isValidMiddleware ( middleware ) ) { throw new Error ( `Invalid middleware "${ middlewareName }"` ) ; } middleware . config = options ; const koaStyleMiddleware = middleware . pipe . bind ( middleware ) ; super . use ( koaStyleMiddleware ) ; } ) ; const router = await loadController ( ) ; super . use ( router . routes ( ) ) . use ( router . allowedMethods ( ) ) ; return this ; } async start ( port ? ) { await this . init ( ) ; return super . listen ( port || process . env . PORT || 3000 ) ; } param middlewareName param options use ( middlewareName , options = { } ) { this [ APP_MIDDLEWARE ] . push ( { middlewareName , options } ) ; return this ; } } export default Application ;