import { userAgent } from 'fast-meta-tags'
import timeoutSignal from 'timeout-abort-signal'
async function getFileBuffer(src, opt = {}) {
const t = timeoutSignal(opt.signal, opt.timeout)
try {
const res = await fetch(src, {
signal: t.signal,
headers: {
Accept: '*/*',
'User-Agent': opt?.userAgent || userAgent,
},
})
if (!res.ok) return null
const type = res.headers.get('Content-Type')
const name = toFilename(src, type)
const arrayBuffer = await res.arrayBuffer()
const buffer = new Uint8Array(arrayBuffer)
return { src, type, name, buffer }
} catch {
return null
} finally {
t.destroy()
}
}
function toFilename(url, type) {
switch (type) {
case 'image/png':
return 'preview.png'
case 'image/jpg':
case 'image/jpeg':
return 'preview.jpeg'
case 'image/gif':
return 'preview.gif'
}
return decodeURIComponent(url?.split('/').pop())
}
export async function getFile(src, opt) {
if (!src) return null
return opt?.noBuffer
? { src, name: toFilename(src, null), buffer: null }
: await getFileBuffer(src, opt)
}
export function getDomain(url) {
try {
return new URL(url).hostname
} catch (error) {
return null
}
}
export function matchDomain(u1, u2) {
try {
const h1 = new URL(u1).hostname
const h2 = new URL(u2).hostname
return h1 === h2 || h1.endsWith('.' + h2)
} catch {
return false
}
}
export function htmlToText(html) {
if (!html) return null
const decoded = html
.replace(/ /gi, ' ')
.replace(/&/gi, '&')
.replace(/</gi, '<')
.replace(/>/gi, '>')
.replace(/"/gi, '"')
.replace(/'/g, "'")
.replace(/'/gi, "'")
.replace(/©/gi, '©')
.replace(/®/gi, '®')
.replace(/…/gi, '…')
.replace(/—/gi, '—')
.replace(/–/gi, '–')
.replace(/<[^>]*?(?:\[[^\]]*\][^>]*?)*>/gs, '')
return decoded
.normalize('NFKC')
.replace(/\[\d+\]/g, '')
.replace(/\[[a-z]\]/gi, '')
.replace(/&[a-z]+;|&#\d+;/gi, '')
.replace(/\s+/g, ' ')
.trim()
}