nexstream-backend / backend /src /utils /network /validation.util.ts
nexstream-deploy
deploy: nexstream backend (experiment)
f3fa747
Raw
History Blame Contribute Delete
2.1 kB
import { URL } from 'node:url';
const SUPPORTED_DOMAINS: string[] = [
'youtube.com',
'youtu.be',
'spotify.com',
'open.spotify.com',
'facebook.com',
'fb.watch',
'instagram.com',
'threads.net',
'threads.com',
'tiktok.com',
'twitter.com',
'x.com',
'soundcloud.com',
'reddit.com',
'bsky.app',
];
export function isSupportedUrl(url: string | null | undefined): boolean {
if (!url) return false;
try {
const parsed = new URL(url);
return SUPPORTED_DOMAINS.some(
(domain) =>
parsed.hostname === domain || parsed.hostname.endsWith(`.${domain}`)
);
} catch {
return false;
}
}
export function isValidSpotifyUrl(url: string | null | undefined): boolean {
if (!url) return false;
try {
const parsed = new URL(url);
return (
parsed.hostname === 'open.spotify.com' ||
parsed.hostname === 'spotify.com'
);
} catch {
return false;
}
}
export function extractTrackId(url: string | null | undefined): string | null {
if (!url || !isValidSpotifyUrl(url)) return null;
const match = url.match(/\/track\/([a-zA-Z0-9]{22})/);
return match ? match[1] : null;
}
const PROXY_ALLOWED_DOMAINS: string[] = [
'googlevideo.com',
'youtube.com',
'youtu.be',
'spotifycdn.com',
'soundcharts.com',
'i.scdn.co',
'fbcdn.net',
'cdninstagram.com',
'facebook.com',
'fb.watch',
'instagram.com',
'akamaihd.net',
];
export function isValidProxyUrl(url: string | null | undefined): boolean {
if (!url) return false;
try {
const parsed = new URL(url);
return PROXY_ALLOWED_DOMAINS.some(
(domain) =>
parsed.hostname === domain || parsed.hostname.endsWith(`.${domain}`)
);
} catch {
return false;
}
}
export function decodeUrlIfNeeded(url: string): string {
if (url?.includes('%')) {
try {
const decoded = decodeURIComponent(url);
if (decoded.startsWith('http')) return decoded;
} catch (error: unknown) {
console.debug(
'[VideoController] URL decode error:',
(error as Error).message
);
}
}
return url;
}