export type EmbedSource = { name: string; url: string; regex: RegExp; }; const sources: EmbedSource[] = [ { name: 'youtube', url: 'https://www.youtube-nocookie.com/embed/{id}', regex: /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:shorts\/|[^/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)(?[a-zA-Z0-9_-]{11})/, }, { name: 'instagram_post', url: 'https://www.instagram.com/p/{id}', regex: /https?:\/\/(?:www\.)?instagram\.com\/p\/(?[^/?#&]+)/, }, { name: 'instagram_story', url: 'https://www.instagram.com/stories/highlights/{id}', regex: /https?:\/\/(?:www\.)?instagram\.com\/stories\/highlights\/(?[^/?#&]+)/, }, { name: 'twitter', url: 'https://twitter.com/i/status/{id}', regex: /https?:\/\/(?:www\.)?(twitter\.com|x\.com)\/.+?\/status\/(?[^/?#&]+)/, }, { name: 'facebook', url: 'https://www.facebook.com/plugins/post.php?href={id}', regex: /https?:\/\/(?:www\.)?facebook\.com\/(?:[^/?#&]+)\/posts\/(?[^/?#&]+)/, }, { name: 'tiktok', url: 'https://www.tiktok.com/embed/{id}', regex: /https?:\/\/(?:www\.)?tiktok\.com\/(?:[^/?#&]+)\/video\/(?[^/?#&]+)/, }, { name: 'vimeo', url: 'https://player.vimeo.com/video/{id}', regex: /https?:\/\/(?:www\.)?vimeo\.com(?:\/[^/?#&]+)?\/(?[^/?#&]+)/, }, { name: 'spotify', url: 'https://open.spotify.com/embed/{id}', regex: /https?:\/\/(?:open\.)?spotify\.com\/(?:[^/?#&]+)\/(?[^/?#&]+)/, }, { name: 'twitch_vod', url: 'https://player.twitch.tv/?parent={origin}&video={id}', regex: /https?:\/\/(?:www\.)?twitch\.tv\/(?:[^/?#&]+)\/(?[^/?#&]+)/, }, { name: 'twitch_clip', url: 'https://clips.twitch.tv/embed?parent={origin}&clip={id}', regex: /https?:\/\/(?:www\.)?twitch\.tv\/(?:[^/?#&]+)\/clip\/(?[^/?#&]+)/, }, { name: 'twitch_channel', url: 'https://player.twitch.tv/?parent={origin}&channel={id}', regex: /https?:\/\/(?:www\.)?twitch\.tv\/(?[^/?#&]+)/, }, { name: 'dailymotion', url: 'https://www.dailymotion.com/embed/video/{id}', regex: /^.+dailymotion.com\/(video|hub)\/(?[^_]+)[^#]*(#video=([^_&]+))?/, }, { name: 'bilibili', url: 'https://player.bilibili.com/player.html?aid=12569853&bvid={id}&cid=20681553&p=1&high_quality=1', regex: /^https?:\/\/(?:www\.)?bilibili\.com\/video\/(?BV[0-9A-Za-z]+)\/?/i, }, { name: 'googledrive', url: 'https://drive.google.com/file/d/{id}/preview', regex: /https?:\/\/(?:www\.)?drive\.google\.com\/file\/d\/(?[^/?#&]+)/, }, { name: 'fbc_sites', url: '{domain}/e/{id}', regex: /(?(.+?))\/(?:api\/tokens|f)\/(?fbc_[A-Za-z0-9_-]{22})\/?/, }, ]; const isEmbedable = (url: string): boolean => sources.some((source) => source.regex.test(url)); const getEmbedable = (url: string): string | null => { for (const source of sources) { const match = source.regex.exec(url); if (!match?.groups) { continue; } const replacements: Record = { ...match.groups, origin: window.location.origin, }; return source.url.replace(/\{(\w+)\}/g, (_, key) => replacements[key] ?? `{${key}}`); } return null; }; export { isEmbedable, getEmbedable };