import Fastify from 'fastify' import prismaPlugin from './plugins/prisma' import vodsRoutes from './plugins/vods' import uploadsRoutes from './plugins/uploads' import vtubersRoutes from './plugins/vtubers' import usersRoutes from './plugins/users' import indexRoutes from './plugins/index' import streamsRoutes from './plugins/streams' import adminRoutes from './plugins/admin' import hls from './plugins/hls.ts' import fastifyStatic from '@fastify/static' import fastifySecureSession from '@fastify/secure-session' import path, { basename, resolve } from 'node:path' import fastifyFormbody from '@fastify/formbody' import fastifyView from "@fastify/view" import { env } from './config/env' import { constants } from './config/constants' import authRoutes from './plugins/auth' import Handlebars from 'handlebars' import graphileWorker from './plugins/graphileWorker' import fastifySwagger from "@fastify/swagger" import fastifySwaggerUi from "@fastify/swagger-ui" import { join } from 'node:path' import fastifyFlash from '@fastify/flash' import { registerHbsHelpers } from './utils/hbsHelpers.ts' import fastifyFavicon from 'fastify-favicon' const __dirname = import.meta.dirname; export async function buildApp() { const app = Fastify() registerHbsHelpers(Handlebars) const swaggerOptions = { swagger: { info: { title: constants.site.title, description: constants.site.description, version: constants.site.version, }, host: env.ORIGIN, schemes: ["http", "https"], consumes: ["application/json"], produces: ["application/json"], }, }; const swaggerUiOptions = { routePrefix: "/api/docs", exposeRoute: true, }; app.register(fastifySwagger, swaggerOptions); app.register(fastifySwaggerUi, swaggerUiOptions); app.register(fastifyFavicon, { path: path.join(__dirname, '..', 'src', 'assets'), name: 'favicon.ico', maxAge: 3600 }) app.register(fastifyStatic, { root: path.join(__dirname, '..', 'dist', 'client'), prefix: '/assets', // optional: default '/' constraints: {} // optional: default {} }) app.register(fastifyFormbody) // app.register(fastifyMultipart, { // limits: { // fileSize: 30 * 1024 * 1024 // 30MB // } // }) app.register(fastifySecureSession, { // the name of the attribute decorated on the request-object, defaults to 'session' sessionName: 'session', cookieName: 'fp-session', // adapt this to point to the directory where secret-key is located key: Buffer.from(env.COOKIE_SECRET, 'hex'), // the amount of time the session is considered valid; this is different from the cookie options // and based on value within the session. expiry: 24 * 60 * 60, // Default 1 day cookie: { path: '/' // options for setCookie, see https://github.com/fastify/fastify-cookie } }) app.register(fastifyFlash) app.register(fastifyView, { engine: { handlebars: Handlebars, }, templates: join(__dirname, '..', 'src', 'views'), viewExt: 'hbs', options: { partials: { navbar: 'partials/navbar.hbs', footer: 'partials/footer.hbs', commentForm: 'partials/commentForm.hbs' } } }) // @todo we are going to need to use redis or similar https://github.com/fastify/fastify-caching // app.register(fastifyCaching, { // expiresIn: 300, // privacy: 'private', // serverExpiresIn: 300, // }) app.register(graphileWorker) app.register(prismaPlugin) app.register(hls) app.register(vodsRoutes) app.register(streamsRoutes) app.register(vtubersRoutes) app.register(uploadsRoutes) app.register(usersRoutes) app.register(indexRoutes) app.register(adminRoutes) app.register(authRoutes) return app }