TypeScript · 3000 bytes Raw Blame History
1 import Fastify from 'fastify';
2 import cors from '@fastify/cors';
3 import jwt from '@fastify/jwt';
4 import multipart from '@fastify/multipart';
5 import websocket from '@fastify/websocket';
6 import staticFiles from '@fastify/static';
7 import { loadConfig } from './config.js';
8 import { registerRoutes } from './routes/index.js';
9 import { errorHandler } from './middleware/error-handler.js';
10 import { authMiddleware } from './middleware/auth.js';
11 import { performanceMiddleware } from './middleware/performance.js';
12 import { cacheMiddleware } from './middleware/cache.js';
13 import { ZephyrFSClient } from './integration/zephyrfs-client.js';
14 import path from 'node:path';
15 import { fileURLToPath } from 'node:url';
16
17 const __filename = fileURLToPath(import.meta.url);
18 const __dirname = path.dirname(__filename);
19
20 async function createServer() {
21 const config = loadConfig();
22
23 const fastify = Fastify({
24 logger: {
25 level: config.logLevel,
26 transport: config.nodeEnv === 'development' ? {
27 target: 'pino-pretty',
28 options: {
29 translateTime: 'HH:MM:ss Z',
30 ignore: 'pid,hostname',
31 },
32 } : undefined,
33 },
34 });
35
36 // Initialize ZephyrFS client
37 const zephyrfsClient = new ZephyrFSClient(config.zephyrfsNodeUrl, {
38 timeout: config.zephyrfsNodeTimeout,
39 });
40
41 // Register plugins
42 await fastify.register(cors, {
43 origin: config.corsOrigins,
44 credentials: true,
45 });
46
47 await fastify.register(jwt, {
48 secret: config.jwtSecret,
49 });
50
51 await fastify.register(multipart, {
52 limits: {
53 fileSize: config.maxFileSize,
54 },
55 });
56
57 await fastify.register(websocket);
58
59 // Serve static files in production
60 if (config.nodeEnv === 'production') {
61 await fastify.register(staticFiles, {
62 root: path.join(__dirname, '../public'),
63 prefix: '/',
64 });
65 }
66
67 // Add context
68 fastify.decorate('zephyrfs', zephyrfsClient);
69 fastify.decorate('config', config);
70
71 // Register middleware
72 fastify.setErrorHandler(errorHandler);
73 await fastify.register(performanceMiddleware);
74 await fastify.register(cacheMiddleware);
75 await fastify.register(authMiddleware);
76
77 // Register routes
78 await fastify.register(registerRoutes, { prefix: '/api' });
79
80 return fastify;
81 }
82
83 async function start() {
84 try {
85 const config = loadConfig();
86 const server = await createServer();
87
88 await server.listen({
89 port: config.port,
90 host: config.host,
91 });
92
93 console.log(`🚀 ZephyrFS Web Server running on http://${config.host}:${config.port}`);
94 } catch (error) {
95 console.error('Failed to start server:', error);
96 process.exit(1);
97 }
98 }
99
100 // Handle graceful shutdown
101 process.on('SIGTERM', async () => {
102 console.log('Received SIGTERM, shutting down gracefully...');
103 process.exit(0);
104 });
105
106 process.on('SIGINT', async () => {
107 console.log('Received SIGINT, shutting down gracefully...');
108 process.exit(0);
109 });
110
111 if (import.meta.url === `file://${process.argv[1]}`) {
112 start();
113 }
114
115 export { createServer };