UNPKG

social-link-parser

Version:

Extract usernames, IDs, and metadata from social media URLs across 100+ platforms

108 lines 4.01 kB
import { Platforms } from '../../core/types.js'; import { normalize } from '../../utils/url.js'; import { createDomainPattern } from '../../utils/url.js'; import { QUERY_HASH } from '../../utils/constants.js'; const domains = ['tiktok.com']; const subdomains = ['m', 'vm']; const DOMAIN_PATTERN = createDomainPattern(domains, subdomains); export const tiktok = { id: Platforms.TikTok, name: 'TikTok', color: '#000000', domains: domains, subdomains: subdomains, patterns: { profile: new RegExp(`^https?://${DOMAIN_PATTERN}/@([A-Za-z0-9._]{2,24})/?${QUERY_HASH}$`, 'i'), handle: /^@?[A-Za-z0-9._]{2,24}$/, content: { video: new RegExp(`^https?://${DOMAIN_PATTERN}/@([A-Za-z0-9._]{2,24})/video/(\\d{10,20})/?${QUERY_HASH}$`, 'i'), live: new RegExp(`^https?://${DOMAIN_PATTERN}/@([A-Za-z0-9._]{2,24})/live/?${QUERY_HASH}$`, 'i'), short: new RegExp(`^https?://vm\\.tiktok\\.com/([A-Za-z0-9]+)/?${QUERY_HASH}$`, 'i'), embed: new RegExp(`^https?://${DOMAIN_PATTERN}/embed/v2/(\\d{10,20})/?${QUERY_HASH}$`, 'i'), }, }, detect(url) { if (!this.domains.some(d => url.includes(d))) { return false; } if (this.patterns.profile.test(url)) return true; if (this.patterns.content) { for (const pattern of Object.values(this.patterns.content)) { if (pattern && pattern.test(url)) return true; } } return false; }, extract(url, result) { const embedMatch = this.patterns.content?.embed?.exec(url); if (embedMatch) { result.ids.videoId = embedMatch[1]; result.metadata.isEmbed = true; result.metadata.contentType = 'embed'; return; } const videoMatch = this.patterns.content?.video?.exec(url); if (videoMatch) { result.username = videoMatch[1]; result.ids.videoId = videoMatch[2]; result.metadata.isVideo = true; result.metadata.contentType = 'video'; return; } const liveMatch = this.patterns.content?.live?.exec(url); if (liveMatch) { result.username = liveMatch[1]; result.metadata.isLive = true; result.metadata.contentType = 'live'; return; } const shortMatch = this.patterns.content?.short?.exec(url); if (shortMatch) { result.ids.shortId = shortMatch[1]; result.metadata.isShort = true; result.metadata.contentType = 'short'; return; } const profileMatch = this.patterns.profile.exec(url); if (profileMatch) { result.username = profileMatch[1]; result.metadata.isProfile = true; result.metadata.contentType = 'profile'; } }, validateHandle(handle) { const cleaned = handle.replace('@', ''); return /^[A-Za-z0-9._]{2,24}$/.test(cleaned); }, buildProfileUrl(username) { const clean = username.replace('@', ''); return `https://tiktok.com/@${clean}`; }, buildContentUrl(contentType, id) { if (contentType === 'video') { return `https://tiktok.com/@placeholder/video/${id}`; } return `https://tiktok.com/v/${id}`; }, normalizeUrl(url) { url = url.replace(/[?&](lang|_d|utm_[^&]+)=[^&]+/g, ''); return normalize(url); }, async resolveShortUrl(shortUrl) { return shortUrl; }, getEmbedInfo(url, parsed) { if (/tiktok\.com\/embed\//.test(url)) { return { embedUrl: url, isEmbedAlready: true }; } const id = parsed.ids.videoId; if (id) { const embedUrl = `https://www.tiktok.com/embed/v2/${id}`; return { embedUrl, type: 'iframe' }; } return null; }, }; //# sourceMappingURL=index.js.map