91 lines
2.4 KiB
TypeScript
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 } : {}),
|
|
};
|
|
}
|