Spaces:
Sleeping
Sleeping
| const express = require('express'); | |
| const cors = require('cors'); | |
| const dotenv = require('dotenv'); | |
| const path = require('path'); | |
| // Import models | |
| const News = require('./models/News'); | |
| const Dataset = require('./models/Dataset'); | |
| dotenv.config(); | |
| const app = express(); | |
| // Use port 8501 for Hugging Face Spaces, or 3001 for local development | |
| const isHuggingFaceSpaces = process.env.HF_SPACES === 'true' || process.env.HF_SPACES === true || !!process.env.HF_SPACES; | |
| const PORT = isHuggingFaceSpaces ? 8501 : (process.env.PORT || 3001); | |
| // Enable CORS for all origins in development, specific origins in production | |
| if (process.env.NODE_ENV === 'development') { | |
| app.use(cors()); | |
| } else { | |
| // In production (like Hugging Face Spaces), be more specific about CORS | |
| app.use(cors({ | |
| origin: function (origin, callback) { | |
| // Allow requests with no origin (like mobile apps or curl requests) | |
| if (!origin) return callback(null, true); | |
| // Allow localhost in development | |
| if (origin.startsWith('http://localhost') || | |
| origin.startsWith('https://localhost') || | |
| origin.includes('huggingface.co') || | |
| origin.includes('hf.space') || | |
| origin === 'http://localhost:80' || | |
| origin === 'http://localhost:5173') { | |
| return callback(null, true); | |
| } | |
| // Allow same origin requests | |
| if (origin === `http://localhost:${PORT}`) { | |
| return callback(null, true); | |
| } | |
| callback(null, true); // Allow all in production for now | |
| } | |
| })); | |
| } | |
| app.use(express.json()); | |
| // Serve static files from the public directory in production | |
| if (process.env.NODE_ENV === 'production') { | |
| app.use(express.static(path.join(__dirname, 'public'))); | |
| } | |
| // Health check endpoint | |
| app.get('/health', (req, res) => { | |
| res.status(200).json({ | |
| status: 'OK', | |
| timestamp: new Date().toISOString(), | |
| uptime: process.uptime() | |
| }); | |
| }); | |
| // API routes | |
| app.get('/api/news', async (req, res) => { | |
| try { | |
| const news = await News.getAll(); | |
| res.json(news); | |
| } catch (error) { | |
| console.error('Error fetching news:', error); | |
| res.status(500).json({ error: 'Failed to fetch news' }); | |
| } | |
| }); | |
| app.get('/api/news/:id', async (req, res) => { | |
| try { | |
| const { id } = req.params; | |
| const newsItem = await News.getById(id); | |
| if (!newsItem) { | |
| return res.status(404).json({ error: 'News item not found' }); | |
| } | |
| res.json(newsItem); | |
| } catch (error) { | |
| console.error('Error fetching news item:', error); | |
| res.status(500).json({ error: 'Failed to fetch news item' }); | |
| } | |
| }); | |
| app.get('/api/datasets', async (req, res) => { | |
| try { | |
| const datasets = await Dataset.getAll(); | |
| res.json(datasets); | |
| } catch (error) { | |
| console.error('Error fetching datasets:', error); | |
| res.status(500).json({ error: 'Failed to fetch datasets' }); | |
| } | |
| }); | |
| app.get('/api/datasets/:id', async (req, res) => { | |
| try { | |
| const { id } = req.params; | |
| const dataset = await Dataset.getById(id); | |
| if (!dataset) { | |
| return res.status(404).json({ error: 'Dataset not found' }); | |
| } | |
| res.json(dataset); | |
| } catch (error) { | |
| console.error('Error fetching dataset:', error); | |
| res.status(500).json({ error: 'Failed to fetch dataset' }); | |
| } | |
| }); | |
| // Serve the React app for all non-API routes in production | |
| if (process.env.NODE_ENV === 'production') { | |
| // For any non-API routes, serve the React app | |
| app.get('*', (req, res) => { | |
| // Don't serve the React app for API routes or health check | |
| if (req.path.startsWith('/api/') || req.path === '/health') { | |
| // For API routes that don't exist, return 404 | |
| if (req.path.startsWith('/api/')) { | |
| return res.status(404).json({ error: 'API endpoint not found' }); | |
| } | |
| // For health check, it's already handled above | |
| return res.status(404).json({ error: 'Not found' }); | |
| } | |
| // Serve the React app for all other routes | |
| res.sendFile(path.resolve(__dirname, 'public', 'index.html')); | |
| }); | |
| } else { | |
| // In development, serve API info at root | |
| app.get('/', (req, res) => { | |
| res.json({ | |
| message: 'BioNexus Hub API', | |
| version: '1.0.0', | |
| timestamp: new Date().toISOString() | |
| }); | |
| }); | |
| } | |
| app.listen(PORT, '0.0.0.0', () => { | |
| console.log(`BioNexus Hub server running on port ${PORT}`); | |
| }); |