78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import fastify, { type FastifyServerOptions } from 'fastify'
|
|
import fcookie from '@fastify/cookie'
|
|
import fsession from '@fastify/session'
|
|
import fstatic from '@fastify/static'
|
|
import RedisStore from 'fastify-session-redis-store'
|
|
import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod'
|
|
import { Redis } from 'ioredis'
|
|
import kysely from './lib/kysely.ts'
|
|
|
|
import StatusError from './lib/status_error.ts'
|
|
import env from './env.ts'
|
|
import ErrorHandler from './handlers/error.ts'
|
|
import authPlugin from './plugins/auth.ts'
|
|
import dbPlugin from './plugins/db.ts'
|
|
import vitePlugin from './plugins/vite.ts'
|
|
import apiRoutes from './routes/api.ts'
|
|
import templateAdmin from './templates/admin.ts'
|
|
import templatePublic from './templates/public.ts'
|
|
|
|
export default async (options?: FastifyServerOptions) => {
|
|
const server = fastify(options)
|
|
|
|
server.setValidatorCompiler(validatorCompiler)
|
|
server.setSerializerCompiler(serializerCompiler)
|
|
|
|
server.register(fcookie)
|
|
server.register(fsession, {
|
|
cookie: {
|
|
secure: env.NODE_ENV !== 'development',
|
|
maxAge: 24 * 60 * 60 * 1000,
|
|
},
|
|
cookieName: 'sessionId',
|
|
secret: env.SESSION_SECRET,
|
|
store: env.NODE_ENV !== 'testing' ? new RedisStore({ client: new Redis(env.REDIS_HOST) }) : undefined,
|
|
})
|
|
server.register(dbPlugin, { kysely })
|
|
|
|
server.setNotFoundHandler(() => {
|
|
throw new StatusError(404)
|
|
})
|
|
|
|
server.register(fstatic, {
|
|
root: new URL('../uploads', import.meta.url),
|
|
prefix: '/uploads/',
|
|
})
|
|
|
|
if (env.NODE_ENV !== 'testing') {
|
|
server.register(vitePlugin, {
|
|
mode: env.NODE_ENV,
|
|
createErrorHandler: ErrorHandler,
|
|
entries: {
|
|
public: {
|
|
path: '/',
|
|
template: templatePublic,
|
|
},
|
|
admin: {
|
|
path: '/admin',
|
|
template: templateAdmin,
|
|
createPreHandler(route) {
|
|
return async function preHandler(request, reply) {
|
|
if (request.session.userId) {
|
|
return (reply.ctx = { user: await request.user })
|
|
} else if (route.auth) {
|
|
return reply.redirect('/admin/login')
|
|
}
|
|
}
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
server.register(authPlugin, { prefix: '/auth' })
|
|
server.register(apiRoutes, { prefix: '/api' })
|
|
|
|
return server
|
|
}
|