136 lines
4.3 KiB
JavaScript
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, """).replace(/'/g, "'");
|
|
}
|