@unitio-code/url-shortener
Version:
A simple URL shortening library
96 lines (95 loc) • 2.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.urlStorage = exports.DEFAULT_SHORT_URL_OPTIONS = void 0;
exports.encodeId = encodeId;
exports.decodeShortUrl = decodeShortUrl;
exports.storeUrlMapping = storeUrlMapping;
exports.getOriginalUrl = getOriginalUrl;
exports.buildShortUrl = buildShortUrl;
const CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const BASE = CHARACTERS.length;
/**
* Generates a short URL code from a numeric ID using base62 encoding
* @param id - The numeric ID to encode
* @returns The base62 encoded string
*/
function encodeId(id) {
let shortUrl = "";
let num = id;
while (num > 0) {
shortUrl = CHARACTERS[num % BASE] + shortUrl;
num = Math.floor(num / BASE);
}
return shortUrl || CHARACTERS[0];
}
/**
* Decodes a short URL code back to its numeric ID
* @param shortCode - The base62 encoded string
* @returns The decoded numeric ID
*/
function decodeShortUrl(shortCode) {
let id = 0;
for (let i = 0; i < shortCode.length; i++) {
const char = shortCode[i];
const charIndex = CHARACTERS.indexOf(char);
if (charIndex === -1) {
throw new Error(`Invalid character in short URL: ${char}`);
}
id = id * BASE + charIndex;
}
return id;
}
/**
* Default options for building a short URL
*/
exports.DEFAULT_SHORT_URL_OPTIONS = {
domain: "short.url",
includeRedirectPath: true,
redirectPathSegment: "r",
includeProtocol: false,
protocol: "https",
pathSeparator: "/",
};
/**
* In-memory storage for URL mappings
* Maps numeric IDs to their original URLs
*/
exports.urlStorage = new Map();
/**
* Stores a URL mapping
* @param id - The numeric ID
* @param originalUrl - The original URL
*/
function storeUrlMapping(id, originalUrl) {
exports.urlStorage.set(id, originalUrl);
}
/**
* Retrieves the original URL for a given ID
* @param id - The numeric ID
* @returns The original URL if found, undefined otherwise
*/
function getOriginalUrl(id) {
return exports.urlStorage.get(id);
}
/**
* Builds a complete short URL with domain and customizable options
* @param id - The numeric ID to encode
* @param options - Configuration options for the short URL
* @returns The complete short URL
*/
function buildShortUrl(id, options) {
const opts = typeof options === "string"
? { ...exports.DEFAULT_SHORT_URL_OPTIONS, domain: options }
: { ...exports.DEFAULT_SHORT_URL_OPTIONS, ...options };
const shortCode = encodeId(id);
let url = "";
if (opts.includeProtocol && opts.protocol) {
url += `${opts.protocol}://`;
}
url += opts.domain;
if (opts.includeRedirectPath && opts.redirectPathSegment) {
url += `${opts.pathSeparator}${opts.redirectPathSegment}`;
}
url += `${opts.pathSeparator}${shortCode}`;
return url;
}