Tldraw/packages/editor/src/lib/utils/embeds.ts

90 wiersze
2.0 KiB
TypeScript

import { EMBED_DEFINITIONS, EmbedDefinition } from '@tldraw/tlschema'
import escapeStringRegexp from 'escape-string-regexp'
/** @public */
export function matchEmbedUrl(url: string) {
const host = new URL(url).host.replace('www.', '')
for (const localEmbedDef of EMBED_DEFINITIONS) {
if (checkHostnames(localEmbedDef.hostnames, host)) {
const originalUrl = localEmbedDef.fromEmbedUrl(url)
if (originalUrl) {
return {
definition: localEmbedDef,
url: originalUrl,
embedUrl: url,
}
}
}
}
}
const globlikeRegExp = (input: string) => {
return input
.split('*')
.map((str) => escapeStringRegexp(str))
.join('.+')
}
const checkHostnames = (hostnames: readonly string[], targetHostname: string) => {
return !!hostnames.find((hostname) => {
const re = new RegExp(globlikeRegExp(hostname))
return targetHostname.match(re)
})
}
/** @public */
export function matchUrl(url: string) {
const host = new URL(url).host.replace('www.', '')
for (const localEmbedDef of EMBED_DEFINITIONS) {
if (checkHostnames(localEmbedDef.hostnames, host)) {
const embedUrl = localEmbedDef.toEmbedUrl(url)
if (embedUrl) {
return {
definition: localEmbedDef,
embedUrl,
url,
}
}
}
}
}
/** @public */
export type EmbedResult =
| {
definition: EmbedDefinition
url: string
embedUrl: string
}
| undefined
/**
* Tests whether an URL supports embedding and returns the result.
*
* @param inputUrl - The URL to match
* @public
*/
export function getEmbedInfoUnsafely(inputUrl: string): EmbedResult {
const result = matchUrl(inputUrl) ?? matchEmbedUrl(inputUrl)
return result
}
/**
* Tests whether an URL supports embedding and returns the result. If we encounter an error, we
* return undefined.
*
* @param inputUrl - The URL to match
* @public
*/
export function getEmbedInfo(inputUrl: string): EmbedResult {
try {
return getEmbedInfoUnsafely(inputUrl)
} catch (e) {
// Don't throw here! We'll throw it from the embed shape's shape util
console.error(e)
}
return undefined
}