You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

61 lines
1.7 KiB

import { POST_MEDIA_PUBLIC_PREFIX } from "#server/constants/media";
const MD_IMG_RE = /!\[[^\]]*]\(([^)]+)\)/g;
function normalizeUrl(raw: string): string {
const t = raw.trim().replace(/^<|>$/g, "").split(/\s+/)[0] ?? "";
if (t.startsWith(POST_MEDIA_PUBLIC_PREFIX)) {
return t;
}
return "";
}
/** 从 markdown 中提取本站图片 URL(去重,顺序稳定) */
export function extractMediaUrlsFromMarkdown(markdown: string): string[] {
const out: string[] = [];
const seen = new Set<string>();
let m: RegExpExecArray | null;
const re = new RegExp(MD_IMG_RE.source, MD_IMG_RE.flags);
while ((m = re.exec(markdown)) !== null) {
const u = normalizeUrl(m[1] ?? "");
if (u && !seen.has(u)) {
seen.add(u);
out.push(u);
}
}
return out;
}
export function extractMediaUrlsFromCover(coverUrl: string | null | undefined): string[] {
if (!coverUrl) {
return [];
}
const u = normalizeUrl(coverUrl);
return u ? [u] : [];
}
export function mergePostMediaUrls(bodyMarkdown: string, coverUrl: string | null | undefined): string[] {
const a = extractMediaUrlsFromMarkdown(bodyMarkdown);
const b = extractMediaUrlsFromCover(coverUrl);
const seen = new Set<string>(a);
for (const u of b) {
if (!seen.has(u)) {
seen.add(u);
a.push(u);
}
}
return a;
}
/** `/public/assets/foo.webp` → `foo.webp` */
export function publicAssetUrlToStorageKey(url: string): string | null {
const t = url.trim();
if (!t.startsWith(POST_MEDIA_PUBLIC_PREFIX)) {
return null;
}
const key = t.slice(POST_MEDIA_PUBLIC_PREFIX.length).replace(/^\/+/, "");
if (!key || key.includes("..") || key.includes("/") || key.includes("\\")) {
return null;
}
return key;
}