import { randomUUID } from 'crypto'; import { feathers } from '@feathersjs/feathers'; import express, { rest, json, urlencoded, cors, serveStatic, notFound, errorHandler } from '@feathersjs/express'; import configuration from '@feathersjs/configuration'; import socketio from '@feathersjs/socketio'; import session from 'express-session'; import cookieParser from 'cookie-parser'; import RedisStore from 'connect-redis'; import { createClient } from 'redis'; import config from 'config'; import type { Application } from './declarations'; import { logger } from './logger'; import { logError } from './hooks/log-error'; import { services } from './services/index'; import { channels } from './channels'; import { Env, getEnv } from './helpers/get-env'; const app: Application = express(feathers()); let sessionStore; // Load app configuration app.configure(configuration()); app.use(cors()); app.use( json({ limit: '20mb', }) ); app.use(cookieParser()); if (getEnv() === Env.prod) { const redisClient = createClient({ url: config.get('redis.url'), }); sessionStore = new RedisStore({ prefix: 'walias:', client: redisClient, }); redisClient.connect().catch(console.error); } app.use( session({ store: sessionStore, secret: config.get('sessionSecret') || randomUUID(), resave: false, saveUninitialized: false, cookie: { secure: false }, }) ); // Propagate session to request.params in feathers services app.use(function (req, _res, next) { req.feathers = { ...req.feathers, session: req.session, }; next(); }); app.use(urlencoded({ extended: true })); // Host the public folder app.use('/', serveStatic(app.get('public'))); // Configure services and real-time functionality app.configure(rest()); app.configure( socketio({ cors: { origin: app.get('origins'), }, }) ); app.configure(services); app.configure(channels); // Configure a middleware for 404s and the error handler app.use(notFound()); app.use(errorHandler({ logger })); // Register hooks that run on all service methods app.hooks({ around: { all: [logError], }, before: {}, after: {}, error: {}, }); // Register application setup and teardown hooks here app.hooks({ setup: [], teardown: [], }); export { app };