Spaces:
Running
Running
File size: 4,325 Bytes
1fe073f 371b64f 1fe073f 1fa708f 1fe073f b125087 1fe073f b125087 1fe073f a6d0947 1fe073f a6d0947 a510753 7f05a1c a510753 67d10f0 1fe073f a510753 1fe073f a510753 1fe073f a510753 1fe073f a510753 1fe073f 67d10f0 a510753 67d10f0 a510753 67d10f0 c607f92 a510753 67d10f0 a6d0947 67d10f0 a510753 1fe073f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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}`);
}); |