personal web client for Bluesky
typescript solidjs bluesky atcute
at trunk 1.7 kB view raw
1const _parse = URL.parse; 2 3// Check for the existence of URL.parse and use that if available, removes the 4// performance hit from try..catch blocks. 5export const safeUrlParse = _parse 6 ? (text: string): URL | null => { 7 const url = _parse(text); 8 9 if (url !== null && (url.protocol === 'https:' || url.protocol === 'http:')) { 10 return url; 11 } 12 13 return null; 14 } 15 : (text: string): URL | null => { 16 try { 17 const url = new URL(text); 18 19 if (url.protocol === 'https:' || url.protocol === 'http:') { 20 return url; 21 } 22 } catch {} 23 24 return null; 25 }; 26 27const TRIM_HOST_RE = /^www\./; 28const TRIM_URLTEXT_RE = /^\s*(https?:\/\/)?(?:www\.)?/; 29 30export const isLinkValid = (uri: string, text: string) => { 31 const url = safeUrlParse(uri); 32 33 if (url === null) { 34 return false; 35 } 36 37 const expectedHost = buildHostPart(url); 38 const length = expectedHost.length; 39 40 const normalized = text.replace(TRIM_URLTEXT_RE, '').toLowerCase(); 41 const normalizedLength = normalized.length; 42 43 const boundary = normalizedLength >= length ? normalized[length] : undefined; 44 45 return ( 46 (boundary === undefined || boundary === '/' || boundary === '?' || boundary === '#') && 47 normalized.startsWith(expectedHost) 48 ); 49}; 50 51const buildHostPart = (url: URL) => { 52 const username = url.username; 53 // const password = url.password; 54 55 const hostname = url.hostname.replace(TRIM_HOST_RE, '').toLowerCase(); 56 const port = url.port; 57 58 // Perhaps might be best if we always warn on authentication being passed. 59 // const auth = username ? username + (password ? ':' + password : '') + '@' : ''; 60 const auth = username ? '\0@@\0' : ''; 61 62 const host = hostname + (port ? ':' + port : ''); 63 64 return auth + host; 65};