import { Url } from './Url.js';
export class ImageUrlNormalizer {
static normalizeImageUrls(images: string[], baseUrl: Url): string[] {
return images.map(imageUrl => ImageUrlNormalizer.normalizeImageUrl(imageUrl, baseUrl));
}
static normalizeImageUrl(imageUrl: string, baseUrl: Url): string {
try {
// If already absolute URL, return as is
if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) {
return Url.create(imageUrl).toString();
}
// Handle protocol-relative URLs (//example.com/image.jpg)
if (imageUrl.startsWith('//')) {
return Url.create('https:' + imageUrl).toString();
}
// Handle absolute path (/images/pic.jpg)
if (imageUrl.startsWith('/')) {
return baseUrl.origin + imageUrl;
}
// Handle relative path (images/pic.jpg or ./images/pic.jpg)
const cleanImageUrl = imageUrl.startsWith('./') ? imageUrl.substring(2) : imageUrl;
const basePath = baseUrl.pathname.endsWith('/') ? baseUrl.pathname : baseUrl.pathname + '/';
return baseUrl.origin + basePath + cleanImageUrl;
} catch (error) {
// If URL normalization fails, return the original URL
// This ensures we don't break the entire processing for one bad image URL
return imageUrl;
}
}
static isValidImageUrl(url: string): boolean {
try {
const urlObj = new URL(url);
return urlObj.protocol === 'http:' || urlObj.protocol === 'https:';
} catch {
return false;
}
}
static filterValidImageUrls(images: string[]): string[] {
return images.filter(ImageUrlNormalizer.isValidImageUrl);
}
}