ManimCat-show / src /server /bootstrap.ts
Bin29's picture
Revert "fix: prevent silent startup in production summary logging"
a2bfa28
import express, { type Request, type Response, type NextFunction } from 'express'
import path from 'path'
import { appConfig, isDevelopment, printConfig, validateConfig } from '../config/app'
import { corsMiddleware } from '../middlewares/cors'
import { errorHandler, notFoundHandler } from '../middlewares/error-handler'
import routes from '../routes'
interface LoggerLike {
info(message: string, meta?: unknown): void
error(message: string, meta?: unknown): void
}
function requestLoggerFactory(logger: LoggerLike) {
return function requestLogger(req: Request, res: Response, next: NextFunction): void {
const start = Date.now()
res.on('finish', () => {
const duration = Date.now() - start
if (!req.path.includes('/jobs/')) {
logger.info('Request completed', {
method: req.method,
path: req.path,
status: res.statusCode,
duration: `${duration}ms`
})
}
})
next()
}
}
export async function initializeExpressApp(app: express.Express, logger: LoggerLike): Promise<void> {
validateConfig()
app.use(express.json({ limit: '10mb' }))
app.use(express.urlencoded({ extended: true, limit: '10mb' }))
app.use(corsMiddleware)
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
if (err instanceof SyntaxError && 'body' in err) {
logger.error('JSON 解析错误', {
method: req.method,
path: req.path,
error: err.message,
body: req.body
})
return res.status(400).json({
error: 'Invalid JSON',
message: err.message
})
}
next(err)
})
if (isDevelopment()) {
app.use(requestLoggerFactory(logger))
}
app.use('/images', express.static(path.join(process.cwd(), 'public', 'images'), { fallthrough: false }))
app.use('/videos', express.static(path.join(process.cwd(), 'public', 'videos'), { fallthrough: false }))
app.use(express.static('public'))
app.use(routes)
app.get('*', (req, res) => {
if (req.path.startsWith('/health') || req.path.startsWith('/api')) {
return notFoundHandler(req, res, () => {})
}
if (path.extname(req.path)) {
return notFoundHandler(req, res, () => {})
}
const indexPath = path.join(__dirname, '..', '..', 'public', 'index.html')
res.sendFile(indexPath, (err) => {
if (err) {
return notFoundHandler(req, res, () => {})
}
})
})
app.use(errorHandler)
printConfig()
}
export { appConfig }