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
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;
|
|
}
|
|
|