77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import {
|
|
ATTACHMENT_TAG_RE,
|
|
extractHtmlFromAttachment,
|
|
extractInlineImageCandidates,
|
|
IMG_SRC_RE,
|
|
isLikelyImageAttachment,
|
|
safeHostForUrl,
|
|
} from "./shared.js";
|
|
import type { MSTeamsAttachmentLike, MSTeamsHtmlAttachmentSummary } from "./types.js";
|
|
|
|
export function summarizeMSTeamsHtmlAttachments(
|
|
attachments: MSTeamsAttachmentLike[] | undefined,
|
|
): MSTeamsHtmlAttachmentSummary | undefined {
|
|
const list = Array.isArray(attachments) ? attachments : [];
|
|
if (list.length === 0) return undefined;
|
|
let htmlAttachments = 0;
|
|
let imgTags = 0;
|
|
let dataImages = 0;
|
|
let cidImages = 0;
|
|
const srcHosts = new Set<string>();
|
|
let attachmentTags = 0;
|
|
const attachmentIds = new Set<string>();
|
|
|
|
for (const att of list) {
|
|
const html = extractHtmlFromAttachment(att);
|
|
if (!html) continue;
|
|
htmlAttachments += 1;
|
|
IMG_SRC_RE.lastIndex = 0;
|
|
let match: RegExpExecArray | null = IMG_SRC_RE.exec(html);
|
|
while (match) {
|
|
imgTags += 1;
|
|
const src = match[1]?.trim();
|
|
if (src) {
|
|
if (src.startsWith("data:")) dataImages += 1;
|
|
else if (src.startsWith("cid:")) cidImages += 1;
|
|
else srcHosts.add(safeHostForUrl(src));
|
|
}
|
|
match = IMG_SRC_RE.exec(html);
|
|
}
|
|
|
|
ATTACHMENT_TAG_RE.lastIndex = 0;
|
|
let attachmentMatch: RegExpExecArray | null = ATTACHMENT_TAG_RE.exec(html);
|
|
while (attachmentMatch) {
|
|
attachmentTags += 1;
|
|
const id = attachmentMatch[1]?.trim();
|
|
if (id) attachmentIds.add(id);
|
|
attachmentMatch = ATTACHMENT_TAG_RE.exec(html);
|
|
}
|
|
}
|
|
|
|
if (htmlAttachments === 0) return undefined;
|
|
return {
|
|
htmlAttachments,
|
|
imgTags,
|
|
dataImages,
|
|
cidImages,
|
|
srcHosts: Array.from(srcHosts).slice(0, 5),
|
|
attachmentTags,
|
|
attachmentIds: Array.from(attachmentIds).slice(0, 5),
|
|
};
|
|
}
|
|
|
|
export function buildMSTeamsAttachmentPlaceholder(
|
|
attachments: MSTeamsAttachmentLike[] | undefined,
|
|
): string {
|
|
const list = Array.isArray(attachments) ? attachments : [];
|
|
if (list.length === 0) return "";
|
|
const imageCount = list.filter(isLikelyImageAttachment).length;
|
|
const inlineCount = extractInlineImageCandidates(list).length;
|
|
const totalImages = imageCount + inlineCount;
|
|
if (totalImages > 0) {
|
|
return `<media:image>${totalImages > 1 ? ` (${totalImages} images)` : ""}`;
|
|
}
|
|
const count = list.length;
|
|
return `<media:document>${count > 1 ? ` (${count} files)` : ""}`;
|
|
}
|