import { uilog } from '../../const'; // const g_url_regexp: RegExp = /^https?:\/\/[^\s/$.?#].[^\s]*$/; const urlPattern: RegExp = // eslint-disable-next-line no-useless-escape /(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})(:[0-9]+)?(\/[\w\.-]*)*\/?(\?[=&\w]*)?/gi; // x regex patterns const titleOGPattern = //i; const descriptionOGPattern = //i; const imageOGPattern = //i; // Non-Open Graph protocol regex patterns const titlePattern = /(.*?)<\/title>/i; const descriptionPattern = /<meta\s+name="description"\s+content="(.*?)"\s*\/?>/i; const imagePattern = /<img\s+[^>]*src="(https?:\/\/[^\s]+)"[^>]*>/i; const imageSrcPattern = /<link\s+rel="image_src"\s+href="(https?:\/\/[^\s]+)"\s*\/?>/i; export function useUrlPreview() { return { getUrlFromText: UseUrlPreview.getUrlFromText, getUrlListFromText: UseUrlPreview.getUrlListFromText, fetchUrlPreview: UseUrlPreview.fetchUrlPreview, }; } export class UseUrlPreview { static getTitle(html: string) { let match = titleOGPattern.exec(html); if (match) { return match[1]; } match = titlePattern.exec(html); if (match) { return match[1]; } return undefined; } static getDescription(html: string) { let match = descriptionOGPattern.exec(html); if (match) { return match[1]; } match = descriptionPattern.exec(html); if (match) { return match[1]; } return undefined; } static getImageUrl(html: string) { let match = imageOGPattern.exec(html); if (match) { return match[1]; } match = imagePattern.exec(html); if (match) { return match[1]; } match = imageSrcPattern.exec(html); if (match) { return match[1]; } return undefined; } static async fetchUrlPreview(url: string) { const r = url.match(urlPattern); if (!r || r.length === 0) { return undefined; } const _url = url.startsWith('http') ? url : `https://${url}`; try { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Request timed out')), 5000); }); const res = (await Promise.race([ fetch(_url), timeoutPromise, ])) as Response; const html = await res.text(); return { url, title: UseUrlPreview.getTitle(html), description: UseUrlPreview.getDescription(html), imageUrl: UseUrlPreview.getImageUrl(html), }; } catch (error) { uilog.error('Failed to fetch URL preview', error); return undefined; } } static getUrlFromText(text: string) { const match = urlPattern.exec(text); if (match) { return match[0]; } return undefined; } static getUrlListFromText(text: string) { return text.match(urlPattern); } }