BioNexus / server /index.js
gaialive's picture
Upload index.js
a6d0947 verified
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}`);
});