69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import type { ViewerKind } from "./types.ts";
|
|
|
|
/** Kind classification only; MIME ownership remains with uploader. */
|
|
export const extensions: Record<ViewerKind, readonly string[]> = {
|
|
image: ["jpg", "jpeg", "png", "gif", "webp", "bmp", "ico", "avif"],
|
|
vector: ["svg"],
|
|
pdf: ["pdf"],
|
|
code: [
|
|
"js",
|
|
"jsx",
|
|
"ts",
|
|
"tsx",
|
|
"py",
|
|
"java",
|
|
"cpp",
|
|
"c",
|
|
"h",
|
|
"cs",
|
|
"css",
|
|
"json",
|
|
"xml",
|
|
"sql",
|
|
"sh",
|
|
"yaml",
|
|
"yml",
|
|
],
|
|
text: ["txt", "md", "log"],
|
|
markup: ["html", "htm"],
|
|
sheet: ["csv", "tsv", "xls", "xlsx", "ods"],
|
|
doc: ["doc", "docx", "dotx", "odt", "rtf", "ppt", "pptx", "ppsx", "potx", "odp"],
|
|
audio: ["mp3", "wav", "aac", "flac", "ogg"],
|
|
video: ["mp4", "webm", "mov", "avi", "mkv"],
|
|
archive: ["zip", "rar", "7z", "tar", "gz", "tgz"],
|
|
binary: ["psd", "ai", "tif", "tiff", "exe", "dll"],
|
|
};
|
|
|
|
export function extensionOf(name: string): string {
|
|
const base = (name.split(/[?#]/)[0] ?? "").split(/[/\\]/).pop() ?? "";
|
|
const dot = base.lastIndexOf(".");
|
|
return dot < 0 ? "" : base.slice(dot).toLowerCase();
|
|
}
|
|
|
|
export function kindOfExtension(ext: string): ViewerKind {
|
|
return (
|
|
(Object.keys(extensions) as ViewerKind[]).find((kind) =>
|
|
extensions[kind].includes(ext.replace(/^\./, "").toLowerCase()),
|
|
) ?? "binary"
|
|
);
|
|
}
|
|
|
|
export function kindOfMime(mime: string): ViewerKind | undefined {
|
|
const type = mime.split(";")[0]!.trim().toLowerCase();
|
|
if (type === "image/svg+xml") return "vector";
|
|
if (type === "text/html" || type === "application/xhtml+xml") return "markup";
|
|
if (type === "application/pdf") return "pdf";
|
|
if (/^(application|text)\/(json|xml|javascript|x-javascript)$/.test(type) || type === "text/css")
|
|
return "code";
|
|
if (/^text\/(csv|tab-separated-values)$/.test(type) || /spreadsheet|ms-excel/.test(type))
|
|
return "sheet";
|
|
if (/opendocument\.spreadsheet/.test(type)) return "sheet";
|
|
if (/msword|wordprocessing|presentation|powerpoint|opendocument|rtf/.test(type)) return "doc";
|
|
if (/zip|gzip|x-tar|x-7z|rar/.test(type)) return "archive";
|
|
if (/^image\/(png|jpeg|gif|webp|bmp|x-icon|vnd.microsoft.icon|avif)$/.test(type)) return "image";
|
|
if (type.startsWith("audio/")) return "audio";
|
|
if (type.startsWith("video/")) return "video";
|
|
if (type.startsWith("text/")) return "text";
|
|
return undefined;
|
|
}
|