import { z } from "zod"; export const videoDetails = { width: "1008", height: "567", minDim: "100", maxDim: "1008", }; /** * Extract YouTube video ID from a URL or a raw ID. */ export const extractYoutubeId = (input: string): string | null => { const trimmed = input.trim(); // Direct ID (11 chars) if (/^[a-zA-Z0-9_-]{11}$/.test(trimmed)) return trimmed; // youtube.com/watch?v=ID const watchMatch = trimmed.match(/[?&]v=([a-zA-Z0-9_-]{11})/); if (watchMatch) return watchMatch[1]; // youtu.be/ID const shortMatch = trimmed.match(/youtu\.be\/([a-zA-Z0-9_-]{11})/); if (shortMatch) return shortMatch[1]; // youtube.com/embed/ID const embedMatch = trimmed.match(/youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/); if (embedMatch) return embedMatch[1]; return null; }; /** * Extract Vimeo video ID from a URL or a raw ID. */ export const extractVimeoId = (input: string): string | null => { const trimmed = input.trim(); // Direct numeric ID if (/^\d+$/.test(trimmed)) return trimmed; // vimeo.com/ID or vimeo.com/video/ID const match = trimmed.match(/vimeo\.com\/(?:video\/)?(\d+)/); if (match) return match[1]; return null; }; /** * Build the iframe src URL for YouTube or Vimeo with options. */ export const buildVideoSrc = (attrs: { videoId?: string | null; isMuted?: boolean; hasControls?: boolean; provider: number; }): string => { const params = new URLSearchParams(); const query = params.toString(); if (attrs.provider == 1) { if (attrs.isMuted) params.set("mute", "1"); params.set("controls", attrs.hasControls ? "1" : "0"); return `https://www.youtube.com/embed/${attrs.videoId}${query ? `?${query}` : ""}`; } if (attrs.provider == 2) { if (attrs.isMuted) params.set("muted", "1"); if (!attrs.hasControls) params.set("controls", "0"); return `https://player.vimeo.com/video/${attrs.videoId}${query ? `?${query}` : ""}`; } return ""; }; /** * Zod schema for video caption input. */ export const videoTextSchema = ({ hasCaption, transValidationCaption, transValidationAlt, }: { hasCaption: boolean; transValidationCaption: { min: string; max: string; string: string, boolean: string }; transValidationAlt: { min: string; max: string; string: string; }; }) => { const altRules = z .string({ message: transValidationAlt.string }) .min(3, transValidationAlt.min) .max(255, transValidationAlt.max); const captionRules = z .string({ message: transValidationCaption.string }) .min(3, transValidationCaption.min) .max(255, transValidationCaption.max); const isBool = z.boolean({ message: transValidationCaption.boolean }); return z.object({ caption: hasCaption ? captionRules : z.null(), isMuted: isBool, hasControls: isBool, canFullScreen: isBool, alt: altRules }); }; export const isBoolsSchema = (transValidation: { isMuted: string; hasControls: string; canFullScreen: string }) => { const isMuted = z.boolean({ message: transValidation.isMuted }); const hasControls = z.boolean({ message: transValidation.hasControls }); const canFullScreen = z.boolean({ message: transValidation.canFullScreen }); return z.object({ isMuted: isMuted, hasControls: hasControls, canFullScreen: canFullScreen, }); };