UNPKG

@developers-joyride/shortify

Version:

High performance URL shortener library with multi-database support (MongoDB, SQLite, PostgreSQL, MySQL)

217 lines (190 loc) 7.04 kB
import express, { Request, Response } from "express"; import Shortify from "../src"; import dotenv from "dotenv"; // Load environment variables dotenv.config(); // Create Express app const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Create Shortify instance const shortify = new Shortify( process.env.BASE_URL || "http://localhost:3000/", process.env.MONGODB_URI || "mongodb://localhost:27017/shortify" ); // Connect to database before starting server async function startServer() { try { // Connect to MongoDB await shortify.connect(); console.log("Connected to MongoDB"); // Set up routes // Home page - Simple form to create shortened URLs app.get("/", (req, res) => { res.send(` <html> <head> <title>URL Shortener</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } .form-group { margin-bottom: 15px; } label { display: block; margin-bottom: 5px; } input[type="text"] { width: 100%; padding: 8px; } input[type="number"] { width: 100px; padding: 8px; } button { padding: 10px 15px; background: #4CAF50; color: white; border: none; cursor: pointer; } .result { margin-top: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px; } </style> </head> <body> <h1>URL Shortener</h1> <form action="/shorten" method="POST"> <div class="form-group"> <label for="url">URL to Shorten:</label> <input type="text" id="url" name="url" placeholder="https://example.com" required> </div> <div class="form-group"> <label for="customId">Custom ID (optional):</label> <input type="text" id="customId" name="customId" placeholder="my-custom-id"> </div> <div class="form-group"> <label for="expiry">Expires in (days):</label> <input type="number" id="expiry" name="expiry" min="1" value="30"> </div> <button type="submit">Shorten URL</button> </form> </body> </html> `); }); // Shorten URL endpoint app.post("/shorten", async (req: Request, res: Response) => { try { const { url, customId, expiry } = req.body; if (!url) { return res.status(400).json({ error: "URL is required" }); } const options: any = {}; if (customId) { options.customUrlId = customId; } if (expiry) { options.expiresInDays = parseInt(expiry); } const result = await shortify.shorten(url, options); res.send(` <html> <head> <title>URL Shortened</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } .result { margin-top: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px; } .copy-btn { padding: 5px 10px; background: #4CAF50; color: white; border: none; cursor: pointer; margin-left: 10px; } </style> </head> <body> <h1>URL Shortened</h1> <div class="result"> <p><strong>Original URL:</strong> ${result.originalUrl}</p> <p> <strong>Shortened URL:</strong> <a href="${result.shortUrl}" target="_blank">${ result.shortUrl }</a> <button class="copy-btn" onclick="copyToClipboard('${ result.shortUrl }')">Copy</button> </p> <p><strong>URL ID:</strong> ${result.urlId}</p> ${ result.expiresAt ? `<p><strong>Expires at:</strong> ${new Date( result.expiresAt ).toLocaleString()}</p>` : "" } </div> <p><a href="/">← Back to homepage</a></p> <script> function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { alert('URL copied to clipboard'); }); } </script> </body> </html> `); } catch (error) { console.error("Error shortening URL:", error); res.status(500).json({ error: "Failed to shorten URL" }); } }); // Redirect shortened URLs app.get( "/:urlId", async (req: Request<{ urlId: string }>, res: Response) => { try { const { urlId } = req.params; const originalUrl = await shortify.resolve(urlId); if (originalUrl) { return res.redirect(originalUrl); } else { return res.status(404).send(` <html> <head> <title>URL Not Found</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; text-align: center; } </style> </head> <body> <h1>URL Not Found</h1> <p>The shortened URL you're looking for doesn't exist or has expired.</p> <p><a href="/">← Go to homepage</a></p> </body> </html> `); } } catch (error) { console.error("Error resolving URL:", error); res.status(500).json({ error: "Failed to resolve URL" }); } } ); // API endpoint to get URL stats app.get( "/api/stats/:urlId", async (req: Request<{ urlId: string }>, res: Response) => { try { const { urlId } = req.params; const stats = await shortify.getStats(urlId); if (stats) { return res.json(stats); } else { return res.status(404).json({ error: "URL not found" }); } } catch (error) { console.error("Error getting URL stats:", error); res.status(500).json({ error: "Failed to get URL stats" }); } } ); // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); }); } catch (error) { console.error("Failed to start server:", error); process.exit(1); } } // Graceful shutdown process.on("SIGINT", async () => { console.log("Shutting down server..."); await shortify.disconnect(); console.log("Disconnected from MongoDB"); process.exit(0); }); // Start the server startServer();