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,
}