🌳
pt0/sharedF/mimeExtF.mts
1// Bidirectional mime <-> extension mapping
2// Extensions without leading dot for flexibility
4export const mimeToExt: Record<string, string> = {
5 'image/jpeg': 'jpg',
6 'image/png': 'png',
7 'image/gif': 'gif',
8 'image/webp': 'webp',
9 'video/mp4': 'mp4',
10 'video/webm': 'webm',
11 'video/quicktime': 'mov',
12 'video/x-matroska': 'mkv',
13 'video/x-m4v': 'm4v',
14 'video/x-flv': 'flv',
15 'video/x-ms-asf': 'asf',
16 'audio/x-m4a': 'm4a',
17 'application/pdf': 'pdf',
18 'text/html': 'html',
19 'text/plain': 'txt',
20 'text/x-diff': 'diff',
21 'application/x-patch': 'patch',
24// Mimes that exist but shouldn't get extensions (can't stream, etc)
25export const mimeNoExt = new Set(['video/x-msvideo', 'application/octet-stream'])
27export const extToMime: Record<string, string> = Object.fromEntries(
28 Object.entries(mimeToExt).map(([m, e]) => [e, m])
31// Returns ext without dot, null if unknown, '' if known-but-no-ext
32export const getExtFromMime = (mime: string): string | null => {
33 const cleaned = mime.replace('; charset=binary', '')
34 if (mimeNoExt.has(cleaned)) return ''
35 return mimeToExt[cleaned] ?? null
38export const getMimeFromExt = (ext: string): string | null =>
39 extToMime[ext.replace(/^\./, '')] ?? null