export type VideoCanvasStoryboardReferenceRequest = { activation?: "locate" | "preview"; contentType?: string; mediaType?: "audio" | "image" | "text" | "video"; mediaUrl?: string; nodeId: string; requestId: string; textContent?: string; title: string; previewUrl?: string; }; export function normalizeVideoCanvasStoryboardReference( value: VideoCanvasStoryboardReferenceRequest, ): VideoCanvasStoryboardReferenceRequest | null { const mediaUrl = String(value.mediaUrl || "").trim(); const nodeId = String(value.nodeId || "").trim(); const requestId = String(value.requestId || "").trim(); const textContent = String(value.textContent || "").trim(); const title = String(value.title || "").trim(); const previewUrl = String(value.previewUrl || "").trim(); if (!(nodeId && requestId && title)) return null; const isTextReference = value.mediaType === "text" || String(value.contentType || "").trim().toLowerCase().startsWith("text/"); if (isTextReference) { if (!textContent) return null; return { activation: "locate", contentType: "text/plain", mediaType: "text", mediaUrl: "", nodeId, requestId, textContent, title, }; } const activation = value.activation === "locate" || value.mediaType === "audio" || value.mediaType === "video" || String(value.contentType || "").trim().toLowerCase().startsWith("audio/") ? "locate" : "preview"; const isVideoReference = value.mediaType === "video" || String(value.contentType || "").trim().toLowerCase().startsWith("video/"); if ( !mediaUrl && !(activation === "locate" && (textContent || isVideoReference)) ) { return null; } for (const candidateUrl of [mediaUrl, previewUrl].filter(Boolean)) { try { const parsedUrl = new URL(candidateUrl); if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") { return null; } } catch { return null; } } const contentType = String( value.contentType || (isVideoReference ? "video/mp4" : "image/jpeg"), ).trim(); const mediaType = isVideoReference ? "video" : value.mediaType === "audio" || contentType.startsWith("audio/") ? "audio" : "image"; return { activation, contentType, mediaType, mediaUrl, nodeId, requestId, ...(textContent ? { textContent } : {}), title, ...(previewUrl ? { previewUrl } : {}), }; }