@freightos/freightwind 2.1.2 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +28 -28
- package/dist/cjs/components/chip.js +1 -1
- package/dist/cjs/components/upload.js +321 -0
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/lib/file-extensions.js +678 -0
- package/dist/cjs/lib/use-stable-id.js +2 -3
- package/dist/esm/components/chip.js +1 -1
- package/dist/esm/components/upload.js +318 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/lib/file-extensions.js +671 -0
- package/dist/esm/lib/use-stable-id.js +2 -3
- package/dist/types/components/chip.d.ts +1 -1
- package/dist/types/components/upload.d.ts +66 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lib/file-extensions.d.ts +52 -0
- package/guidelines/Guidelines.md +233 -233
- package/guidelines/design-tokens/colors.md +81 -81
- package/guidelines/design-tokens/spacing.md +45 -45
- package/guidelines/design-tokens/typography.md +87 -87
- package/guidelines/overview-components.md +252 -252
- package/guidelines/overview-icons.md +52 -52
- package/package.json +104 -102
- package/tokens.css +419 -419
|
@@ -0,0 +1,671 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MIME-type → extensions map sourced from the IANA / Apache / Nginx MIME database
|
|
3
|
+
* (https://github.com/jshttp/mime-db). Keys are canonical MIME types
|
|
4
|
+
* (e.g. `image/aces`); values are the extensions that legitimately produce that
|
|
5
|
+
* type, without a leading dot and in lowercase.
|
|
6
|
+
*
|
|
7
|
+
* Used to validate uploaded files: reject when the browser-reported `File.type`
|
|
8
|
+
* is unknown, **and** cross-check that the filename's extension matches the set
|
|
9
|
+
* registered for that type. This catches "extension spoofing" — e.g. a `.exe`
|
|
10
|
+
* renamed to `.jpg` will report `application/x-msdownload` (or empty), which
|
|
11
|
+
* does not list `jpg`, so it fails validation.
|
|
12
|
+
*/
|
|
13
|
+
export const VALID_MIME_TYPES = {
|
|
14
|
+
// ── Documents ──────────────────────────────────────────────────────────────
|
|
15
|
+
'application/pdf': ['pdf'],
|
|
16
|
+
'application/msword': ['doc', 'dot'],
|
|
17
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['docx'],
|
|
18
|
+
'application/vnd.ms-word.document.macroenabled.12': ['docm'],
|
|
19
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.template': ['dotx'],
|
|
20
|
+
'application/vnd.ms-word.template.macroenabled.12': ['dotm'],
|
|
21
|
+
'application/vnd.oasis.opendocument.text': ['odt'],
|
|
22
|
+
'application/vnd.oasis.opendocument.text-template': ['ott'],
|
|
23
|
+
'application/vnd.oasis.opendocument.text-master': ['odm'],
|
|
24
|
+
'application/vnd.oasis.opendocument.text-web': ['oth'],
|
|
25
|
+
'application/rtf': ['rtf'],
|
|
26
|
+
'text/rtf': ['rtf'],
|
|
27
|
+
'text/plain': ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'],
|
|
28
|
+
'text/markdown': ['md', 'markdown'],
|
|
29
|
+
'text/x-markdown': ['mkd'],
|
|
30
|
+
'text/mdx': ['mdx'],
|
|
31
|
+
'application/x-tex': ['tex'],
|
|
32
|
+
'application/x-texinfo': ['texinfo', 'texi'],
|
|
33
|
+
'application/vnd.wordperfect': ['wpd'],
|
|
34
|
+
'application/vnd.ms-works': ['wps', 'wks', 'wcm', 'wdb'],
|
|
35
|
+
'application/vnd.apple.pages': ['pages'],
|
|
36
|
+
'application/x-iwork-pages-sffpages': ['pages'],
|
|
37
|
+
'application/vnd.google-apps.document': ['gdoc'],
|
|
38
|
+
'application/fdf': ['fdf'],
|
|
39
|
+
'application/vnd.fdf': ['fdf'],
|
|
40
|
+
'application/xfdf': ['xfdf'],
|
|
41
|
+
'application/vnd.adobe.xfdf': ['xfdf'],
|
|
42
|
+
'application/epub+zip': ['epub'],
|
|
43
|
+
'application/x-mobipocket-ebook': ['mobi', 'prc'],
|
|
44
|
+
'application/vnd.amazon.ebook': ['azw'],
|
|
45
|
+
'application/x-abiword': ['abw'],
|
|
46
|
+
'application/x-gnumeric': ['gnumeric'],
|
|
47
|
+
'text/richtext': ['rtx'],
|
|
48
|
+
'text/sgml': ['sgml', 'sgm'],
|
|
49
|
+
'text/troff': ['t', 'tr', 'roff', 'man', 'me', 'ms'],
|
|
50
|
+
'application/vnd.software602.filler.form+xml': ['fo'],
|
|
51
|
+
'text/shex': ['shex'],
|
|
52
|
+
'text/spdx': ['spdx'],
|
|
53
|
+
'text/turtle': ['ttl'],
|
|
54
|
+
'text/n3': ['n3'],
|
|
55
|
+
'text/vnd.sun.j2me.app-descriptor': ['jad'],
|
|
56
|
+
'text/x-org': ['org'],
|
|
57
|
+
// ── Spreadsheets ───────────────────────────────────────────────────────────
|
|
58
|
+
'application/vnd.ms-excel': ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw'],
|
|
59
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['xlsx'],
|
|
60
|
+
'application/vnd.ms-excel.sheet.macroenabled.12': ['xlsm'],
|
|
61
|
+
'application/vnd.ms-excel.sheet.binary.macroenabled.12': ['xlsb'],
|
|
62
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.template': ['xltx'],
|
|
63
|
+
'application/vnd.ms-excel.template.macroenabled.12': ['xltm'],
|
|
64
|
+
'application/vnd.ms-excel.addin.macroenabled.12': ['xlam'],
|
|
65
|
+
'application/vnd.oasis.opendocument.spreadsheet': ['ods'],
|
|
66
|
+
'application/vnd.oasis.opendocument.spreadsheet-template': ['ots'],
|
|
67
|
+
'text/csv': ['csv'],
|
|
68
|
+
'text/tab-separated-values': ['tsv'],
|
|
69
|
+
'application/vnd.apple.numbers': ['numbers'],
|
|
70
|
+
'application/x-iwork-numbers-sffnumbers': ['numbers'],
|
|
71
|
+
'application/vnd.google-apps.spreadsheet': ['gsheet'],
|
|
72
|
+
// ── Presentations ──────────────────────────────────────────────────────────
|
|
73
|
+
'application/vnd.ms-powerpoint': ['ppt', 'pps', 'pot'],
|
|
74
|
+
'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['pptx'],
|
|
75
|
+
'application/vnd.ms-powerpoint.presentation.macroenabled.12': ['pptm'],
|
|
76
|
+
'application/vnd.openxmlformats-officedocument.presentationml.slideshow': ['ppsx'],
|
|
77
|
+
'application/vnd.ms-powerpoint.slideshow.macroenabled.12': ['ppsm'],
|
|
78
|
+
'application/vnd.openxmlformats-officedocument.presentationml.template': ['potx'],
|
|
79
|
+
'application/vnd.ms-powerpoint.template.macroenabled.12': ['potm'],
|
|
80
|
+
'application/vnd.ms-powerpoint.addin.macroenabled.12': ['ppam'],
|
|
81
|
+
'application/vnd.openxmlformats-officedocument.presentationml.slide': ['sldx'],
|
|
82
|
+
'application/vnd.ms-powerpoint.slide.macroenabled.12': ['sldm'],
|
|
83
|
+
'application/vnd.oasis.opendocument.presentation': ['odp'],
|
|
84
|
+
'application/vnd.oasis.opendocument.presentation-template': ['otp'],
|
|
85
|
+
'application/vnd.apple.keynote': ['key'],
|
|
86
|
+
'application/x-iwork-keynote-sffkey': ['key'],
|
|
87
|
+
'application/vnd.google-apps.presentation': ['gslides'],
|
|
88
|
+
'application/vnd.google-apps.form': ['gform'],
|
|
89
|
+
'application/vnd.google-apps.drawing': ['gdraw'],
|
|
90
|
+
'application/vnd.google-apps.jam': ['gjam'],
|
|
91
|
+
'application/vnd.google-apps.map': ['gmap'],
|
|
92
|
+
'application/vnd.google-apps.script': ['gscript'],
|
|
93
|
+
'application/vnd.google-apps.site': ['gsite'],
|
|
94
|
+
// ── Images ─────────────────────────────────────────────────────────────────
|
|
95
|
+
'image/png': ['png'],
|
|
96
|
+
'image/jpeg': ['jpg', 'jpeg', 'jpe'],
|
|
97
|
+
'image/pjpeg': ['jfif'],
|
|
98
|
+
'image/gif': ['gif'],
|
|
99
|
+
'image/webp': ['webp'],
|
|
100
|
+
'image/avif': ['avif'],
|
|
101
|
+
'image/apng': ['apng'],
|
|
102
|
+
'image/bmp': ['bmp', 'dib'],
|
|
103
|
+
'image/x-ms-bmp': ['bmp'],
|
|
104
|
+
'image/tiff': ['tif', 'tiff'],
|
|
105
|
+
'image/svg+xml': ['svg', 'svgz'],
|
|
106
|
+
'image/x-icon': ['ico'],
|
|
107
|
+
'image/vnd.microsoft.icon': ['ico'],
|
|
108
|
+
'image/heic': ['heic'],
|
|
109
|
+
'image/heic-sequence': ['heics'],
|
|
110
|
+
'image/heif': ['heif'],
|
|
111
|
+
'image/heif-sequence': ['heifs'],
|
|
112
|
+
'image/cgm': ['cgm'],
|
|
113
|
+
'image/jp2': ['jp2', 'jpg2'],
|
|
114
|
+
'image/jpx': ['jpx', 'jpf'],
|
|
115
|
+
'image/jpm': ['jpm', 'jpgm'],
|
|
116
|
+
'image/jxl': ['jxl'],
|
|
117
|
+
'image/jxr': ['jxr'],
|
|
118
|
+
'image/jxra': ['jxra'],
|
|
119
|
+
'image/jxrs': ['jxrs'],
|
|
120
|
+
'image/jxs': ['jxs'],
|
|
121
|
+
'image/jxsc': ['jxsc'],
|
|
122
|
+
'image/jxsi': ['jxsi'],
|
|
123
|
+
'image/jxss': ['jxss'],
|
|
124
|
+
'image/jph': ['jph'],
|
|
125
|
+
'image/jphc': ['jhc'],
|
|
126
|
+
'image/hej2k': ['hej2'],
|
|
127
|
+
'image/jls': ['jls'],
|
|
128
|
+
'image/jaii': ['jaii'],
|
|
129
|
+
'image/jais': ['jais'],
|
|
130
|
+
'image/ktx': ['ktx'],
|
|
131
|
+
'image/ktx2': ['ktx2'],
|
|
132
|
+
'image/aces': ['exr'],
|
|
133
|
+
'image/avci': ['avci'],
|
|
134
|
+
'image/avcs': ['avcs'],
|
|
135
|
+
'image/dicom-rle': ['drle'],
|
|
136
|
+
'image/dpx': ['dpx'],
|
|
137
|
+
'image/fits': ['fits'],
|
|
138
|
+
'image/g3fax': ['g3'],
|
|
139
|
+
'image/ief': ['ief'],
|
|
140
|
+
'image/t38': ['t38'],
|
|
141
|
+
'image/tiff-fx': ['tfx'],
|
|
142
|
+
'image/emf': ['emf'],
|
|
143
|
+
'image/wmf': ['wmf'],
|
|
144
|
+
'image/vnd.adobe.photoshop': ['psd'],
|
|
145
|
+
'application/postscript': ['ai', 'eps', 'ps'],
|
|
146
|
+
'image/x-adobe-dng': ['dng'],
|
|
147
|
+
'image/prs.btif': ['btif', 'btf'],
|
|
148
|
+
'image/prs.pti': ['pti'],
|
|
149
|
+
'image/vnd.airzip.accelerator.azv': ['azv'],
|
|
150
|
+
'image/vnd.blockfact.facti': ['facti'],
|
|
151
|
+
'image/vnd.dece.graphic': ['uvi', 'uvvi', 'uvg', 'uvvg'],
|
|
152
|
+
'image/vnd.djvu': ['djvu', 'djv'],
|
|
153
|
+
'image/vnd.dvb.subtitle': ['sub'],
|
|
154
|
+
'image/vnd.dwg': ['dwg'],
|
|
155
|
+
'image/vnd.dxf': ['dxf'],
|
|
156
|
+
'image/vnd.fastbidsheet': ['fbs'],
|
|
157
|
+
'image/vnd.fpx': ['fpx'],
|
|
158
|
+
'image/vnd.fst': ['fst'],
|
|
159
|
+
'image/vnd.fujixerox.edmics-mmr': ['mmr'],
|
|
160
|
+
'image/vnd.fujixerox.edmics-rlc': ['rlc'],
|
|
161
|
+
'image/vnd.ms-dds': ['dds'],
|
|
162
|
+
'image/vnd.ms-modi': ['mdi'],
|
|
163
|
+
'image/vnd.ms-photo': ['wdp'],
|
|
164
|
+
'image/vnd.net-fpx': ['npx'],
|
|
165
|
+
'image/vnd.pco.b16': ['b16'],
|
|
166
|
+
'image/vnd.tencent.tap': ['tap'],
|
|
167
|
+
'image/vnd.valve.source.texture': ['vtf'],
|
|
168
|
+
'image/vnd.wap.wbmp': ['wbmp'],
|
|
169
|
+
'image/vnd.xiff': ['xif'],
|
|
170
|
+
'image/vnd.zbrush.pcx': ['pcx'],
|
|
171
|
+
'image/x-3ds': ['3ds'],
|
|
172
|
+
'image/x-cmu-raster': ['ras'],
|
|
173
|
+
'image/x-cmx': ['cmx'],
|
|
174
|
+
'image/x-freehand': ['fh', 'fhc', 'fh4', 'fh5', 'fh7'],
|
|
175
|
+
'image/x-jng': ['jng'],
|
|
176
|
+
'image/x-mrsid-image': ['sid'],
|
|
177
|
+
'image/sgi': ['sgi'],
|
|
178
|
+
'image/x-pcx': ['pcx'],
|
|
179
|
+
'image/x-pict': ['pic', 'pct'],
|
|
180
|
+
'image/x-portable-anymap': ['pnm'],
|
|
181
|
+
'image/x-portable-bitmap': ['pbm'],
|
|
182
|
+
'image/x-portable-graymap': ['pgm'],
|
|
183
|
+
'image/x-portable-pixmap': ['ppm'],
|
|
184
|
+
'image/x-rgb': ['rgb'],
|
|
185
|
+
'image/x-tga': ['tga'],
|
|
186
|
+
'image/x-xbitmap': ['xbm'],
|
|
187
|
+
'image/x-xpixmap': ['xpm'],
|
|
188
|
+
'image/x-xwindowdump': ['xwd'],
|
|
189
|
+
// ── Audio ──────────────────────────────────────────────────────────────────
|
|
190
|
+
'audio/mpeg': ['mpga', 'mp2', 'mp2a', 'mp3', 'm2a', 'm3a'],
|
|
191
|
+
'audio/mp3': ['mp3'],
|
|
192
|
+
'audio/wav': ['wav'],
|
|
193
|
+
'audio/wave': ['wav'],
|
|
194
|
+
'audio/x-wav': ['wav'],
|
|
195
|
+
'audio/ogg': ['oga', 'ogg', 'spx', 'opus'],
|
|
196
|
+
'audio/mp4': ['m4a', 'mp4a', 'm4b'],
|
|
197
|
+
'audio/x-m4a': ['m4a'],
|
|
198
|
+
'audio/aac': ['adts', 'aac'],
|
|
199
|
+
'audio/x-aac': ['aac'],
|
|
200
|
+
'audio/x-aiff': ['aif', 'aiff', 'aifc'],
|
|
201
|
+
'audio/x-flac': ['flac'],
|
|
202
|
+
'audio/x-ms-wma': ['wma'],
|
|
203
|
+
'audio/amr': ['amr'],
|
|
204
|
+
'audio/midi': ['mid', 'midi', 'kar', 'rmi'],
|
|
205
|
+
'audio/matroska': ['mka'],
|
|
206
|
+
'audio/x-matroska': ['mka'],
|
|
207
|
+
'audio/mobile-xmf': ['mxmf'],
|
|
208
|
+
'audio/basic': ['au', 'snd'],
|
|
209
|
+
'audio/x-pn-realaudio': ['ram', 'ra'],
|
|
210
|
+
'audio/x-realaudio': ['ra'],
|
|
211
|
+
'audio/x-pn-realaudio-plugin': ['rmp'],
|
|
212
|
+
'audio/webm': ['weba'],
|
|
213
|
+
'audio/x-caf': ['caf'],
|
|
214
|
+
'audio/s3m': ['s3m'],
|
|
215
|
+
'audio/silk': ['sil'],
|
|
216
|
+
'audio/xm': ['xm'],
|
|
217
|
+
'audio/x-ms-wax': ['wax'],
|
|
218
|
+
'audio/x-mpegurl': ['m3u'],
|
|
219
|
+
'audio/adpcm': ['adp'],
|
|
220
|
+
'audio/vnd.dra': ['dra'],
|
|
221
|
+
'audio/vnd.dts': ['dts'],
|
|
222
|
+
'audio/vnd.dts.hd': ['dtshd'],
|
|
223
|
+
'audio/vnd.lucent.voice': ['lvp'],
|
|
224
|
+
'audio/vnd.ms-playready.media.pya': ['pya'],
|
|
225
|
+
'audio/vnd.digital-winds': ['eol'],
|
|
226
|
+
'audio/vnd.rip': ['rip'],
|
|
227
|
+
'audio/vnd.nuera.ecelp4800': ['ecelp4800'],
|
|
228
|
+
'audio/vnd.nuera.ecelp7470': ['ecelp7470'],
|
|
229
|
+
'audio/vnd.nuera.ecelp9600': ['ecelp9600'],
|
|
230
|
+
// ── Video ──────────────────────────────────────────────────────────────────
|
|
231
|
+
'video/mp4': ['mp4', 'mp4v', 'mpg4'],
|
|
232
|
+
'video/mpeg': ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'],
|
|
233
|
+
'video/x-m4v': ['m4v'],
|
|
234
|
+
'video/quicktime': ['qt', 'mov'],
|
|
235
|
+
'video/x-msvideo': ['avi'],
|
|
236
|
+
'video/x-matroska': ['mkv', 'mk3d', 'mks'],
|
|
237
|
+
'video/matroska': ['mkv'],
|
|
238
|
+
'video/matroska-3d': ['mk3d'],
|
|
239
|
+
'video/webm': ['webm'],
|
|
240
|
+
'video/x-flv': ['flv'],
|
|
241
|
+
'video/x-f4v': ['f4v'],
|
|
242
|
+
'video/x-ms-wmv': ['wmv'],
|
|
243
|
+
'video/x-ms-wm': ['wm'],
|
|
244
|
+
'video/x-ms-wmx': ['wmx'],
|
|
245
|
+
'video/x-ms-wvx': ['wvx'],
|
|
246
|
+
'video/x-ms-asf': ['asf', 'asx'],
|
|
247
|
+
'video/x-ms-vob': ['vob'],
|
|
248
|
+
'video/mp2t': ['ts', 'm2t', 'm2ts', 'mts'],
|
|
249
|
+
'video/ogg': ['ogv'],
|
|
250
|
+
'video/3gpp': ['3gp', '3gpp'],
|
|
251
|
+
'video/3gpp2': ['3g2'],
|
|
252
|
+
'video/vnd.mpegurl': ['mxu', 'm4u'],
|
|
253
|
+
'video/x-mng': ['mng'],
|
|
254
|
+
'video/x-fli': ['fli'],
|
|
255
|
+
'video/x-sgi-movie': ['movie'],
|
|
256
|
+
'video/x-smv': ['smv'],
|
|
257
|
+
'video/iso.segment': ['m4s'],
|
|
258
|
+
'video/mj2': ['mj2', 'mjp2'],
|
|
259
|
+
'video/h261': ['h261'],
|
|
260
|
+
'video/h263': ['h263'],
|
|
261
|
+
'video/h264': ['h264'],
|
|
262
|
+
'video/jpeg': ['jpgv'],
|
|
263
|
+
'video/jpm': ['jpm', 'jpgm'],
|
|
264
|
+
'video/vnd.dvb.file': ['dvb'],
|
|
265
|
+
'video/vnd.fvt': ['fvt'],
|
|
266
|
+
'video/vnd.vivo': ['viv'],
|
|
267
|
+
'video/vnd.ms-playready.media.pyv': ['pyv'],
|
|
268
|
+
'video/vnd.dece.hd': ['uvh', 'uvvh'],
|
|
269
|
+
'video/vnd.dece.mobile': ['uvm', 'uvvm'],
|
|
270
|
+
'video/vnd.dece.pd': ['uvp', 'uvvp'],
|
|
271
|
+
'video/vnd.dece.sd': ['uvs', 'uvvs'],
|
|
272
|
+
'video/vnd.dece.video': ['uvv', 'uvvv'],
|
|
273
|
+
'video/vnd.uvvu.mp4': ['uvu', 'uvvu'],
|
|
274
|
+
// ── Archives & Compression ─────────────────────────────────────────────────
|
|
275
|
+
'application/zip': ['zip'],
|
|
276
|
+
'application/x-zip-compressed': ['zip'],
|
|
277
|
+
'application/vnd.rar': ['rar'],
|
|
278
|
+
'application/x-rar-compressed': ['rar'],
|
|
279
|
+
'application/x-compressed': ['rar'],
|
|
280
|
+
'application/gzip': ['gz'],
|
|
281
|
+
'application/x-bzip': ['bz'],
|
|
282
|
+
'application/x-bzip2': ['bz2', 'boz'],
|
|
283
|
+
'application/x-7z-compressed': ['7z'],
|
|
284
|
+
'application/x-tar': ['tar'],
|
|
285
|
+
'application/x-xz': ['xz'],
|
|
286
|
+
'application/x-lzh-compressed': ['lzh', 'lha'],
|
|
287
|
+
'application/vnd.ms-cab-compressed': ['cab'],
|
|
288
|
+
'application/x-arj': ['arj'],
|
|
289
|
+
'application/x-freearc': ['arc'],
|
|
290
|
+
'application/x-ace-compressed': ['ace'],
|
|
291
|
+
'application/x-stuffit': ['sit'],
|
|
292
|
+
'application/x-stuffitx': ['sitx'],
|
|
293
|
+
'application/x-sea': ['sea'],
|
|
294
|
+
'application/x-shar': ['shar'],
|
|
295
|
+
'application/x-iso9660-image': ['iso'],
|
|
296
|
+
'application/x-apple-diskimage': ['dmg'],
|
|
297
|
+
'application/x-cpio': ['cpio'],
|
|
298
|
+
'application/vnd.android.package-archive': ['apk'],
|
|
299
|
+
'application/java-archive': ['jar', 'war', 'ear'],
|
|
300
|
+
'application/x-debian-package': ['deb', 'udeb'],
|
|
301
|
+
'application/x-redhat-package-manager': ['rpm'],
|
|
302
|
+
'application/x-msdownload': ['exe', 'dll', 'com', 'bat', 'msi'],
|
|
303
|
+
'application/octet-stream': ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy', 'exe', 'dll', 'deb', 'dmg', 'iso', 'img', 'msi', 'msp', 'msm', 'buffer'],
|
|
304
|
+
'application/msix': ['msix'],
|
|
305
|
+
'application/msixbundle': ['msixbundle'],
|
|
306
|
+
'application/appx': ['appx'],
|
|
307
|
+
'application/appxbundle': ['appxbundle'],
|
|
308
|
+
'application/appinstaller': ['appinstaller'],
|
|
309
|
+
'application/x-chrome-extension': ['crx'],
|
|
310
|
+
'application/x-xpinstall': ['xpi'],
|
|
311
|
+
'application/zip+dotlottie': ['lottie'],
|
|
312
|
+
'application/x-cbr': ['cbr', 'cba', 'cbt', 'cbz', 'cb7'],
|
|
313
|
+
'application/x-gca-compressed': ['gca'],
|
|
314
|
+
'application/x-dgc-compressed': ['dgc'],
|
|
315
|
+
'application/x-virtualbox-ova': ['ova'],
|
|
316
|
+
'application/x-virtualbox-vbox': ['vbox'],
|
|
317
|
+
'application/x-virtualbox-vbox-extpack': ['vbox-extpack'],
|
|
318
|
+
'application/x-sv4cpio': ['sv4cpio'],
|
|
319
|
+
'application/x-sv4crc': ['sv4crc'],
|
|
320
|
+
'application/x-ustar': ['ustar'],
|
|
321
|
+
'application/x-gtar': ['gtar'],
|
|
322
|
+
'application/x-cfs-compressed': ['cfs'],
|
|
323
|
+
'application/x-nzb': ['nzb'],
|
|
324
|
+
'application/x-bittorrent': ['torrent'],
|
|
325
|
+
'application/vnd.ms-pki.stl': ['stl'],
|
|
326
|
+
// ── Code & Markup ──────────────────────────────────────────────────────────
|
|
327
|
+
'application/javascript': ['js'],
|
|
328
|
+
'text/javascript': ['js', 'mjs'],
|
|
329
|
+
'application/node': ['cjs'],
|
|
330
|
+
'text/jsx': ['jsx'],
|
|
331
|
+
'application/json': ['json', 'map'],
|
|
332
|
+
'application/json5': ['json5'],
|
|
333
|
+
'application/ld+json': ['jsonld'],
|
|
334
|
+
'application/jsonml+json': ['jsonml'],
|
|
335
|
+
'application/wasm': ['wasm'],
|
|
336
|
+
'text/html': ['html', 'htm', 'shtml'],
|
|
337
|
+
'application/xhtml+xml': ['xhtml', 'xht'],
|
|
338
|
+
'text/css': ['css'],
|
|
339
|
+
'text/less': ['less'],
|
|
340
|
+
'text/x-sass': ['sass'],
|
|
341
|
+
'text/x-scss': ['scss'],
|
|
342
|
+
'text/stylus': ['stylus', 'styl'],
|
|
343
|
+
'application/xml': ['xml', 'xsl', 'xsd', 'rng'],
|
|
344
|
+
'text/xml': ['xml'],
|
|
345
|
+
'application/xslt+xml': ['xsl', 'xslt'],
|
|
346
|
+
'application/xml-dtd': ['dtd'],
|
|
347
|
+
'text/x-c': ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'],
|
|
348
|
+
'text/x-java-source': ['java'],
|
|
349
|
+
'application/java-vm': ['class'],
|
|
350
|
+
'text/x-php': ['php'],
|
|
351
|
+
'application/x-httpd-php': ['php'],
|
|
352
|
+
'text/x-pascal': ['p', 'pas'],
|
|
353
|
+
'text/x-fortran': ['f', 'for', 'f77', 'f90'],
|
|
354
|
+
'text/x-asm': ['s', 'asm'],
|
|
355
|
+
'application/x-perl': ['pl', 'pm'],
|
|
356
|
+
'application/x-sh': ['sh'],
|
|
357
|
+
'application/x-csh': ['csh'],
|
|
358
|
+
'application/x-tcl': ['tcl', 'tk'],
|
|
359
|
+
'application/x-lua-bytecode': ['luac'],
|
|
360
|
+
'text/x-lua': ['lua'],
|
|
361
|
+
'application/x-sql': ['sql'],
|
|
362
|
+
'application/sql': ['sql'],
|
|
363
|
+
'application/dart': ['dart'],
|
|
364
|
+
'application/vnd.dart': ['dart'],
|
|
365
|
+
'text/coffeescript': ['coffee', 'litcoffee'],
|
|
366
|
+
'text/jade': ['jade'],
|
|
367
|
+
'text/x-handlebars-template': ['hbs'],
|
|
368
|
+
'text/x-processing': ['pde'],
|
|
369
|
+
'text/mathml': ['mml'],
|
|
370
|
+
'application/mathml+xml': ['mathml'],
|
|
371
|
+
'application/yaml': ['yaml', 'yml'],
|
|
372
|
+
'text/yaml': ['yaml', 'yml'],
|
|
373
|
+
'application/toml': ['toml'],
|
|
374
|
+
'text/x-component': ['htc'],
|
|
375
|
+
'text/x-nfo': ['nfo'],
|
|
376
|
+
'text/x-opml': ['opml'],
|
|
377
|
+
'text/uri-list': ['uri', 'uris', 'urls'],
|
|
378
|
+
'text/x-suse-ymp': ['ymp'],
|
|
379
|
+
'text/x-uuencode': ['uu'],
|
|
380
|
+
'text/vnd.curl': ['curl'],
|
|
381
|
+
'text/vnd.curl.dcurl': ['dcurl'],
|
|
382
|
+
'text/vnd.curl.mcurl': ['mcurl'],
|
|
383
|
+
'text/vnd.curl.scurl': ['scurl'],
|
|
384
|
+
'text/x-sfv': ['sfv'],
|
|
385
|
+
'text/x-setext': ['etx'],
|
|
386
|
+
'text/wgsl': ['wgsl'],
|
|
387
|
+
'application/x-ipynb+json': ['ipynb'],
|
|
388
|
+
'text/prs.lines.tag': ['dsc'],
|
|
389
|
+
'text/vnd.fly': ['fly'],
|
|
390
|
+
'text/vnd.fmi.flexstor': ['flx'],
|
|
391
|
+
'text/vnd.graphviz': ['gv'],
|
|
392
|
+
'text/vnd.in3d.3dml': ['3dml'],
|
|
393
|
+
'text/vnd.in3d.spot': ['spot'],
|
|
394
|
+
'text/vnd.wap.wml': ['wml'],
|
|
395
|
+
'text/vnd.wap.wmlscript': ['wmls'],
|
|
396
|
+
// ── Fonts ──────────────────────────────────────────────────────────────────
|
|
397
|
+
'font/ttf': ['ttf'],
|
|
398
|
+
'font/otf': ['otf'],
|
|
399
|
+
'font/collection': ['ttc'],
|
|
400
|
+
'font/woff': ['woff'],
|
|
401
|
+
'font/woff2': ['woff2'],
|
|
402
|
+
'application/vnd.ms-fontobject': ['eot'],
|
|
403
|
+
'application/x-font-type1': ['pfa', 'pfb', 'pfm', 'afm'],
|
|
404
|
+
'application/x-font-bdf': ['bdf'],
|
|
405
|
+
'application/x-font-ghostscript': ['gsf'],
|
|
406
|
+
'application/x-font-linux-psf': ['psf'],
|
|
407
|
+
'application/x-font-pcf': ['pcf'],
|
|
408
|
+
'application/x-font-snf': ['snf'],
|
|
409
|
+
// ── Data & Database ────────────────────────────────────────────────────────
|
|
410
|
+
'application/vnd.sqlite3': ['sqlite', 'sqlite3'],
|
|
411
|
+
'application/x-msaccess': ['mdb'],
|
|
412
|
+
'application/vnd.dbf': ['dbf'],
|
|
413
|
+
'application/vnd.apache.parquet': ['parquet'],
|
|
414
|
+
'application/x-netcdf': ['nc', 'cdf'],
|
|
415
|
+
'application/x-hdf': ['hdf'],
|
|
416
|
+
// ── Office (other) ─────────────────────────────────────────────────────────
|
|
417
|
+
'application/onenote': ['onetoc', 'onetoc2', 'onetmp', 'onepkg', 'one', 'onea'],
|
|
418
|
+
'application/x-mspublisher': ['pub'],
|
|
419
|
+
'application/vnd.ms-project': ['mpp', 'mpt'],
|
|
420
|
+
'application/vnd.visio': ['vsd', 'vst', 'vss', 'vsw', 'vsdx', 'vtx'],
|
|
421
|
+
'application/vnd.ms-visio.viewer': ['vdx'],
|
|
422
|
+
'application/vnd.ms-officetheme': ['thmx'],
|
|
423
|
+
'application/vnd.ms-htmlhelp': ['chm'],
|
|
424
|
+
'application/x-msmoney': ['mny'],
|
|
425
|
+
'application/vnd.ms-wpl': ['wpl'],
|
|
426
|
+
'application/vnd.ms-xpsdocument': ['xps'],
|
|
427
|
+
'application/x-msbinder': ['obd'],
|
|
428
|
+
'application/x-mscardfile': ['crd'],
|
|
429
|
+
'application/x-msclip': ['clp'],
|
|
430
|
+
'application/x-msschedule': ['scd'],
|
|
431
|
+
'application/x-msterminal': ['trm'],
|
|
432
|
+
'application/x-mswrite': ['wri'],
|
|
433
|
+
'application/winhlp': ['hlp'],
|
|
434
|
+
// ── CAD & 3D ───────────────────────────────────────────────────────────────
|
|
435
|
+
'model/vnd.dwf': ['dwf'],
|
|
436
|
+
'model/step': ['step', 'stp', 'stpnc', 'p21', '210'],
|
|
437
|
+
'model/step+xml': ['stpx'],
|
|
438
|
+
'model/step+zip': ['stpz'],
|
|
439
|
+
'model/step-xml+zip': ['stpxz'],
|
|
440
|
+
'model/stl': ['stl'],
|
|
441
|
+
'model/iges': ['iges', 'igs'],
|
|
442
|
+
'model/3mf': ['3mf'],
|
|
443
|
+
'model/obj': ['obj'],
|
|
444
|
+
'model/mtl': ['mtl'],
|
|
445
|
+
'application/vnd.autodesk.fbx': ['fbx'],
|
|
446
|
+
'model/gltf+json': ['gltf'],
|
|
447
|
+
'model/gltf-binary': ['glb'],
|
|
448
|
+
'model/vnd.usdz+zip': ['usdz'],
|
|
449
|
+
'model/vnd.usda': ['usda'],
|
|
450
|
+
'application/x-blender': ['blend'],
|
|
451
|
+
'model/vnd.collada+xml': ['dae'],
|
|
452
|
+
'model/x3d+xml': ['x3d', 'x3dz'],
|
|
453
|
+
'model/x3d+binary': ['x3db', 'x3dbz'],
|
|
454
|
+
'model/x3d+vrml': ['x3dv', 'x3dvz'],
|
|
455
|
+
'model/vrml': ['wrl', 'vrml'],
|
|
456
|
+
'model/mesh': ['msh', 'mesh', 'silo'],
|
|
457
|
+
'model/u3d': ['u3d'],
|
|
458
|
+
'model/jt': ['jt'],
|
|
459
|
+
'model/prc': ['prc'],
|
|
460
|
+
'model/vnd.bary': ['bary'],
|
|
461
|
+
'model/vnd.cld': ['cld'],
|
|
462
|
+
'model/vnd.gdl': ['gdl'],
|
|
463
|
+
'model/vnd.gtw': ['gtw'],
|
|
464
|
+
'model/vnd.opengex': ['ogex'],
|
|
465
|
+
'model/vnd.parasolid.transmit.binary': ['x_b'],
|
|
466
|
+
'model/vnd.parasolid.transmit.text': ['x_t'],
|
|
467
|
+
'model/vnd.pytha.pyox': ['pyo', 'pyox'],
|
|
468
|
+
'model/vnd.sap.vds': ['vds'],
|
|
469
|
+
'model/vnd.valve.source.compiled-map': ['bsp'],
|
|
470
|
+
'model/vnd.vtu': ['vtu'],
|
|
471
|
+
// ── Calendar / Contact / Mail ──────────────────────────────────────────────
|
|
472
|
+
'text/calendar': ['ics', 'ifb'],
|
|
473
|
+
'text/x-vcalendar': ['vcs'],
|
|
474
|
+
'text/vcard': ['vcard'],
|
|
475
|
+
'text/x-vcard': ['vcf'],
|
|
476
|
+
'message/rfc822': ['eml', 'mime', 'mht', 'mhtml'],
|
|
477
|
+
'application/vnd.ms-outlook': ['msg'],
|
|
478
|
+
'application/mbox': ['mbox'],
|
|
479
|
+
'message/global': ['u8msg'],
|
|
480
|
+
'message/global-delivery-status': ['u8dsn'],
|
|
481
|
+
'message/global-disposition-notification': ['u8mdn'],
|
|
482
|
+
'message/global-headers': ['u8hdr'],
|
|
483
|
+
'message/vnd.wfa.wsc': ['wsc'],
|
|
484
|
+
'text/vnd.familysearch.gedcom': ['ged'],
|
|
485
|
+
// ── Certificates / Keys / Crypto ───────────────────────────────────────────
|
|
486
|
+
'application/x-x509-ca-cert': ['der', 'crt', 'pem'],
|
|
487
|
+
'application/x-pkcs12': ['p12', 'pfx'],
|
|
488
|
+
'application/x-pkcs7-certificates': ['p7b', 'spc'],
|
|
489
|
+
'application/pkcs7-mime': ['p7m', 'p7c'],
|
|
490
|
+
'application/x-pkcs7-certreqresp': ['p7r'],
|
|
491
|
+
'application/pkcs7-signature': ['p7s'],
|
|
492
|
+
'application/pkcs8': ['p8'],
|
|
493
|
+
'application/pkcs10': ['p10'],
|
|
494
|
+
'application/pkix-cert': ['cer'],
|
|
495
|
+
'application/pkix-crl': ['crl'],
|
|
496
|
+
'application/pkix-pkipath': ['pkipath'],
|
|
497
|
+
'application/pkixcmp': ['pki'],
|
|
498
|
+
'application/pgp-encrypted': ['pgp'],
|
|
499
|
+
'application/pgp-keys': ['asc'],
|
|
500
|
+
'application/pgp-signature': ['sig', 'asc'],
|
|
501
|
+
'application/x-keepass2': ['kdbx'],
|
|
502
|
+
// ── Subtitles / Captions ───────────────────────────────────────────────────
|
|
503
|
+
'application/x-subrip': ['srt'],
|
|
504
|
+
'text/vtt': ['vtt'],
|
|
505
|
+
'text/vnd.dvb.subtitle': ['sub'],
|
|
506
|
+
// ── Disk Images / Virtualization ───────────────────────────────────────────
|
|
507
|
+
'application/x-virtualbox-vhd': ['vhd'],
|
|
508
|
+
'application/x-virtualbox-vmdk': ['vmdk'],
|
|
509
|
+
'application/x-virtualbox-vdi': ['vdi'],
|
|
510
|
+
'application/x-virtualbox-ovf': ['ovf'],
|
|
511
|
+
'application/x-virtualbox-hdd': ['hdd'],
|
|
512
|
+
// ── GIS / Geospatial ───────────────────────────────────────────────────────
|
|
513
|
+
'application/geo+json': ['geojson'],
|
|
514
|
+
'application/vnd.google-earth.kml+xml': ['kml'],
|
|
515
|
+
'application/vnd.google-earth.kmz': ['kmz'],
|
|
516
|
+
'application/gpx+xml': ['gpx'],
|
|
517
|
+
'application/gml+xml': ['gml'],
|
|
518
|
+
'application/vnd.mapbox-vector-tile': ['mvt'],
|
|
519
|
+
'application/vnd.openstreetmap.data+xml': ['osm'],
|
|
520
|
+
// ── Web / Manifests / Feeds / RDF ──────────────────────────────────────────
|
|
521
|
+
'application/manifest+json': ['webmanifest'],
|
|
522
|
+
'application/x-web-app-manifest+json': ['webapp'],
|
|
523
|
+
'application/atom+xml': ['atom'],
|
|
524
|
+
'application/atomcat+xml': ['atomcat'],
|
|
525
|
+
'application/atomdeleted+xml': ['atomdeleted'],
|
|
526
|
+
'application/atomsvc+xml': ['atomsvc'],
|
|
527
|
+
'application/rss+xml': ['rss'],
|
|
528
|
+
'application/rsd+xml': ['rsd'],
|
|
529
|
+
'application/rdf+xml': ['rdf', 'owl'],
|
|
530
|
+
'application/wsdl+xml': ['wsdl'],
|
|
531
|
+
'application/wspolicy+xml': ['wspolicy'],
|
|
532
|
+
'application/widget': ['wgt'],
|
|
533
|
+
'application/yang': ['yang'],
|
|
534
|
+
'application/yin+xml': ['yin'],
|
|
535
|
+
'application/xv+xml': ['mxml', 'xhvml', 'xvml', 'xvm'],
|
|
536
|
+
'application/xaml+xml': ['xaml'],
|
|
537
|
+
'application/xproc+xml': ['xpl'],
|
|
538
|
+
'application/xop+xml': ['xop'],
|
|
539
|
+
'application/xenc+xml': ['xenc'],
|
|
540
|
+
'application/xliff+xml': ['xlf'],
|
|
541
|
+
'application/xspf+xml': ['xspf'],
|
|
542
|
+
'application/vnd.xfdl': ['xfdl'],
|
|
543
|
+
'application/vnd.xara': ['xar'],
|
|
544
|
+
'application/voicexml+xml': ['vxml'],
|
|
545
|
+
'application/watcherinfo+xml': ['wif'],
|
|
546
|
+
// ── Installers / Specialty containers ──────────────────────────────────────
|
|
547
|
+
'application/x-shockwave-flash': ['swf'],
|
|
548
|
+
'application/x-silverlight-app': ['xap'],
|
|
549
|
+
'application/x-ms-application': ['application'],
|
|
550
|
+
'application/x-ms-shortcut': ['lnk'],
|
|
551
|
+
'application/x-java-jnlp-file': ['jnlp'],
|
|
552
|
+
'application/x-install-instructions': ['install'],
|
|
553
|
+
'application/x-makeself': ['run'],
|
|
554
|
+
'application/x-java-archive-diff': ['jardiff'],
|
|
555
|
+
'application/x-mie': ['mie'],
|
|
556
|
+
'application/vnd.apple.installer+xml': ['mpkg'],
|
|
557
|
+
'application/vnd.apple.pkpass': ['pkpass'],
|
|
558
|
+
'application/vnd.apple.mpegurl': ['m3u8'],
|
|
559
|
+
// ── Z-machine / Game data ──────────────────────────────────────────────────
|
|
560
|
+
'application/x-zmachine': ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'],
|
|
561
|
+
'application/x-tads': ['gam'],
|
|
562
|
+
'application/x-glulx': ['ulx'],
|
|
563
|
+
'application/x-doom': ['wad'],
|
|
564
|
+
'application/x-conference': ['nsc'],
|
|
565
|
+
'application/x-cdlink': ['vcd'],
|
|
566
|
+
'application/x-chess-pgn': ['pgn'],
|
|
567
|
+
'application/x-chat': ['chat'],
|
|
568
|
+
'application/x-cocoa': ['cco'],
|
|
569
|
+
// ── Adobe AIR / Misc app packages ──────────────────────────────────────────
|
|
570
|
+
'application/vnd.adobe.air-application-installer-package+zip': ['air'],
|
|
571
|
+
'application/vnd.adobe.fxp': ['fxp', 'fxpl'],
|
|
572
|
+
'application/vnd.adobe.xdp+xml': ['xdp'],
|
|
573
|
+
'application/vnd.adobe.formscentral.fcdt': ['fcdt'],
|
|
574
|
+
// ── Other (preserved from prior list) ──────────────────────────────────────
|
|
575
|
+
'application/x-research-info-systems': ['ris'],
|
|
576
|
+
'application/x-tex-tfm': ['tfm'],
|
|
577
|
+
'application/x-t3vm-image': ['t3'],
|
|
578
|
+
'application/x-eva': ['eva'],
|
|
579
|
+
'application/x-envoy': ['evy'],
|
|
580
|
+
'application/x-dvi': ['dvi'],
|
|
581
|
+
'application/x-dtbresource+xml': ['res'],
|
|
582
|
+
'application/x-dtbook+xml': ['dtb'],
|
|
583
|
+
'application/x-dtbncx+xml': ['ncx'],
|
|
584
|
+
'application/x-director': ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'],
|
|
585
|
+
'application/x-bcpio': ['bcpio'],
|
|
586
|
+
'application/x-blorb': ['blb', 'blorb'],
|
|
587
|
+
'application/x-authorware-bin': ['aab', 'x32', 'u32', 'vox'],
|
|
588
|
+
'application/x-authorware-map': ['aam'],
|
|
589
|
+
'application/x-authorware-seg': ['aas'],
|
|
590
|
+
'application/x-futuresplash': ['spl'],
|
|
591
|
+
'application/x-gramps-xml': ['gramps'],
|
|
592
|
+
'application/x-wais-source': ['src'],
|
|
593
|
+
'application/x-pilot': ['prc', 'pdb'],
|
|
594
|
+
'application/x-pki-message': [],
|
|
595
|
+
'application/x-ns-proxy-autoconfig': ['pac'],
|
|
596
|
+
'application/x-xfig': ['fig'],
|
|
597
|
+
'application/x-msmediaview': ['mvb', 'm13', 'm14'],
|
|
598
|
+
'application/x-ms-wmd': ['wmd'],
|
|
599
|
+
'application/x-ms-wmz': ['wmz'],
|
|
600
|
+
'application/x-ms-xbap': ['xbap'],
|
|
601
|
+
'application/x-msmetafile': ['wmf', 'wmz', 'emf', 'emz'],
|
|
602
|
+
'x-conference/x-cooltalk': ['ice'],
|
|
603
|
+
};
|
|
604
|
+
/**
|
|
605
|
+
* Flat set of every extension known to {@link VALID_MIME_TYPES}, used by the
|
|
606
|
+
* extension-only fast path ({@link hasValidExtension}). Derived once at module
|
|
607
|
+
* load — kept in sync with the map automatically.
|
|
608
|
+
*/
|
|
609
|
+
export const VALID_FILE_EXTENSIONS = new Set(Object.values(VALID_MIME_TYPES).flat());
|
|
610
|
+
/**
|
|
611
|
+
* Normalize a filename or raw extension to a lowercase no-dot extension token.
|
|
612
|
+
* Returns null if no extension is present.
|
|
613
|
+
*/
|
|
614
|
+
export function normalizeExtension(input) {
|
|
615
|
+
const dot = input.lastIndexOf('.');
|
|
616
|
+
if (dot < 0 || dot === input.length - 1)
|
|
617
|
+
return null;
|
|
618
|
+
return input.slice(dot + 1).toLowerCase();
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Returns true when the given filename ends in a recognized extension.
|
|
622
|
+
* Files with no extension, or extensions that aren't in {@link VALID_FILE_EXTENSIONS},
|
|
623
|
+
* are rejected as "fake" / nonsense.
|
|
624
|
+
*
|
|
625
|
+
* Prefer {@link validateFileType} when a `File` object is available — it catches
|
|
626
|
+
* extension spoofing that this function cannot.
|
|
627
|
+
*/
|
|
628
|
+
export function hasValidExtension(filename) {
|
|
629
|
+
const ext = normalizeExtension(filename);
|
|
630
|
+
if (!ext)
|
|
631
|
+
return false;
|
|
632
|
+
return VALID_FILE_EXTENSIONS.has(ext);
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Strict file validation: the browser-reported MIME type must be known, AND the
|
|
636
|
+
* filename's extension must be one of the extensions registered for that type.
|
|
637
|
+
*
|
|
638
|
+
* Rejects:
|
|
639
|
+
* - files with no extension
|
|
640
|
+
* - files whose `type` is empty or unknown to {@link VALID_MIME_TYPES}
|
|
641
|
+
* - files whose extension does not match the registered list for `file.type`
|
|
642
|
+
* (extension-spoofing guard, e.g. `.exe` renamed to `.jpg`)
|
|
643
|
+
*
|
|
644
|
+
* `file.type` comparison is case-insensitive; some browsers lowercase but a few
|
|
645
|
+
* legacy ones don't.
|
|
646
|
+
*/
|
|
647
|
+
export function validateFileType(file) {
|
|
648
|
+
const mimeType = file.type.toLowerCase();
|
|
649
|
+
if (!mimeType)
|
|
650
|
+
return false;
|
|
651
|
+
const allowedExtensions = VALID_MIME_TYPES[mimeType];
|
|
652
|
+
if (!allowedExtensions)
|
|
653
|
+
return false;
|
|
654
|
+
const ext = normalizeExtension(file.name);
|
|
655
|
+
if (!ext)
|
|
656
|
+
return false;
|
|
657
|
+
return allowedExtensions.includes(ext);
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Look up every MIME type that legitimately produces the given extension.
|
|
661
|
+
* Useful for `accept`-attribute construction or reverse diagnostics.
|
|
662
|
+
*/
|
|
663
|
+
export function getMimeTypesForExtension(extension) {
|
|
664
|
+
const ext = extension.startsWith('.') ? extension.slice(1).toLowerCase() : extension.toLowerCase();
|
|
665
|
+
const matches = [];
|
|
666
|
+
for (const [mimeType, exts] of Object.entries(VALID_MIME_TYPES)) {
|
|
667
|
+
if (exts.includes(ext))
|
|
668
|
+
matches.push(mimeType);
|
|
669
|
+
}
|
|
670
|
+
return matches;
|
|
671
|
+
}
|