64 lines
2.1 KiB
JavaScript
64 lines
2.1 KiB
JavaScript
const { cacheImageFromUrl } = require("./redis/linkPreviewImageCache.service")
|
|
|
|
function extractImageUrlsFromDescription(description, { max = 5 } = {}) {
|
|
if (!description || typeof description !== "string") return []
|
|
const regex = /<img[^>]+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(
|
|
/<img[^>]+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,
|
|
}
|