Bpistle/src/lib/url.ts
2025-02-06 22:52:44 +08:00

91 lines
2.6 KiB
TypeScript

export function isWebsocketUrl(url: string): boolean {
return /^wss?:\/\/.+$/.test(url)
}
// copy from nostr-tools/utils
export function normalizeUrl(url: string): string {
if (url.indexOf('://') === -1) url = 'wss://' + url
const p = new URL(url)
p.pathname = p.pathname.replace(/\/+/g, '/')
if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)
if ((p.port === '80' && p.protocol === 'ws:') || (p.port === '443' && p.protocol === 'wss:'))
p.port = ''
p.searchParams.sort()
p.hash = ''
return p.toString()
}
export function normalizeHttpUrl(url: string): string {
if (url.indexOf('://') === -1) url = 'https://' + url
const p = new URL(url)
p.pathname = p.pathname.replace(/\/+/g, '/')
if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1)
if ((p.port === '80' && p.protocol === 'http:') || (p.port === '443' && p.protocol === 'https:'))
p.port = ''
p.searchParams.sort()
p.hash = ''
return p.toString()
}
export function simplifyUrl(url: string): string {
return url.replace('wss://', '').replace('ws://', '').replace(/\/$/, '')
}
export function isLocalNetworkUrl(urlString: string): boolean {
try {
const url = new URL(urlString)
const hostname = url.hostname
// Check if it's localhost
if (hostname === 'localhost' || hostname === '::1') {
return true
}
// Check if it's an IPv4 local network address
const ipv4Match = hostname.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
if (ipv4Match) {
const [, a, b, c, d] = ipv4Match.map(Number)
return (
a === 10 ||
(a === 172 && b >= 16 && b <= 31) ||
(a === 192 && b === 168) ||
(a === 127 && b === 0 && c === 0 && d === 1)
)
}
// Check if it's an IPv6 address
if (hostname.includes(':')) {
if (hostname === '::1') {
return true // IPv6 loopback address
}
if (hostname.startsWith('fe80:')) {
return true // Link-local address
}
if (hostname.startsWith('fc') || hostname.startsWith('fd')) {
return true // Unique local address (ULA)
}
}
return false
} catch {
return false // Return false for invalid URLs
}
}
export function isImage(url: string) {
try {
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.heic', '.svg']
return imageExtensions.some((ext) => new URL(url).pathname.toLowerCase().endsWith(ext))
} catch {
return false
}
}
export function isVideo(url: string) {
try {
const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov']
return videoExtensions.some((ext) => new URL(url).pathname.toLowerCase().endsWith(ext))
} catch {
return false
}
}