File size: 1,347 Bytes
3050b83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Lightweight MIME helpers to avoid new dependencies.

const EXTENSION_TO_MIME: Record<string, string> = {
	png: "image/png",
	jpg: "image/jpeg",
	jpe: "image/jpeg",
	jpeg: "image/jpeg",
	gif: "image/gif",
	webp: "image/webp",
	svg: "image/svg+xml",
	pdf: "application/pdf",
	txt: "text/plain",
	csv: "text/csv",
	json: "application/json",
	mp3: "audio/mpeg",
	wav: "audio/wav",
	ogg: "audio/ogg",
	mp4: "video/mp4",
	mov: "video/quicktime",
	webm: "video/webm",
	zip: "application/zip",
	gz: "application/gzip",
	tgz: "application/gzip",
	tar: "application/x-tar",
	html: "text/html",
	htm: "text/html",
	md: "text/markdown",
};

export function guessMimeFromUrl(url: string): string | undefined {
	try {
		const pathname = new URL(url).pathname;
		const ext = pathname.split(".").pop()?.toLowerCase();
		if (ext && EXTENSION_TO_MIME[ext]) return EXTENSION_TO_MIME[ext];
	} catch {
		/* ignore */
	}
	return undefined;
}

export function pickSafeMime(
	forwardedType: string | null,
	blobType: string | undefined,
	url: string
): string {
	const inferred = guessMimeFromUrl(url);
	if (forwardedType) return forwardedType;
	if (
		inferred &&
		(!blobType || blobType === "application/octet-stream" || blobType.startsWith("text/plain"))
	) {
		return inferred;
	}
	if (blobType) return blobType;
	return inferred || "application/octet-stream";
}