82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import type { Attachment } from "@/lib/types";
|
|
|
|
type MessageImageSource = {
|
|
parts?: unknown[] | null;
|
|
attachments?: unknown[] | null;
|
|
};
|
|
|
|
function normalizeImageContentType(value: unknown) {
|
|
const contentType = String(value || "").trim().toLowerCase();
|
|
return contentType.startsWith("image/") ? contentType : "image/jpeg";
|
|
}
|
|
|
|
export function getMessageImagePartUrl(part: unknown) {
|
|
const value = part as Record<string, any> | null;
|
|
if (!value) return "";
|
|
|
|
const imageUrl = value.image_url;
|
|
const candidate =
|
|
value.type === "image_url"
|
|
? typeof imageUrl === "string"
|
|
? imageUrl
|
|
: imageUrl?.url || value.url
|
|
: value.type === "image" || value.type === "input_image"
|
|
? value.image || value.url || value.data
|
|
: value.type === "file"
|
|
? value.url || value.data
|
|
: "";
|
|
|
|
return typeof candidate === "string" ? candidate.trim() : "";
|
|
}
|
|
|
|
export function collectMessageImageAttachments(
|
|
message: MessageImageSource | null | undefined
|
|
): Attachment[] {
|
|
if (!message) return [];
|
|
|
|
const result: Attachment[] = [];
|
|
const seen = new Set<string>();
|
|
const append = (value: unknown, fallbackIndex: number, fromPart: boolean) => {
|
|
const item = value as Record<string, any> | null;
|
|
if (!item) return;
|
|
|
|
const url = fromPart
|
|
? getMessageImagePartUrl(item)
|
|
: typeof item.url === "string"
|
|
? item.url.trim()
|
|
: "";
|
|
if (!url || seen.has(url)) return;
|
|
|
|
const explicitContentType = String(
|
|
item.contentType || item.mediaType || item.mimeType || ""
|
|
).trim();
|
|
if (explicitContentType && !explicitContentType.startsWith("image/")) {
|
|
return;
|
|
}
|
|
|
|
seen.add(url);
|
|
result.push({
|
|
name: String(item.name || item.filename || item.alt || `图片${fallbackIndex + 1}`),
|
|
url,
|
|
contentType: normalizeImageContentType(explicitContentType),
|
|
assetId:
|
|
typeof item.assetId === "string" && item.assetId.trim()
|
|
? item.assetId.trim()
|
|
: undefined,
|
|
width: Number.isFinite(Number(item.width)) ? Number(item.width) : undefined,
|
|
height: Number.isFinite(Number(item.height)) ? Number(item.height) : undefined,
|
|
});
|
|
};
|
|
|
|
(Array.isArray(message.parts) ? message.parts : []).forEach((part, index) => {
|
|
append(part, index, true);
|
|
});
|
|
(Array.isArray(message.attachments) ? message.attachments : []).forEach(
|
|
(attachment, index) => {
|
|
append(attachment, result.length + index, false);
|
|
}
|
|
);
|
|
|
|
return result;
|
|
}
|