Do not subclass Bootstrap.ts
This commit is contained in:
parent
5688a65cb0
commit
dcc5b52725
@ -5,23 +5,60 @@ import { AddressInfo } from 'net'
|
|||||||
import { Database } from '../database/Database'
|
import { Database } from '../database/Database'
|
||||||
import { IDatabase } from '../database/IDatabase'
|
import { IDatabase } from '../database/IDatabase'
|
||||||
import { loggerFactory, SqlLogger } from '../logger'
|
import { loggerFactory, SqlLogger } from '../logger'
|
||||||
import { configureServer } from './configureServer'
|
import { ServerConfigurator } from './configureServer'
|
||||||
import { createServer } from './createServer'
|
import { createServer } from './createServer'
|
||||||
import { IApplication } from './IApplication'
|
import { IApplication } from './IApplication'
|
||||||
import { IBootstrap } from './IBootstrap'
|
import { IBootstrap } from './IBootstrap'
|
||||||
import { IConfig } from './IConfig'
|
import { IConfig } from './IConfig'
|
||||||
|
import { IServerConfig } from './IServerConfig'
|
||||||
|
|
||||||
|
export interface IBootstrapParams {
|
||||||
|
readonly config: IConfig
|
||||||
|
readonly configureServer: ServerConfigurator
|
||||||
|
readonly namespace?: Namespace
|
||||||
|
readonly exit?: (code: number) => void
|
||||||
|
readonly entities?: object
|
||||||
|
readonly migrations?: object
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line
|
||||||
|
function getFunctions(obj: object): Function[] {
|
||||||
|
return Object.keys(obj)
|
||||||
|
.map(k => (obj as any)[k])
|
||||||
|
.filter(f => typeof f === 'function')
|
||||||
|
}
|
||||||
|
|
||||||
export class Bootstrap implements IBootstrap {
|
export class Bootstrap implements IBootstrap {
|
||||||
|
protected config: IConfig
|
||||||
|
protected configureServer: ServerConfigurator
|
||||||
|
protected namespace: Namespace
|
||||||
|
protected exit: (code: number) => void
|
||||||
|
|
||||||
protected server?: Server
|
protected server?: Server
|
||||||
protected inUse: boolean = false
|
protected inUse: boolean = false
|
||||||
readonly application: IApplication
|
readonly application: IApplication
|
||||||
readonly database: IDatabase
|
readonly database: IDatabase
|
||||||
|
|
||||||
constructor(
|
constructor(params: IBootstrapParams) {
|
||||||
private readonly config: IConfig,
|
this.config = {
|
||||||
protected readonly namespace: Namespace = createNamespace('application'),
|
...params.config,
|
||||||
protected readonly exit: (code: number) => void = process.exit,
|
app: {
|
||||||
) {
|
...params.config.app,
|
||||||
|
db: {
|
||||||
|
...params.config.app.db,
|
||||||
|
entities: params.entities
|
||||||
|
? getFunctions(params.entities)
|
||||||
|
: params.config.app.db.entities,
|
||||||
|
migrations: params.migrations
|
||||||
|
? getFunctions(params.migrations)
|
||||||
|
: params.config.app.db.migrations,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
this.configureServer = params.configureServer
|
||||||
|
this.namespace = params.namespace || createNamespace('application')
|
||||||
|
this.exit = params.exit || process.exit
|
||||||
|
|
||||||
this.database = this.createDatabase()
|
this.database = this.createDatabase()
|
||||||
this.application = this.createApplication(this.database)
|
this.application = this.createApplication(this.database)
|
||||||
}
|
}
|
||||||
@ -31,12 +68,13 @@ export class Bootstrap implements IBootstrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected createDatabase(): IDatabase {
|
protected createDatabase(): IDatabase {
|
||||||
const sqlLogger = new SqlLogger(
|
const {namespace} = this
|
||||||
loggerFactory.getLogger('sql'), this.namespace)
|
const sqlLogger = new SqlLogger(loggerFactory.getLogger('sql'), namespace)
|
||||||
return new Database(this.namespace, sqlLogger, this.getConfig().app.db)
|
return new Database(namespace, sqlLogger, this.getConfig().app.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createApplication(database: IDatabase): IApplication {
|
protected createApplication(database: IDatabase): IApplication {
|
||||||
|
const {configureServer} = this
|
||||||
return createServer(configureServer(this.getConfig(), database))
|
return createServer(configureServer(this.getConfig(), database))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,14 +14,14 @@ import { TransactionalRouter } from '../router'
|
|||||||
import { IRoutes, IContext } from '@rondo.dev/common'
|
import { IRoutes, IContext } from '@rondo.dev/common'
|
||||||
import { Express } from 'express-serve-static-core'
|
import { Express } from 'express-serve-static-core'
|
||||||
|
|
||||||
export type AppConfigurator<
|
export type ServerConfigurator<
|
||||||
T extends IServerConfig = IServerConfig
|
T extends IServerConfig = IServerConfig
|
||||||
> = (
|
> = (
|
||||||
config: IConfig,
|
config: IConfig,
|
||||||
database: IDatabase,
|
database: IDatabase,
|
||||||
) => T
|
) => T
|
||||||
|
|
||||||
export const configureServer: AppConfigurator = (config, database) => {
|
export const configureServer: ServerConfigurator = (config, database) => {
|
||||||
|
|
||||||
const logger = loggerFactory.getLogger('api')
|
const logger = loggerFactory.getLogger('api')
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
if (!process.env.LOG) {
|
|
||||||
process.env.LOG = 'api,sql:warn'
|
|
||||||
}
|
|
||||||
|
|
||||||
import {config} from './config'
|
import {config} from './config'
|
||||||
import {Bootstrap} from './application/Bootstrap'
|
import {Bootstrap} from './application/Bootstrap'
|
||||||
|
import {configureServer} from './application/configureServer'
|
||||||
|
|
||||||
export const bootstrap = new Bootstrap(config)
|
export default new Bootstrap({
|
||||||
// FIXME determine a port by parsing app url from config
|
config,
|
||||||
const port: string | number = process.env.PORT || 3000
|
configureServer,
|
||||||
|
})
|
||||||
bootstrap.listen(port)
|
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
if (require.main === module) {
|
||||||
|
if (!process.env.LOG) {
|
||||||
|
process.env.LOG = 'api,sql:warn'
|
||||||
|
}
|
||||||
|
}
|
||||||
export * from './application'
|
export * from './application'
|
||||||
export * from './database'
|
export * from './database'
|
||||||
export * from './entities'
|
export * from './entities'
|
||||||
@ -14,3 +19,9 @@ export * from './validator'
|
|||||||
|
|
||||||
import * as rpc from './rpc'
|
import * as rpc from './rpc'
|
||||||
export {rpc}
|
export {rpc}
|
||||||
|
|
||||||
|
import bootstrap from './bootstrap'
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
bootstrap.exec(process.argv[2])
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import {Bootstrap} from './application/Bootstrap'
|
import {Bootstrap} from './application/Bootstrap'
|
||||||
|
import {configureServer} from './application/configureServer'
|
||||||
import {IAPIDef} from '@rondo.dev/common'
|
import {IAPIDef} from '@rondo.dev/common'
|
||||||
import {TestUtils} from './test-utils'
|
import {TestUtils} from './test-utils'
|
||||||
import {config} from './config'
|
import {config} from './config'
|
||||||
@ -6,11 +7,12 @@ import {createNamespace} from 'cls-hooked'
|
|||||||
|
|
||||||
export const exit = jest.fn()
|
export const exit = jest.fn()
|
||||||
|
|
||||||
export const bootstrap = new Bootstrap(
|
export const bootstrap = new Bootstrap({
|
||||||
config,
|
config,
|
||||||
createNamespace('test'),
|
configureServer,
|
||||||
|
namespace: createNamespace('test'),
|
||||||
exit,
|
exit,
|
||||||
)
|
})
|
||||||
|
|
||||||
// TODO separate IAPIDef between projects
|
// TODO separate IAPIDef between projects
|
||||||
export const test = new TestUtils<IAPIDef>(bootstrap)
|
export const test = new TestUtils<IAPIDef>(bootstrap)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user