Files
2026-08-24 09:35:03 -05:00

136 lines
4.3 KiB
JavaScript

export function getFileExt(name = "") {
const idx = name.lastIndexOf(".");
if (idx < 0 || idx === name.length - 1) return "";
return name.slice(idx + 1).toLowerCase();
}
export const PREVIEW_IMAGE_EXTS = new Set(["jpg", "jpeg", "png", "gif", "webp", "bmp"]);
export const PREVIEW_PDF_EXTS = new Set(["pdf"]);
export const PREVIEW_MAX_BYTES = 50 * 1024 * 1024;
const HIGHLIGHT_FILENAME_MAP = {
dockerfile: "dockerfile",
makefile: "makefile",
gnumakefile: "makefile",
"nginx.conf": "nginx",
".env": "bash",
};
const HIGHLIGHT_EXTENSION_MAP = {
js: "javascript", mjs: "javascript", cjs: "javascript", jsx: "javascript",
ts: "typescript", mts: "typescript", cts: "typescript", tsx: "typescript",
py: "python", pyw: "python", rb: "ruby", java: "java",
cpp: "cpp", cxx: "cpp", cc: "cpp", hpp: "cpp", hxx: "cpp",
c: "c", h: "c", cs: "csharp", php: "php", phtml: "php",
go: "go", rs: "rust",
sh: "bash", bash: "bash", zsh: "bash", ksh: "bash",
bat: "powershell", cmd: "powershell", ps1: "powershell", psm1: "powershell", psd1: "powershell",
json: "json", jsonc: "json", json5: "json",
xml: "xml", svg: "xml", xsl: "xml", xslt: "xml", plist: "xml",
html: "xml", htm: "xml", xhtml: "xml", vue: "xml", svelte: "xml",
css: "css", scss: "scss", sass: "scss", sql: "sql",
yaml: "yaml", yml: "yaml", md: "markdown", markdown: "markdown",
ini: "ini", cfg: "ini", properties: "ini", toml: "ini",
diff: "diff", patch: "diff", dockerfile: "dockerfile", makefile: "makefile", nginx: "nginx",
};
export function getHighlightLanguage(name = "") {
const fileName = name.split(/[\\/]/).pop()?.toLowerCase() || "";
if (HIGHLIGHT_FILENAME_MAP[fileName]) return HIGHLIGHT_FILENAME_MAP[fileName];
if (fileName.startsWith("dockerfile.")) return "dockerfile";
if (fileName.startsWith(".env.")) return "bash";
return HIGHLIGHT_EXTENSION_MAP[getFileExt(fileName)] || "plaintext";
}
export const KNOWN_BINARY_EXTS = new Set([
"mp4", "avi", "mkv", "mov", "wmv", "flv", "webm", "m4v",
"mp3", "wav", "flac", "ogg", "aac", "wma", "m4a",
"exe", "msi", "com", "app", "appimage",
"dll", "so", "dylib", "lib",
"zip", "rar", "7z", "tar", "gz", "bz2", "xz", "tgz",
"db", "sqlite", "sqlite3", "mdb",
"ttf", "otf", "woff", "woff2", "eot",
"iso", "img", "vhd", "vmdk",
]);
const IMAGE_MIME_MAP = {
jpg: "image/jpeg",
jpeg: "image/jpeg",
png: "image/png",
gif: "image/gif",
webp: "image/webp",
bmp: "image/bmp",
};
export function isPreviewable(name) {
const ext = getFileExt(name);
return PREVIEW_IMAGE_EXTS.has(ext) || PREVIEW_PDF_EXTS.has(ext);
}
export function getPreviewMimeType(name) {
const ext = getFileExt(name);
if (PREVIEW_PDF_EXTS.has(ext)) return "application/pdf";
return IMAGE_MIME_MAP[ext] || null;
}
export function shouldShowParentDirectory(path) {
if (!path || path === ".") {
return false;
}
return true;
}
export function getParentPath(path) {
const normalized = path.replace(/\\/g, "/");
const parts = normalized.split("/").filter((p) => p);
if (parts.length === 1 && parts[0].match(/^[A-Za-z]:$/)) {
return ".";
}
if (parts.length <= 1) {
return ".";
}
parts.pop();
let parentPath = parts.join("/");
if (parentPath.match(/^[A-Za-z]:?$/)) {
return parentPath.replace(/^([A-Za-z]):?$/, "$1:\\");
}
return parentPath || ".";
}
export function joinRemotePath(directory, fileName) {
if (!directory || directory === ".") return fileName;
if (/[\\/]$/.test(directory)) return `${directory}${fileName}`;
const separator = directory.includes("\\") && !directory.includes("/") ? "\\" : "/";
return `${directory}${separator}${fileName}`;
}
export function formatBytes(bytes) {
if (bytes === 0 || bytes === 0n) return "0 B";
const sizes = ["B", "KB", "MB", "GB", "TB"];
if (typeof bytes === "bigint") {
const k = 1024n;
let i = 0;
let value = bytes;
while (value >= k && i < sizes.length - 1) {
value /= k;
i += 1;
}
return `${value.toString()} ${sizes[i]}`;
}
const k = 1024;
const i = Math.floor(Math.log(bytes) / Math.log(k));
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + " " + sizes[i];
}
export function escapeHtml(text) {
const div = document.createElement("div");
div.textContent = text;
return div.innerHTML.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}