| const express = require('express'); |
| const app = express(); |
| const dotenv = require('dotenv'); |
| const path = require('path'); |
| const cors = require('cors'); |
| const cookieParser = require('cookie-parser'); |
| const connectDatabase = require('./config/connectDatabase'); |
| const { execSync } = require('child_process'); |
| const fs = require('fs'); |
|
|
| dotenv.config({ path: path.join(__dirname, 'config', 'config.env') }); |
|
|
| const products = require('./routes/product'); |
| const users = require('./routes/user'); |
| const adminRoutes = require('./routes/admin'); |
|
|
| connectDatabase(); |
|
|
| const isProduction = process.env.NODE_ENV === 'production'; |
| const isDevelopment = process.env.NODE_ENV === 'development'; |
| if (isProduction) { |
| const buildPath = path.join(__dirname, '..', 'frontend', 'build'); |
| const frontendPath = path.join(__dirname, '..', 'frontend'); |
| |
| if (!fs.existsSync(buildPath)) { |
| console.log('ποΈ Building frontend for production...'); |
| try { |
| const packageJsonPath = path.join(frontendPath, 'package.json'); |
| const nodeModulesPath = path.join(frontendPath, 'node_modules'); |
| |
| if (!fs.existsSync(nodeModulesPath)) { |
| console.log('π¦ Installing frontend dependencies...'); |
| execSync('npm install', { |
| cwd: frontendPath, |
| stdio: 'inherit' |
| }); |
| } |
| |
| console.log('π¦ Building React app...'); |
| execSync('npm run build', { |
| cwd: frontendPath, |
| stdio: 'inherit' |
| }); |
| console.log('β
Frontend build completed'); |
| } catch (error) { |
| console.error('β Frontend build failed:', error.message); |
| console.log('β οΈ Starting server without frontend build...'); |
| } |
| } |
| } |
|
|
| const getBackendUrl = () => { |
| if (isProduction) { |
|
|
| return process.env.APP_URL || `https://${process.env.HOST || 'localhost'}:${process.env.PORT || 7860}`; |
| } |
| return 'http://localhost:7860'; |
| }; |
|
|
| const getFrontendUrl = () => { |
| if (isProduction) { |
|
|
| return process.env.FRONTEND_URL || getBackendUrl().replace('7860', '3000').replace('api.', ''); |
| } |
| return 'http://localhost:3000'; |
| }; |
|
|
| const corsOptions = { |
| origin: function (origin, callback) { |
| if (!origin) return callback(null, true); |
| |
| const backendUrl = getBackendUrl(); |
| const frontendUrl = getFrontendUrl(); |
| |
| const allowedOrigins = [ |
| backendUrl, |
| frontendUrl, |
| 'http://localhost:3000', |
| 'https://localhost:3000', |
| 'http://localhost:3001', |
| 'https://localhost:3001', |
| 'http://localhost:7860', |
| 'https://localhost:7860', |
| 'https://mkshopping.onrender.com', |
| 'https://mkshoppingbd.onrender.com', |
| 'https://kumar715-mkcart.hf.space' |
| ] |
| |
| |
| if (origin.endsWith('.hf.space')) { |
| return callback(null, true); |
| } |
|
|
| if (isDevelopment) { |
| if (origin.includes('localhost') || origin.includes('127.0.0.1')) { |
| return callback(null, true); |
| } |
| } |
| |
| if (allowedOrigins.includes(origin)) { |
| callback(null, true); |
| } else { |
| console.log("Blocked by CORS:", origin); |
| console.log("Allowed origins:", allowedOrigins); |
| callback(new Error("Not allowed by CORS")); |
| } |
| }, |
| credentials: true, |
| methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'], |
| allowedHeaders: [ |
| 'Content-Type', |
| 'Authorization', |
| 'X-Requested-With', |
| 'Accept', |
| 'Origin', |
| 'Access-Control-Request-Method', |
| 'Access-Control-Request-Headers' |
| ], |
| exposedHeaders: ['Set-Cookie', 'Authorization'], |
| preflightContinue: false, |
| optionsSuccessStatus: 204 |
| }; |
|
|
| app.use(cors(corsOptions)); |
|
|
| app.options('*', cors(corsOptions)); |
|
|
| app.use(express.json()); |
| app.use(express.urlencoded({ extended: true })); |
| app.use(cookieParser()); |
|
|
| app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); |
|
|
| app.use('/images', express.static(path.join(__dirname, '../frontend/public/images'))); |
|
|
| app.use('/api', products); |
| app.use('/api', users); |
| app.use('/api/admin', adminRoutes); |
|
|
| if (isProduction) { |
| const buildPath = path.join(__dirname, '..', 'frontend', 'build'); |
| if (fs.existsSync(buildPath)) { |
| app.use(express.static(buildPath)); |
| app.get('*', (req, res) => { |
| res.sendFile(path.resolve(buildPath, 'index.html')); |
| }); |
| } |
| } |
|
|
| app.use((err, req, res, next) => { |
| const statusCode = res.statusCode === 200 ? 500 : res.statusCode; |
| res.status(statusCode); |
| res.json({ |
| message: err.message, |
| stack: isDevelopment ? err.stack : {}, |
| }); |
| }); |
|
|
| app.listen(process.env.PORT, () => { |
| console.log(`π Server running on Port ${process.env.PORT} in ${process.env.NODE_ENV} mode`); |
| console.log(`π‘ Backend URL: ${getBackendUrl()}`); |
| console.log(`π Frontend URL: ${getFrontendUrl()}`); |
| console.log(`π§ Environment: ${isProduction ? 'Production' : 'Development'}`); |
| |
| }); |