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 =
//i;
const imagePattern = /
]*src="(https?:\/\/[^\s]+)"[^>]*>/i;
const imageSrcPattern =
//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);
}
}