-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
129 lines (111 loc) · 3.5 KB
/
Copy pathserver.js
File metadata and controls
129 lines (111 loc) · 3.5 KB
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
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const validUrl = require('valid-url');
const { nanoid } = require('nanoid');
const cors = require('cors');
const path = require('path');
const Url = require('./models/url');
const app = express();
// Middleware
app.use(express.json());
app.use(cors());
app.use(express.static('public'));
// MongoDB Connection
let isConnected = false;
const connectToDatabase = async () => {
if (isConnected) {
return;
}
try {
await mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
isConnected = true;
console.log('MongoDB connected successfully');
} catch (err) {
console.error('MongoDB connection error:', err.message);
throw err;
}
};
// API Routes
// Create short URL
app.post('/api/shorten', async (req, res) => {
await connectToDatabase();
const { longUrl } = req.body;
console.log('Received request to shorten URL:', longUrl);
// Check if the URL is valid
if (!validUrl.isUri(longUrl)) {
console.log('Invalid URL received:', longUrl);
return res.status(400).json({ error: 'Invalid URL' });
}
try {
// Check if URL already exists
let url = await Url.findOne({ longUrl });
if (url) {
console.log('Existing URL found:', url);
return res.json(url);
}
// Create URL code and short URL
const urlCode = nanoid(8);
const baseUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: process.env.BASE_URL || `http://localhost:${process.env.PORT || 3000}`;
const shortUrl = `${baseUrl}/${urlCode}`;
// Create new URL document
url = new Url({
longUrl,
shortUrl,
urlCode,
});
await url.save();
console.log('New URL created:', url);
res.json(url);
} catch (err) {
console.error('Error in /api/shorten:', err.message);
res.status(500).json({ error: 'Server error', details: err.message });
}
});
// Redirect to long URL
app.get('/:code', async (req, res) => {
await connectToDatabase();
try {
const url = await Url.findOne({ urlCode: req.params.code });
if (url) {
// Increment clicks
url.clicks += 1;
await url.save();
return res.redirect(url.longUrl);
}
return res.status(404).json({ error: 'URL not found' });
} catch (err) {
console.error('Error in redirect:', err.message);
res.status(500).json({ error: 'Server error' });
}
});
// Get all URLs
app.get('/api/urls', async (req, res) => {
await connectToDatabase();
try {
const urls = await Url.find().sort({ createdAt: -1 });
console.log('Retrieved URLs count:', urls.length);
res.json(urls);
} catch (err) {
console.error('Error in /api/urls:', err.message);
res.status(500).json({ error: 'Server error' });
}
});
// Handle root path
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Only start the server if we're not in a Vercel environment
if (process.env.NODE_ENV !== 'production') {
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
}
// Export the Express API for Vercel
module.exports = app;