import express from 'express'; import cors from 'cors'; import { createUser, getUserByEmail, updateUser, getAllUsers, getUserById } from './lib/api/users.js'; import { getScripts, getScriptById, createScript, updateScript, deleteScript, moderateScript } from './lib/api/scripts.js'; import { login, register, refreshToken } from './lib/api/auth.js'; import { rateScript, getUserRating, getScriptRatingStats } from './lib/api/ratings.js'; import { getPlatformAnalytics, getScriptAnalytics, trackEvent } from './lib/api/analytics.js'; import { createCollection, getUserCollections, getPublicCollections, addScriptToCollection } from './lib/api/collections.js'; const app = express(); const PORT = process.env.PORT || 3000; // Middleware app.use(cors({ origin: process.env.CORS_ORIGIN || '*', credentials: true })); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true })); // Health check endpoint app.get('/api/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // Auth routes app.post('/api/auth/login', async (req, res) => { try { const result = await login(req.body); res.json(result); } catch (error) { console.error('Login error:', error); res.status(401).json({ error: 'Invalid credentials' }); } }); app.post('/api/auth/register', async (req, res) => { try { const result = await register(req.body); res.json(result); } catch (error) { console.error('Register error:', error); res.status(400).json({ error: 'Registration failed' }); } }); // Scripts routes app.get('/api/scripts', async (req, res) => { try { const result = await getScripts(req.query); res.json(result); } catch (error) { console.error('Get scripts error:', error); res.status(500).json({ error: 'Failed to fetch scripts' }); } }); app.get('/api/scripts/:id', async (req, res) => { try { const script = await getScriptById(req.params.id); if (!script) { return res.status(404).json({ error: 'Script not found' }); } res.json(script); } catch (error) { console.error('Get script error:', error); res.status(500).json({ error: 'Failed to fetch script' }); } }); app.post('/api/scripts', async (req, res) => { try { const userId = req.headers['x-user-id'] as string; if (!userId) { return res.status(401).json({ error: 'Unauthorized' }); } const result = await createScript(req.body, userId); res.json(result); } catch (error) { console.error('Create script error:', error); res.status(500).json({ error: 'Failed to create script' }); } }); // Users routes app.get('/api/users', async (req, res) => { try { const result = await getAllUsers(); res.json(result); } catch (error) { console.error('Get users error:', error); res.status(500).json({ error: 'Failed to fetch users' }); } }); app.get('/api/users/:id', async (req, res) => { try { const user = await getUserById(req.params.id); if (!user) { return res.status(404).json({ error: 'User not found' }); } res.json(user); } catch (error) { console.error('Get user error:', error); res.status(500).json({ error: 'Failed to fetch user' }); } }); // Analytics routes app.get('/api/analytics/platform', async (req, res) => { try { const days = parseInt(req.query.days as string) || 30; const result = await getPlatformAnalytics(days); res.json(result); } catch (error) { console.error('Analytics error:', error); res.status(500).json({ error: 'Failed to fetch analytics' }); } }); app.post('/api/analytics/track', async (req, res) => { try { const result = await trackEvent(req.body); res.json(result); } catch (error) { console.error('Track event error:', error); res.status(500).json({ error: 'Failed to track event' }); } }); // Collections routes app.get('/api/collections', async (req, res) => { try { const userId = req.headers['x-user-id'] as string; const result = userId ? await getUserCollections(userId) : await getPublicCollections(); res.json(result); } catch (error) { console.error('Get collections error:', error); res.status(500).json({ error: 'Failed to fetch collections' }); } }); // Ratings routes app.post('/api/ratings', async (req, res) => { try { const result = await rateScript(req.body); res.json(result); } catch (error) { console.error('Rate script error:', error); res.status(500).json({ error: 'Failed to rate script' }); } }); app.get('/api/scripts/:id/ratings', async (req, res) => { try { const result = await getScriptRatingStats(req.params.id); res.json(result); } catch (error) { console.error('Get ratings error:', error); res.status(500).json({ error: 'Failed to fetch ratings' }); } }); // Error handling middleware app.use((error: any, req: express.Request, res: express.Response, next: express.NextFunction) => { console.error('Unhandled error:', error); res.status(500).json({ error: 'Internal server error' }); }); // 404 handler app.use('*', (req, res) => { res.status(404).json({ error: 'Endpoint not found' }); }); app.listen(PORT, () => { console.log(`ScriptShare API server running on port ${PORT}`); console.log(`Environment: ${process.env.NODE_ENV}`); console.log(`Database URL configured: ${!!process.env.DATABASE_URL}`); });