const { cacheImageFromUrl } = require("./redis/linkPreviewImageCache.service") function extractImageUrlsFromDescription(description, { max = 5 } = {}) { if (!description || typeof description !== "string") return [] const regex = /]+src\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s>]+))[^>]*>/gi const urls = [] let match while ((match = regex.exec(description)) !== null) { const src = match[1] || match[2] || match[3] || "" if (src) urls.push(src) if (urls.length >= max) break } return urls } function replaceDescriptionImageUrls(description, urlMap, { maxImages = 5 } = {}) { if (!description || typeof description !== "string") return description let seen = 0 const safeMap = urlMap instanceof Map ? urlMap : new Map() return description.replace( /]+src\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s>]+))[^>]*>/gi, (full, srcDq, srcSq, srcUnq) => { seen += 1 if (seen > maxImages) return "" const src = srcDq || srcSq || srcUnq || "" const next = safeMap.get(src) if (!next) return full return full.replace(src, next) } ) } async function cacheLinkPreviewImages({ product, baseUrl } = {}) { if (!product || typeof product !== "object") return { product } const images = Array.isArray(product.images) ? product.images : [] const description = product.description || "" const descImages = extractImageUrlsFromDescription(description, { max: 5 }) const combined = [...images, ...descImages].filter(Boolean) const unique = Array.from(new Set(combined)) const urlMap = new Map() for (const url of unique) { const cached = await cacheImageFromUrl(url, { ttlSeconds: 5 * 60 }) if (cached?.key) { urlMap.set(url, `${baseUrl}/cache/deal_create/${cached.key}`) } } const nextImages = images.map((url) => urlMap.get(url) || url) const nextDescription = replaceDescriptionImageUrls(description, urlMap, { maxImages: 5 }) return { product: { ...product, images: nextImages, description: nextDescription, }, } } module.exports = { cacheLinkPreviewImages, }