|
| 1 | +local M = {} |
| 2 | + |
| 3 | +--- Check if the MIME type is a supported format |
| 4 | +--- @param mime_type string |
| 5 | +--- @param supported_formats string[] |
| 6 | +--- @return boolean |
| 7 | +M.is_supported_mime_type = function(mime_type, supported_formats) |
| 8 | + local mime_fmts = M.formats_from_mime_type(mime_type) |
| 9 | + |
| 10 | + -- Handle unknown formats |
| 11 | + if mime_fmts == nil then |
| 12 | + return false |
| 13 | + end |
| 14 | + |
| 15 | + -- Convert into a set (https://www.lua.org/pil/11.5.html) |
| 16 | + local valid_formats = {} |
| 17 | + for _, format in ipairs(supported_formats) do |
| 18 | + valid_formats[format] = true |
| 19 | + end |
| 20 | + |
| 21 | + for _, fmt in pairs(mime_fmts) do |
| 22 | + if valid_formats[fmt] ~= nil then |
| 23 | + return true |
| 24 | + end |
| 25 | + end |
| 26 | + |
| 27 | + return false |
| 28 | +end |
| 29 | + |
| 30 | +-- Return a table of the image format extensions corresponding to this mime type |
| 31 | +--- @return string[] |
| 32 | +M.formats_from_mime_type = function(mime_type) |
| 33 | + local mime_fmts = M.mime_types[mime_type] |
| 34 | + |
| 35 | + if type(mime_fmts) == "string" then |
| 36 | + -- Make a table, because multiple formats could map to the MIME type |
| 37 | + mime_fmts = { mime_fmts } |
| 38 | + end |
| 39 | + |
| 40 | + return mime_fmts |
| 41 | +end |
| 42 | + |
| 43 | +-- A table of common MIME types mapping to file extensions. |
| 44 | +-- Based on public documentation and observed conventions across platforms. |
| 45 | +M.mime_types = { |
| 46 | + ["audio/aac"] = "aac", |
| 47 | + ["application/x-abiword"] = "abw", |
| 48 | + ["image/apng"] = "apng", |
| 49 | + ["application/x-freearc"] = "arc", |
| 50 | + ["image/avif"] = "avif", |
| 51 | + ["video/x-msvideo"] = "avi", |
| 52 | + ["application/vnd.amazon.ebook"] = "azw", |
| 53 | + ["application/octet-stream"] = "bin", |
| 54 | + ["image/bmp"] = "bmp", |
| 55 | + ["application/x-bzip"] = "bz", |
| 56 | + ["application/x-bzip2"] = "bz2", |
| 57 | + ["application/x-cdf"] = "cda", |
| 58 | + ["application/x-csh"] = "csh", |
| 59 | + ["text/css"] = "css", |
| 60 | + ["text/csv"] = "csv", |
| 61 | + ["application/msword"] = "doc", |
| 62 | + ["application/vnd.openxmlformats-officedocument.wordprocessingml.document"] = "docx", |
| 63 | + ["application/vnd.ms-fontobject"] = "eot", |
| 64 | + ["application/epub+zip"] = "epub", |
| 65 | + ["application/gzip"] = "gz", |
| 66 | + -- Windows and macOS upload `.gz` files with this the non-standard MIME type. |
| 67 | + ["application/x-gzip"] = "gz", |
| 68 | + ["image/gif"] = "gif", |
| 69 | + ["text/html"] = { "htm", "html" }, |
| 70 | + ["image/vnd.microsoft.icon"] = "ico", |
| 71 | + ["text/calendar"] = "ics", |
| 72 | + ["application/java-archive"] = "jar", |
| 73 | + ["image/jpeg"] = { "jpeg", "jpg" }, |
| 74 | + -- (Specifications: HTML and RFC 9239) |
| 75 | + ["text/javascript "] = "js", |
| 76 | + ["application/json"] = "json", |
| 77 | + ["application/ld+json"] = "jsonld", |
| 78 | + ["audio/midi, audio/x-midi"] = { "mid", "midi" }, |
| 79 | + ["text/javascript"] = "mjs", |
| 80 | + ["audio/mpeg"] = "mp3", |
| 81 | + ["video/mp4"] = "mp4", |
| 82 | + ["video/mpeg"] = "mpeg", |
| 83 | + ["application/vnd.apple.installer+xml"] = "mpkg", |
| 84 | + ["application/vnd.oasis.opendocument.presentation"] = "odp", |
| 85 | + ["application/vnd.oasis.opendocument.spreadsheet"] = "ods", |
| 86 | + ["application/vnd.oasis.opendocument.text"] = "odt", |
| 87 | + ["audio/ogg"] = { "oga", "opus" }, |
| 88 | + ["video/ogg"] = "ogv", |
| 89 | + ["application/ogg"] = "ogx", |
| 90 | + ["font/otf"] = "otf", |
| 91 | + ["image/png"] = "png", |
| 92 | + ["application/pdf"] = "pdf", |
| 93 | + ["application/x-httpd-php"] = "php", |
| 94 | + ["application/vnd.ms-powerpoint"] = "ppt", |
| 95 | + ["application/vnd.openxmlformats-officedocument.presentationml.presentation"] = "pptx", |
| 96 | + ["application/vnd.rar"] = "rar", |
| 97 | + ["application/rtf"] = "rtf", |
| 98 | + ["application/x-sh"] = "sh", |
| 99 | + ["image/svg+xml"] = "svg", |
| 100 | + ["application/x-tar"] = "tar", |
| 101 | + ["image/tiff"] = { "tif", "tiff" }, |
| 102 | + ["video/mp2t"] = "ts", |
| 103 | + ["font/ttf"] = "ttf", |
| 104 | + ["text/plain"] = "txt", |
| 105 | + ["application/vnd.visio"] = "vsd", |
| 106 | + ["audio/wav"] = "wav", |
| 107 | + ["audio/webm"] = "weba", |
| 108 | + ["video/webm"] = "webm", |
| 109 | + ["image/webp"] = "webp", |
| 110 | + ["font/woff"] = "woff", |
| 111 | + ["font/woff2"] = "woff2", |
| 112 | + ["application/xhtml+xml"] = "xhtml", |
| 113 | + ["application/vnd.ms-excel"] = "xls", |
| 114 | + ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"] = "xlsx", |
| 115 | + -- `application/xml` is recommended but `text/xml` is still commonly used. |
| 116 | + -- The specific MIME types used depends on the content semantics. |
| 117 | + ["application/xml"] = "xml", |
| 118 | + ["text/xml"] = "xml", |
| 119 | + ["application/vnd.mozilla.xul+xml"] = "xul", |
| 120 | + ["application/zip"] = "zip", |
| 121 | + -- Windows use this non-standard MIME type for `.zip` files. |
| 122 | + ["application/x-zip-compressed"] = "zip", |
| 123 | + ["video/3gpp"] = "3gp", |
| 124 | + -- `audio/3gpp` if it doesn't contain video |
| 125 | + ["audio/3gpp"] = "3gp", |
| 126 | + ["video/3gpp2"] = "3g2", |
| 127 | + -- `audio/3gpp2` if it doesn't contain video |
| 128 | + ["audo/3gpp2"] = "3g2", |
| 129 | + ["application/x-7z-compressed"] = "7z", |
| 130 | +} |
| 131 | + |
| 132 | +return M |
0 commit comments