ai-chatbot/lib/video-canvas/storyboard-reference.ts

91 lines
2.4 KiB
TypeScript

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 } : {}),
};
}