Fork of github.com/did-method-plc/did-method-plc
1// catch errors that get thrown in async route handlers
2// this is a relatively non-invasive change to express
3// they get handled in the error.handler middleware
4// leave at top of file before importing Routes
5import 'express-async-errors'
6
7import express from 'express'
8import cors from 'cors'
9import http from 'http'
10import events from 'events'
11import * as error from './error'
12import createRouter from './routes'
13import { loggerMiddleware } from './logger'
14import AppContext from './context'
15import { createHttpTerminator, HttpTerminator } from 'http-terminator'
16import { PlcDatabase } from './db/types'
17
18export * from './db'
19export * from './context'
20
21export class PlcServer {
22 public ctx: AppContext
23 public app: express.Application
24 public server?: http.Server
25 private terminator?: HttpTerminator
26
27 constructor(opts: { ctx: AppContext; app: express.Application }) {
28 this.ctx = opts.ctx
29 this.app = opts.app
30 }
31
32 static create(opts: {
33 db: PlcDatabase
34 port?: number
35 version?: string
36 }): PlcServer {
37 const app = express()
38 app.use(express.json({ limit: '100kb' }))
39 app.use(cors())
40
41 app.use(loggerMiddleware)
42
43 const ctx = new AppContext({
44 db: opts.db,
45 version: opts.version || '0.0.0',
46 port: opts.port,
47 })
48
49 app.use('/', createRouter(ctx))
50 app.use(error.handler)
51
52 return new PlcServer({
53 ctx,
54 app,
55 })
56 }
57
58 async start(): Promise<http.Server> {
59 const server = this.app.listen(this.ctx.port)
60 this.server = server
61 this.terminator = createHttpTerminator({ server })
62 await events.once(server, 'listening')
63 return server
64 }
65
66 async destroy() {
67 await this.terminator?.terminate()
68 await this.ctx.db.close()
69 }
70}
71
72export default PlcServer