Replace Application.ts with createAppication and configureApplication

This commit is contained in:
Jerko Steiner 2019-08-31 11:42:12 +07:00
parent 4814316fa7
commit 64f5f2f642
5 changed files with 156 additions and 4 deletions

View File

@ -9,6 +9,8 @@ import {IDatabase} from '../database/IDatabase'
import {Server} from 'http'
import {SqlLogger, loggerFactory} from '../logger'
import {createNamespace, Namespace} from 'cls-hooked'
import { configureApplication } from './configureApplication'
import { createApplication } from './createApplication'
export class Bootstrap implements IBootstrap {
protected server?: Server
@ -36,7 +38,7 @@ export class Bootstrap implements IBootstrap {
}
protected createApplication(database: IDatabase): IApplication {
return new Application(this.getConfig(), database)
return createApplication(configureApplication(this.getConfig(), database))
}
async exec(command: string = 'listen') {

View File

@ -6,7 +6,4 @@ import {IDatabase} from '../database/IDatabase'
export interface IApplication {
readonly server: express.Application
readonly database: IDatabase
createAsyncRouter<T extends IRoutes>(): AsyncRouter<T>
createTransactionalRouter<T extends IRoutes>(): AsyncRouter<T>
}

View File

@ -0,0 +1,31 @@
import { IConfig } from './IConfig'
import { IDatabase } from '../database'
import { ILogger } from '@rondo.dev/logger'
import { IServices } from './IServices'
import { RequestHandlerParams, ErrorRequestHandler } from 'express-serve-static-core'
export interface IFramework {
readonly middleware: RequestHandlerParams[]
// TODO remove app, i believe this is used in tests
readonly app: RequestHandlerParams[]
readonly api: RequestHandlerParams[]
readonly apiError: ErrorRequestHandler
readonly frontend: RequestHandlerParams[]
readonly error: ErrorRequestHandler
}
export interface IFrameworkPaths {
readonly middleware: string
readonly app: string
readonly api: string
readonly frontend: string
}
export interface IApplicationConfig {
readonly config: IConfig
readonly database: IDatabase
readonly logger: ILogger
readonly services: IServices
readonly paths?: Partial<IFrameworkPaths>
readonly framework: IFramework
}

View File

@ -0,0 +1,83 @@
import cookieParser from 'cookie-parser'
import { json } from 'body-parser'
import { IDatabase } from '../database'
import { loggerFactory } from '../logger'
import * as Middleware from '../middleware'
import * as Services from '../services'
import * as Team from '../team'
import * as User from '../user'
import { IApplicationConfig } from './IApplicationConfig'
import { IConfig } from './IConfig'
import { IServices } from './IServices'
import * as routes from '../routes'
import { TransactionalRouter } from '../router'
import { IRoutes, IContext } from '@rondo.dev/common'
import { Express } from 'express-serve-static-core'
export function configureApplication(
config: IConfig,
database: IDatabase,
): IApplicationConfig {
const logger = loggerFactory.getLogger('api')
const services: IServices = {
userService: new Services.UserService(database),
teamService: new Team.TeamService(database),
userPermissions: new User.UserPermissions(database),
}
const authenticator = new Middleware.Authenticator(services.userService)
const transactionManager = database.transactionManager
const createTransactionalRouter = <T extends IRoutes>() =>
new TransactionalRouter<T>(transactionManager)
const getContext = (req: Express.Request): IContext => ({user: req.user})
return {
config,
database,
logger,
services,
framework: {
middleware: [
new Middleware.SessionMiddleware({
transactionManager,
baseUrl: config.app.baseUrl,
sessionName: config.app.session.name,
sessionSecret: config.app.session.secret,
}).handle,
new Middleware.RequestLogger(logger).handle,
json(),
cookieParser(config.app.session.secret),
new Middleware.CSRFMiddleware({
baseUrl: config.app.baseUrl,
cookieName: config.app.session.name + '_csrf',
}).handle,
new Middleware.Transaction(database.namespace).handle,
authenticator.handle,
],
app: [routes.application],
api: [
new routes.LoginRoutes(
services.userService,
authenticator,
createTransactionalRouter(),
).handle,
new routes.UserRoutes(
services.userService,
createTransactionalRouter(),
).handle,
new Team.TeamRoutes(
services.teamService,
services.userPermissions,
createTransactionalRouter(),
).handle,
],
apiError: new Middleware.ErrorApiHandler(logger).handle,
frontend: [],
error: new Middleware.ErrorPageHandler(logger).handle,
},
}
}

View File

@ -0,0 +1,39 @@
import { IApplicationConfig, IFrameworkPaths } from './IApplicationConfig'
import { IApplication } from './IApplication'
import express from 'express'
export const defaultPaths: IFrameworkPaths = {
middleware: '/',
app: '/app',
api: '/api',
frontend: '/',
}
export function createApplication(appConfig: IApplicationConfig): IApplication {
const {config, database, framework} = appConfig
const server = express()
const paths = {
...defaultPaths,
...(appConfig.paths || {}),
}
server.set('trust proxy', 1)
server.disable('x-powered-by')
const router = express.Router()
router.use(paths.middleware, ...framework.middleware)
router.use(paths.app, ...framework.app)
router.use(paths.api, ...framework.api)
router.use(paths.api, framework.apiError)
if (framework.frontend.length) {
router.use(paths.frontend, ...framework.frontend)
}
server.use(config.app.context, router)
server.use(framework.error)
return {
server,
database,
}
}