/**
* @fileoverview URL Utilities for Rantii
* @author retoor <retoor@molodetz.nl>
* @description URL parsing and detection utilities
* @keywords url, link, youtube, image, detection
*/
const URL_REGEX = /https?:\/\/[^\s<]+[^<.,:;"')\]\s]/gi;
const YOUTUBE_REGEX = /(?:youtube\.com\/(?:watch\?v=|embed\/|v\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/i;
const IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp'];
function extractUrls(text) {
const matches = text.match(URL_REGEX);
return matches || [];
}
function isYoutubeUrl(url) {
return YOUTUBE_REGEX.test(url);
}
function getYoutubeVideoId(url) {
const match = url.match(YOUTUBE_REGEX);
return match ? match[1] : null;
}
function getYoutubeThumbnail(videoId) {
return `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`;
}
function getYoutubeEmbedUrl(videoId) {
return `https://www.youtube-nocookie.com/embed/${videoId}`;
}
function isImageUrl(url) {
const lower = url.toLowerCase();
return IMAGE_EXTENSIONS.some(ext => lower.includes(ext));
}
function isGifUrl(url) {
return url.toLowerCase().includes('.gif');
}
function extractImageUrls(text) {
return extractUrls(text).filter(isImageUrl);
}
function extractYoutubeUrls(text) {
return extractUrls(text).filter(isYoutubeUrl);
}
function extractNonMediaUrls(text) {
return extractUrls(text).filter(url => !isImageUrl(url) && !isYoutubeUrl(url));
}
function sanitizeUrl(url) {
try {
const parsed = new URL(url);
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
return null;
}
return parsed.href;
} catch {
return null;
}
}
function getDomain(url) {
try {
const parsed = new URL(url);
return parsed.hostname;
} catch {
return null;
}
}
function makeAbsoluteUrl(url, base) {
try {
return new URL(url, base).href;
} catch {
return url;
}
}
function isDevrantImageUrl(url) {
return url.includes('devrant.com') || url.includes('devrant.io');
}
function buildDevrantImageUrl(imagePath) {
if (imagePath.startsWith('http')) {
return imagePath;
}
return `https://img.devrant.com/${imagePath}`;
}
function buildAvatarUrl(avatar) {
if (!avatar || !avatar.i) {
return null;
}
return `https://avatars.devrant.com/${avatar.i}`;
}
export {
extractUrls,
isYoutubeUrl,
getYoutubeVideoId,
getYoutubeThumbnail,
getYoutubeEmbedUrl,
isImageUrl,
isGifUrl,
extractImageUrls,
extractYoutubeUrls,
extractNonMediaUrls,
sanitizeUrl,
getDomain,
makeAbsoluteUrl,
isDevrantImageUrl,
buildDevrantImageUrl,
buildAvatarUrl
};