@developers-joyride/shortify
v2.1.0
Published
High performance URL shortener library with multi-database support (MongoDB, SQLite, PostgreSQL, MySQL)
Downloads
157
Maintainers
Readme
Shortify
A high-performance URL shortener library for Node.js, written in TypeScript with support for multiple databases (MongoDB, SQLite, PostgreSQL, MySQL).
Features
- ⚡️ High performance: Optimized for high throughput
- 🔒 Type safety: Full TypeScript support
- 📈 Analytics: Track clicks and usage stats for your shortened URLs
- ⌛️ Expiration support: Set expiration dates for your shortened URLs
- 🛠️ Customizable: Use custom URL IDs or auto-generated ones
- 🔄 Automatic retry: Built-in database connection retry with exponential backoff
- 🧠 Unique URL IDs: Each shorten() call generates a unique URL ID, ensuring no conflicts
- 🗄️ Multi-database support: Choose between MongoDB, SQLite, PostgreSQL, or MySQL
- 🔧 Database abstraction: Easy to switch between databases without changing your code
Installation
# Using npm
npm i @developers-joyride/shortify
# Using yarn
yarn add @developers-joyride/shortifyUsage
Basic Usage
MongoDB (Original way - Backward Compatible)
import Shortify from "@developers-joyride/shortify";
import dotenv from "dotenv";
// Load environment variables
dotenv.config();
// Create a new Shortify instance with MongoDB (backward compatible)
const shortify = Shortify.createWithMongo(
"https://your-domain.com/", // Base URL for your shortened links
process.env.MONGODB_URI || "mongodb://localhost:27017/shortify" // MongoDB connection URI
);
// Connect to database
await shortify.connect();
// Shorten a URL
const result = await shortify.shorten(
"https://example.com/very-long-url-that-needs-shortening"
);
console.log(`Shortened URL: ${result.shortUrl}`); // https://your-domain.com/abc123
// Resolve a shortened URL
const originalUrl = await shortify.resolve("abc123");
console.log(`Original URL: ${originalUrl}`); // https://example.com/very-long-url-that-needs-shortening
// Get statistics for a shortened URL
const stats = await shortify.getStats("abc123");
console.log(`Clicks: ${stats?.clicks}`);
// Delete a shortened URL
await shortify.delete("abc123");
// Disconnect when done
await shortify.disconnect();SQLite
import Shortify, { DatabaseConfig } from "@developers-joyride/shortify";
const dbConfig: DatabaseConfig = {
type: "sqlite",
database: "./shortify.db", // Path to SQLite database file
tableName: "my_custom_urls", // Optional: Custom table name (default: "urls")
maxRetries: 3,
retryDelay: 2000,
};
const shortify = new Shortify("https://your-domain.com/", dbConfig);
await shortify.connect();
// Use the same API as before
const result = await shortify.shorten("https://example.com/long-url");
console.log(`Shortened URL: ${result.shortUrl}`);MongoDB (New Format)
import Shortify, { DatabaseConfig } from "@developers-joyride/shortify";
const dbConfig: DatabaseConfig = {
type: "mongodb",
connectionString: "mongodb://localhost:27017/shortify",
collectionName: "my_custom_urls", // Optional: Custom collection name (default: "urls")
maxRetries: 3,
retryDelay: 2000,
};
const shortify = new Shortify("https://your-domain.com/", dbConfig);
await shortify.connect();
// Use the same API as before
const result = await shortify.shorten("https://example.com/long-url");
console.log(`Shortened URL: ${result.shortUrl}`);Custom Collection/Table Names: You can specify custom collection names for MongoDB using the collectionName option, or custom table names for SQLite, PostgreSQL, and MySQL using the tableName option. This is useful when you want to organize your data differently or avoid conflicts with existing collections/tables. If not specified, they default to "urls".
Note: Collection and table names are now preserved exactly as specified, including case sensitivity. Previously, MongoDB collection names were automatically converted to lowercase, and SQL databases would convert unquoted table names to lowercase on case-insensitive filesystems.
MySQL
import Shortify, { DatabaseConfig } from "@developers-joyride/shortify";
const dbConfig: DatabaseConfig = {
type: "mysql",
host: "localhost",
port: 3306,
database: "shortify",
username: "root",
password: "your_password",
tableName: "my_custom_urls", // Optional: Custom table name (default: "urls")
maxRetries: 3,
retryDelay: 2000,
};
const shortify = new Shortify("https://your-domain.com/", dbConfig);
await shortify.connect();
// Use the same API as before
const result = await shortify.shorten("https://example.com/long-url");
console.log(`Shortened URL: ${result.shortUrl}`);PostgreSQL
import Shortify, { DatabaseConfig } from "@developers-joyride/shortify";
const dbConfig: DatabaseConfig = {
type: "postgresql",
host: "localhost",
port: 5432,
database: "shortify",
username: "postgres",
password: "your_password",
tableName: "my_custom_urls", // Optional: Custom table name (default: "urls")
maxRetries: 3,
retryDelay: 2000,
};
const shortify = new Shortify("https://your-domain.com/", dbConfig);
await shortify.connect();
// Use the same API as before
const result = await shortify.shorten("https://example.com/long-url");
console.log(`Shortened URL: ${result.shortUrl}`);Advanced Options
// Shorten a URL with custom options
const result = await shortify.shorten("https://example.com", {
customUrlId: "custom-id", // Use a custom ID instead of auto-generated one
urlLength: 6, // Set length of auto-generated ID (ignored if customUrlId is set)
expiresInDays: 30, // URL will expire after 30 days
baseUrl: "https://short.ly/", // Override the base URL for this specific link
});
// Each shorten() call generates a unique URL ID, even for the same original URL
const result1 = await shortify.shorten("https://example.com");
const result2 = await shortify.shorten("https://example.com");
console.log(result1.urlId !== result2.urlId); // true - different URL IDs
console.log(
(await shortify.resolve(result1.urlId)) ===
(await shortify.resolve(result2.urlId))
); // true - same original URL
// Create with connection options (MongoDB backward compatibility)
const shortify = Shortify.createWithMongo(
"https://your-domain.com/",
"mongodb://localhost:27017/shortify",
{
maxRetries: 5, // Maximum number of connection retry attempts
retryDelay: 5000, // Initial delay between retries in ms (doubles with each retry)
collectionName: "my_custom_urls", // Optional: Custom collection name (default: "urls")
}
);API Reference
Shortify Class
Constructor
constructor(baseUrl: string, dbConfig: DatabaseConfig)Static Methods
createWithMongo(baseUrl: string, mongoUri: string, options?: { maxRetries?: number, retryDelay?: number }): Create instance with MongoDB (backward compatibility)
Instance Methods
connect(): Connect to databasedisconnect(): Disconnect from databaseisReady(): Check if the connection is establishedshorten(url: string, options?: ShortifyOptions): Shorten a URLresolve(urlId: string): Resolve a short URL to its original URLgetStats(urlId: string): Get statistics for a shortened URLdelete(urlId: string): Delete a shortened URL
DatabaseConfig Interface
interface DatabaseConfig {
type: "mongodb" | "sqlite" | "postgresql" | "mysql";
connectionString?: string; // For MongoDB
database?: string; // For SQLite (file path) or PostgreSQL/MySQL (database name)
host?: string; // For PostgreSQL/MySQL
port?: number; // For PostgreSQL/MySQL
username?: string; // For PostgreSQL/MySQL
password?: string; // For PostgreSQL/MySQL
maxRetries?: number; // Maximum connection retry attempts
retryDelay?: number; // Initial delay between retries in ms
collectionName?: string; // For MongoDB: Custom collection name (default: "urls")
tableName?: string; // For SQLite/PostgreSQL/MySQL: Custom table name (default: "urls")
}ShortifyOptions Interface
interface ShortifyOptions {
baseUrl?: string; // Override the base URL
urlLength?: number; // Length of the generated URL ID
customUrlId?: string; // Custom URL ID
expiresInDays?: number; // Number of days until the URL expires
}Database Support
Shortify supports multiple database types, allowing you to choose the best option for your use case:
MongoDB
- Best for: High-traffic applications, complex queries, horizontal scaling
- Setup: Requires MongoDB server running
- Configuration: Use
connectionStringparameter
SQLite
- Best for: Simple applications, development, embedded systems
- Setup: No server required, file-based
- Configuration: Use
databaseparameter (file path)
MySQL
- Best for: Web applications, compatibility with existing MySQL infrastructure
- Setup: Requires MySQL server running
- Configuration: Use
host,port,database,username,passwordparameters
PostgreSQL
- Best for: ACID compliance, complex relationships, enterprise applications
- Setup: Requires PostgreSQL server running
- Configuration: Use
host,port,database,username,passwordparameters
Examples
Check out the examples/ directory for comprehensive usage examples:
basic-usage.ts- Basic URL shortening functionalitysqlite-example.ts- SQLite database usagepostgresql-example.ts- PostgreSQL database usagemulti-database-usage.ts- Multi-database configuration examplesclick-tracking-example.ts- Click tracking and analytics demonstrationexpress-server.ts- Express.js server integrationcustom-collection-example.ts- Custom collection name demonstrationcustom-table-names-example.ts- Custom table names for all database types
Click Tracking & Analytics
The library automatically tracks clicks when URLs are resolved. Here's a quick example:
// Create a shortened URL
const result = await shortify.shorten("https://example.com/my-page");
// Resolve the URL (this increments the click count)
const originalUrl = await shortify.resolve(result.urlId);
// Get statistics
const stats = await shortify.getStats(result.urlId);
console.log(`Clicks: ${stats?.clicks}`); // Will show 1
console.log(`Created: ${stats?.createdAt}`);
console.log(`Expires: ${stats?.expiresAt || "Never"}`);For a comprehensive demonstration of click tracking features, run:
npx ts-node examples/click-tracking-example.tsMigration Guide
From Previous Version
If you're upgrading from a previous version that only supported MongoDB, your code will continue to work without changes:
// Old way (still works)
const shortify = new Shortify(
"https://your-domain.com/",
"mongodb://localhost:27017/shortify"
);
// New way (recommended)
const shortify = Shortify.createWithMongo(
"https://your-domain.com/",
"mongodb://localhost:27017/shortify"
);License
MIT
