An in-browser wisp.place site explorer
1/**
2 * MIME type utilities
3 */
4
5/**
6 * Comprehensive MIME type mapping by file extension
7 */
8export const MIME_TYPES: Record<string, string> = {
9 // Text files
10 html: 'text/html',
11 htm: 'text/html',
12 css: 'text/css',
13 js: 'text/javascript',
14 mjs: 'text/javascript',
15 cjs: 'text/javascript',
16 json: 'application/json',
17 xml: 'application/xml',
18 txt: 'text/plain',
19 md: 'text/markdown',
20 csv: 'text/csv',
21 ts: 'text/typescript',
22
23 // Images
24 png: 'image/png',
25 jpg: 'image/jpeg',
26 jpeg: 'image/jpeg',
27 gif: 'image/gif',
28 webp: 'image/webp',
29 svg: 'image/svg+xml',
30 ico: 'image/x-icon',
31 bmp: 'image/bmp',
32 tiff: 'image/tiff',
33 tif: 'image/tiff',
34 avif: 'image/avif',
35
36 // Videos
37 mp4: 'video/mp4',
38 webm: 'video/webm',
39 ogv: 'video/ogg',
40 mov: 'video/quicktime',
41 avi: 'video/x-msvideo',
42 wmv: 'video/x-ms-wmv',
43 flv: 'video/x-flv',
44 mkv: 'video/x-matroska',
45 m4v: 'video/mp4',
46 mpeg: 'video/mpeg',
47 mpg: 'video/mpeg',
48
49 // Audio
50 mp3: 'audio/mpeg',
51 wav: 'audio/wav',
52 ogg: 'audio/ogg',
53 oga: 'audio/ogg',
54 flac: 'audio/flac',
55 aac: 'audio/aac',
56 m4a: 'audio/mp4',
57 wma: 'audio/x-ms-wma',
58 mid: 'audio/midi',
59 midi: 'audio/midi',
60
61 // Fonts
62 ttf: 'font/ttf',
63 otf: 'font/otf',
64 woff: 'font/woff',
65 woff2: 'font/woff2',
66 eot: 'application/vnd.ms-fontobject',
67
68 // Archives
69 zip: 'application/zip',
70 gz: 'application/gzip',
71 tar: 'application/x-tar',
72 rar: 'application/vnd.rar',
73 '7z': 'application/x-7z-compressed',
74 bz2: 'application/x-bzip2',
75
76 // Documents
77 pdf: 'application/pdf',
78 doc: 'application/msword',
79 docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
80 xls: 'application/vnd.ms-excel',
81 xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
82 ppt: 'application/vnd.ms-powerpoint',
83 pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
84 odt: 'application/vnd.oasis.opendocument.text',
85 ods: 'application/vnd.oasis.opendocument.spreadsheet',
86 odp: 'application/vnd.oasis.opendocument.presentation',
87 rtf: 'application/rtf',
88 epub: 'application/epub+zip',
89
90 // Web
91 wasm: 'application/wasm',
92 swf: 'application/x-shockwave-flash',
93 manifest: 'text/cache-manifest',
94 map: 'application/json',
95
96 // Other
97 bin: 'application/octet-stream',
98 exe: 'application/x-msdownload',
99 dll: 'application/x-msdownload',
100 so: 'application/octet-stream',
101 dmg: 'application/x-apple-diskimage',
102 iso: 'application/x-iso9660-image',
103 img: 'application/octet-stream',
104 apk: 'application/vnd.android.package-archive',
105};
106
107/**
108 * Get MIME type from file extension
109 */
110export function getMimeType(filename: string): string {
111 if (!filename) {
112 return 'application/octet-stream';
113 }
114
115 // Handle query strings in URLs
116 const cleanFilename = filename.split('?')[0].split('#')[0];
117 const ext = cleanFilename.split('.').pop()?.toLowerCase() || '';
118
119 return MIME_TYPES[ext] || 'application/octet-stream';
120}
121
122/**
123 * Check if a MIME type is text-based
124 */
125export function isTextMimeType(mimeType: string): boolean {
126 return (
127 mimeType.startsWith('text/') ||
128 mimeType === 'application/json' ||
129 mimeType === 'application/xml'
130 );
131}
132
133/**
134 * Check if a MIME type is an image
135 */
136export function isImageMimeType(mimeType: string): boolean {
137 return mimeType.startsWith('image/');
138}
139
140/**
141 * Check if a MIME type is a video
142 */
143export function isVideoMimeType(mimeType: string): boolean {
144 return mimeType.startsWith('video/');
145}
146
147/**
148 * Check if a MIME type is an audio
149 */
150export function isAudioMimeType(mimeType: string): boolean {
151 return mimeType.startsWith('audio/');
152}
153
154/**
155 * Get charset for text MIME types
156 */
157export function getCharset(mimeType: string): string {
158 if (isTextMimeType(mimeType)) {
159 return 'utf-8';
160 }
161 return '';
162}
163
164/**
165 * Get content type string with charset if applicable
166 */
167export function getContentType(mimeType: string): string {
168 const charset = getCharset(mimeType);
169 return charset ? `${mimeType}; charset=${charset}` : mimeType;
170}