1// src/server.ts - Basic Implementation
2import { createApp, z, validate } from '@morojs/moro';
3
4// Create app with WebSocket support
5const app = createApp();
6
7// Simple in-memory storage for demo
8let users: any[] = [];
9let rooms: any[] = [
10 { id: 'general', name: 'General Chat', description: 'Main chat room' },
11 { id: 'random', name: 'Random', description: 'Random discussions' }
12];
13let messages: any[] = [];
14
15// Basic welcome endpoint
16app.get('/', (req, res) => {
17 return {
18 message: 'Real-time Chat API - Simple Demo',
19 status: 'running',
20 version: '1.0.0',
21 note: 'This is a simplified demo without database dependencies',
22 endpoints: [
23 'GET / - This message',
24 'GET /health - Health check',
25 'GET /rooms - Get available rooms',
26 'GET /test - WebSocket test client (open in browser)',
27 'POST /auth/register - Simple user registration (no persistence)',
28 'POST /auth/login - Simple user login (no persistence)',
29 'WebSocket /chat - Real-time chat functionality'
30 ],
31 websocket: {
32 url: 'ws://localhost:3000/chat',
33 events: ['join', 'message', 'leave']
34 }
35 };
36});
37
38// Simple authentication endpoints (no database)
39app.post('/auth/register',
40 validate({
41 body: z.object({
42 username: z.string().min(3).max(20),
43 email: z.string().email(),
44 password: z.string().min(6)
45 })
46 }, async (req, res) => {
47 // Check if user already exists
48 const existingUser = users.find(u => u.email === req.body.email || u.username === req.body.username);
49 if (existingUser) {
50 res.status(400);
51 return { error: 'User already exists with this email or username' };
52 }
53
54 // Create user (in memory)
55 const user = {
56 id: Date.now().toString(),
57 username: req.body.username,
58 email: req.body.email,
59 createdAt: new Date().toISOString()
60 };
61
62 users.push(user);
63
64 return {
65 user,
66 token: `demo-token-${user.id}`,
67 message: 'User registered successfully (demo mode - no persistence)'
68 };
69 })
70);
71
72// Basic WebSocket handler
73app.websocket('/chat', {
74 connect: (socket: any) => {
75 console.log(`🔗 WebSocket client connected: ${socket.id}`);
76 },
77
78 disconnect: (socket: any) => {
79 console.log(`❌ WebSocket client disconnected: ${socket.id}`);
80 },
81
82 join: (socket: any, data: any) => {
83 console.log(`📝 Join event received:`, data);
84 const roomId = data.roomId || 'general';
85 const username = data.username || 'Anonymous';
86
87 console.log(`👥 ${username} joined room ${roomId}`);
88
89 return {
90 success: true,
91 message: `Joined room ${roomId}`,
92 room: rooms.find(r => r.id === roomId) || { id: roomId, name: roomId }
93 };
94 },
95
96 message: (socket: any, data: any) => {
97 console.log(`💬 Message event received:`, data);
98 const roomId = data.roomId || 'general';
99 const username = data.username || 'Anonymous';
100
101 const message = {
102 id: Date.now(),
103 content: data.message,
104 sender: username,
105 roomId,
106 timestamp: new Date().toISOString()
107 };
108
109 // Store message in memory
110 messages.push(message);
111 console.log(`📨 Broadcasting message to room ${roomId}:`, message);
112
113 return { success: true, message: 'Message sent' };
114 }
115});
116
117// REST API endpoints
118app.get('/rooms', (req, res) => {
119 return {
120 rooms,
121 message: 'Available chat rooms'
122 };
123});
124
125app.get('/rooms/:roomId/messages', (req, res) => {
126 const roomMessages = messages
127 .filter(m => m.roomId === req.params.roomId)
128 .slice(-50); // Last 50 messages
129
130 return {
131 messages: roomMessages,
132 roomId: req.params.roomId,
133 count: roomMessages.length
134 };
135});
136
137const PORT = Number(process.env.PORT) || 3000;
138app.listen(PORT, () => {
139 console.log(`Real-time Chat Server running on port ${PORT}`);
140 console.log(`WebSocket endpoint: ws://localhost:${PORT}/chat`);
141 console.log(`Test client: http://localhost:${PORT}/test`);
142});