// This file isn't processed by Vite, see https://github.com/vikejs/vike/issues/562 // Consequently: // - When changing this file, you needed to manually restart your server for your changes to take effect. // - To use your environment variables defined in your .env files, you need to install dotenv, see https://vike.dev/env // - To use your path aliases defined in your vite.config.js, you need to tell Node.js about them, see https://vike.dev/path-aliases // If you want Vite to process your server code then use one of these: // - vavite (https://github.com/cyco130/vavite) // - See vavite + Vike examples at https://github.com/cyco130/vavite/tree/main/examples // - vite-node (https://github.com/antfu/vite-node) // - HatTip (https://github.com/hattipjs/hattip) // - You can use Bati (https://batijs.github.io/) to scaffold a Vike + HatTip app. Note that Bati generates apps that use the V1 design (https://vike.dev/migration/v1-design) and Vike packages (https://vike.dev/vike-packages) import config from 'config'; import express from 'express'; import boolParser from 'express-query-boolean'; import Router from 'express-promise-router'; import session from 'express-session'; import RedisStore from 'connect-redis'; import compression from 'compression'; import { renderPage } from 'vike/server'; // eslint-disable-line import/extensions // import root from './root.js'; import redis from '../redis.js'; import errorHandler from './error.js'; import { fetchScenesApi } from './scenes.js'; import { fetchActorsApi } from './actors.js'; import { fetchMoviesApi } from './movies.js'; import { setUserApi, loginApi, logoutApi, signupApi, } from './auth.js'; import { createStashApi, removeStashApi, stashActorApi, stashSceneApi, stashMovieApi, unstashActorApi, unstashSceneApi, unstashMovieApi, updateStashApi, } from './stashes.js'; import initLogger from '../logger.js'; const logger = initLogger(); const isProduction = process.env.NODE_ENV === 'production'; export default async function initServer() { const app = express(); const router = Router(); app.use(compression()); app.disable('x-powered-by'); router.use(boolParser()); router.use('/', express.static('public')); router.use('/', express.static('static')); router.use('/media', express.static(config.media.path)); router.use(express.json()); const redisStore = new RedisStore({ client: redis, prefix: 'traxxx:session:', }); router.use(session({ ...config.web.session, store: redisStore, })); router.use(setUserApi); // Vite integration if (isProduction) { // In production, we need to serve our static assets ourselves. // (In dev, Vite's middleware serves our static assets.) const sirv = (await import('sirv')).default; router.use(sirv('dist/client')); } else { // We instantiate Vite's development server and integrate its middleware to our server. // ⚠️ We instantiate it only in development. (It isn't needed in production and it // would unnecessarily bloat our production server.) const vite = await import('vite'); const viteDevMiddleware = ( await vite.createServer({ // root, server: { middlewareMode: true }, }) ).middlewares; router.use(viteDevMiddleware); } // SESSION router.post('/api/session', loginApi); router.delete('/api/session', logoutApi); // USERS router.post('/api/users', signupApi); // STASHES router.post('/api/stashes', createStashApi); router.patch('/api/stashes/:stashId', updateStashApi); router.delete('/api/stashes/:stashId', removeStashApi); router.post('/api/stashes/:stashId/actors', stashActorApi); router.post('/api/stashes/:stashId/scenes', stashSceneApi); router.post('/api/stashes/:stashId/movies', stashMovieApi); router.delete('/api/stashes/:stashId/actors/:actorId', unstashActorApi); router.delete('/api/stashes/:stashId/scenes/:sceneId', unstashSceneApi); router.delete('/api/stashes/:stashId/movies/:movieId', unstashMovieApi); // SCENES router.get('/api/scenes', fetchScenesApi); // ACTORS router.get('/api/actors', fetchActorsApi); // MOVIES router.get('/api/movies', fetchMoviesApi); router.get('*', async (req, res, next) => { const pageContextInit = { urlOriginal: req.originalUrl, urlQuery: req.query, // vike's own query does not apply boolean parser user: req.user && { id: req.user.id, username: req.user.username, email: req.user.email, avatar: req.user.avatar, stashes: req.user.stashes, primaryStash: req.user.primaryStash, }, env: { maxAggregateSize: config.database.manticore.maxAggregateSize, }, }; const pageContext = await renderPage(pageContextInit); const { httpResponse } = pageContext; if (pageContext.errorWhileRendering) { console.error(pageContext.errorWhileRendering); } if (!httpResponse) { next(); return; } const { body, statusCode, headers, earlyHints, } = httpResponse; if (res.writeEarlyHints) { res.writeEarlyHints({ link: earlyHints.map((e) => e.earlyHintLink) }); } headers.forEach(([name, value]) => res.setHeader(name, value)); res.status(statusCode); // For HTTP streams use httpResponse.pipe() instead, see https://vike.dev/stream res.send(body); }); router.use(errorHandler); app.use(router); const port = process.env.PORT || config.web.port || 3000; app.listen(port); logger.info(`Server running at http://localhost:${port}`); }