/** * Affiliate URL validation utilities for marketplace links * Ensures affiliate tracking IDs are properly formatted */ export interface ValidationResult { isValid: boolean; error?: string; } /** * Validate Amazon Associate tag format * Expected format: tag=XXXX-20 */ export function validateAmazonAffiliateUrl(url: string): ValidationResult { try { const urlObj = new URL(url); // Check if it's an Amazon domain if (!urlObj.hostname.includes('amazon.com')) { return { isValid: false, error: 'Not an Amazon URL' }; } // Check for tag parameter const tag = urlObj.searchParams.get('tag'); if (!tag) { return { isValid: false, error: 'Missing affiliate tag parameter' }; } // Validate tag format (should end with -20) if (!tag.endsWith('-20')) { return { isValid: false, error: 'Invalid Amazon tag format (must end with -20)' }; } return { isValid: true }; } catch { return { isValid: false, error: 'Invalid URL format' }; } } /** * Validate eBay Partner Network campaign ID * Expected format: rover.ebay.com with campid parameter */ export function validateEbayAffiliateUrl(url: string): ValidationResult { try { const urlObj = new URL(url); // Check if it's an eBay rover URL if (!urlObj.hostname.includes('rover.ebay.com')) { return { isValid: false, error: 'Not an eBay Partner Network URL' }; } // Check for campid parameter const campid = urlObj.searchParams.get('campid'); if (!campid) { return { isValid: false, error: 'Missing campaign ID parameter' }; } // Validate campid is numeric if (!/^\d+$/.test(campid)) { return { isValid: false, error: 'Invalid campaign ID format' }; } return { isValid: true }; } catch { return { isValid: false, error: 'Invalid URL format' }; } } /** * Validate Etsy affiliate parameters * Expected format: etsy.com with ref parameter */ export function validateEtsyAffiliateUrl(url: string): ValidationResult { try { const urlObj = new URL(url); // Check if it's an Etsy domain if (!urlObj.hostname.includes('etsy.com')) { return { isValid: false, error: 'Not an Etsy URL' }; } // Check for ref parameter const ref = urlObj.searchParams.get('ref'); if (!ref) { return { isValid: false, error: 'Missing affiliate ref parameter' }; } return { isValid: true }; } catch { return { isValid: false, error: 'Invalid URL format' }; } } /** * Validate affiliate URL based on marketplace type */ export function validateAffiliateUrl( url: string, marketplace: 'amazon' | 'ebay' | 'etsy' ): ValidationResult { switch (marketplace) { case 'amazon': return validateAmazonAffiliateUrl(url); case 'ebay': return validateEbayAffiliateUrl(url); case 'etsy': return validateEtsyAffiliateUrl(url); default: return { isValid: false, error: 'Unknown marketplace type' }; } }