UNPKG

@xbibzlibrary/tiktokscrap

Version:

Powerful TikTok Scraper and Downloader Library

146 lines (114 loc) 5.67 kB
import { ValidationError } from '../errors'; import { TikTokSearchOptions, TikTokUserFeedOptions, TikTokHashtagFeedOptions, TikTokDownloadOptions } from '../types'; import Logger from './logger'; export class Validator { private logger = Logger; public validateUrl(url: string): boolean { try { const urlObj = new URL(url); return urlObj.protocol === 'http:' || urlObj.protocol === 'https:'; } catch (error) { return false; } } public validateTikTokUrl(url: string): boolean { if (!this.validateUrl(url)) { return false; } const tiktokRegex = /^https?:\/\/(www\.)?tiktok\.com\/(@[\w.-]+)\/(video|photo)\/([\d]+)(\?.*)?$/; return tiktokRegex.test(url); } public validateTikTokUsername(username: string): boolean { const usernameRegex = /^@[\w.-]+$/; return usernameRegex.test(username); } public validateTikTokHashtag(hashtag: string): boolean { const hashtagRegex = /^#?[\w]+$/; return hashtagRegex.test(hashtag); } public validateSearchOptions(options: TikTokSearchOptions): void { if (!options || typeof options !== 'object') { throw new ValidationError('Search options must be an object'); } if (!options.keyword || typeof options.keyword !== 'string' || options.keyword.trim() === '') { throw new ValidationError('Keyword is required and must be a non-empty string'); } if (options.cursor !== undefined && (typeof options.cursor !== 'number' || options.cursor < 0)) { throw new ValidationError('Cursor must be a non-negative number'); } if (options.count !== undefined && (typeof options.count !== 'number' || options.count <= 0 || options.count > 100)) { throw new ValidationError('Count must be a positive number not exceeding 100'); } if (options.sortType !== undefined && ![0, 1, 2].includes(options.sortType)) { throw new ValidationError('Sort type must be 0 (Relevant), 1 (Latest), or 2 (Most liked)'); } if (options.publishTime !== undefined && ![0, 1, 2, 3].includes(options.publishTime)) { throw new ValidationError('Publish time must be 0 (All time), 1 (Within 1 day), 2 (Within 7 days), or 3 (Within 30 days)'); } if (options.duration !== undefined && ![0, 1, 2].includes(options.duration)) { throw new ValidationError('Duration must be 0 (All), 1 (Under 15s), or 2 (Over 15s)'); } } public validateUserFeedOptions(options: TikTokUserFeedOptions): void { if (!options || typeof options !== 'object') { throw new ValidationError('User feed options must be an object'); } if (!options.username || typeof options.username !== 'string' || options.username.trim() === '') { throw new ValidationError('Username is required and must be a non-empty string'); } if (!this.validateTikTokUsername(options.username)) { throw new ValidationError('Invalid TikTok username format'); } if (options.cursor !== undefined && (typeof options.cursor !== 'number' || options.cursor < 0)) { throw new ValidationError('Cursor must be a non-negative number'); } if (options.count !== undefined && (typeof options.count !== 'number' || options.count <= 0 || options.count > 100)) { throw new ValidationError('Count must be a positive number not exceeding 100'); } if (options.type !== undefined && !['post', 'like'].includes(options.type)) { throw new ValidationError('Type must be either "post" or "like"'); } } public validateHashtagFeedOptions(options: TikTokHashtagFeedOptions): void { if (!options || typeof options !== 'object') { throw new ValidationError('Hashtag feed options must be an object'); } if (!options.hashtag || typeof options.hashtag !== 'string' || options.hashtag.trim() === '') { throw new ValidationError('Hashtag is required and must be a non-empty string'); } if (!this.validateTikTokHashtag(options.hashtag)) { throw new ValidationError('Invalid TikTok hashtag format'); } if (options.cursor !== undefined && (typeof options.cursor !== 'number' || options.cursor < 0)) { throw new ValidationError('Cursor must be a non-negative number'); } if (options.count !== undefined && (typeof options.count !== 'number' || options.count <= 0 || options.count > 100)) { throw new ValidationError('Count must be a positive number not exceeding 100'); } } public validateDownloadOptions(options: TikTokDownloadOptions): void { if (!options || typeof options !== 'object') { throw new ValidationError('Download options must be an object'); } if (options.outputDir !== undefined && (typeof options.outputDir !== 'string' || options.outputDir.trim() === '')) { throw new ValidationError('Output directory must be a non-empty string'); } if (options.filename !== undefined && (typeof options.filename !== 'string' || options.filename.trim() === '')) { throw new ValidationError('Filename must be a non-empty string'); } if (options.progressCallback !== undefined && typeof options.progressCallback !== 'function') { throw new ValidationError('Progress callback must be a function'); } } public validateId(id: string): void { if (!id || typeof id !== 'string' || id.trim() === '') { throw new ValidationError('ID is required and must be a non-empty string'); } } public validateSecUid(secUid: string): void { if (!secUid || typeof secUid !== 'string' || secUid.trim() === '') { throw new ValidationError('SecUid is required and must be a non-empty string'); } } } export default Validator;