UNPKG

filetree-pro

Version:

A powerful file tree generator for VS Code and Cursor. Generate beautiful file trees in multiple formats with smart exclusions and custom configurations.

287 lines (263 loc) 7.73 kB
import { filesize } from 'filesize'; import moment from 'moment'; import * as path from 'path'; import { FileTypeInfo } from '../types'; export function getFileTypeInfo(filename: string): FileTypeInfo { const ext = path.extname(filename).toLowerCase(); const name = path.basename(filename).toLowerCase(); // Code files if (['.js', '.ts', '.jsx', '.tsx', '.vue', '.svelte'].includes(ext)) { return { type: 'code', icon: '📄', color: '#f7df1e', extensions: ['.js', '.ts', '.jsx', '.tsx'], }; } if (['.py', '.pyc', '.pyo'].includes(ext)) { return { type: 'code', icon: '🐍', color: '#3776ab', extensions: ['.py', '.pyc', '.pyo'] }; } if (['.java', '.class'].includes(ext)) { return { type: 'code', icon: '☕', color: '#007396', extensions: ['.java', '.class'] }; } if (['.cpp', '.cc', '.cxx', '.c++', '.hpp', '.h'].includes(ext)) { return { type: 'code', icon: '⚡', color: '#00599c', extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.h'], }; } if (['.go'].includes(ext)) { return { type: 'code', icon: '🐹', color: '#00add8', extensions: ['.go'] }; } if (['.rs'].includes(ext)) { return { type: 'code', icon: '🦀', color: '#ce422b', extensions: ['.rs'] }; } if (['.php'].includes(ext)) { return { type: 'code', icon: '🐘', color: '#777bb4', extensions: ['.php'] }; } if (['.rb'].includes(ext)) { return { type: 'code', icon: '💎', color: '#cc342d', extensions: ['.rb'] }; } if (['.swift'].includes(ext)) { return { type: 'code', icon: '🍎', color: '#ff6b35', extensions: ['.swift'] }; } if (['.kt'].includes(ext)) { return { type: 'code', icon: '☕', color: '#f18e33', extensions: ['.kt'] }; } if (['.scala'].includes(ext)) { return { type: 'code', icon: '☕', color: '#dc322f', extensions: ['.scala'] }; } // Web files if (['.html', '.htm'].includes(ext)) { return { type: 'code', icon: '🌐', color: '#e34c26', extensions: ['.html', '.htm'] }; } if (['.css', '.scss', '.sass', '.less'].includes(ext)) { return { type: 'code', icon: '🎨', color: '#1572b6', extensions: ['.css', '.scss', '.sass', '.less'], }; } if (['.json', '.xml', '.yaml', '.yml', '.toml'].includes(ext)) { return { type: 'config', icon: '⚙️', color: '#f7df1e', extensions: ['.json', '.xml', '.yaml', '.yml', '.toml'], }; } // Config files if (['.env', '.config', '.conf', '.ini'].includes(ext) || name.startsWith('.')) { return { type: 'config', icon: '⚙️', color: '#6c757d', extensions: ['.env', '.config', '.conf', '.ini'], }; } if (['.gitignore', '.gitattributes', '.gitmodules'].includes(name)) { return { type: 'config', icon: '📁', color: '#f05032', extensions: ['.gitignore', '.gitattributes'], }; } if (['package.json', 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml'].includes(name)) { return { type: 'config', icon: '📦', color: '#cb3837', extensions: ['package.json', 'yarn.lock'], }; } if (['dockerfile', '.dockerignore', 'Dockerfile'].includes(name)) { return { type: 'config', icon: '🐳', color: '#2496ed', extensions: ['dockerfile', '.dockerignore', 'Dockerfile'], }; } // Document files if (['.md', '.markdown'].includes(ext)) { return { type: 'document', icon: '📝', color: '#000000', extensions: ['.md', '.markdown'] }; } if (['.txt', '.rtf'].includes(ext)) { return { type: 'document', icon: '📄', color: '#6c757d', extensions: ['.txt', '.rtf'] }; } if (['.pdf'].includes(ext)) { return { type: 'document', icon: '📕', color: '#ff0000', extensions: ['.pdf'] }; } if (['.doc', '.docx'].includes(ext)) { return { type: 'document', icon: '📘', color: '#2b579a', extensions: ['.doc', '.docx'] }; } // Image files if (['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'].includes(ext)) { return { type: 'image', icon: '🖼️', color: '#ff6b6b', extensions: ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'], }; } // Video files if (['.mp4', '.avi', '.mov', '.wmv', '.flv', '.webm'].includes(ext)) { return { type: 'video', icon: '🎬', color: '#ff6b6b', extensions: ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.webm'], }; } // Audio files if (['.mp3', '.wav', '.flac', '.aac', '.ogg'].includes(ext)) { return { type: 'audio', icon: '🎵', color: '#ff6b6b', extensions: ['.mp3', '.wav', '.flac', '.aac', '.ogg'], }; } // Archive files if (['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2'].includes(ext)) { return { type: 'archive', icon: '📦', color: '#ffa500', extensions: ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2'], }; } // Binary files if (['.exe', '.dll', '.so', '.dylib', '.bin'].includes(ext)) { return { type: 'binary', icon: '⚙️', color: '#6c757d', extensions: ['.exe', '.dll', '.so', '.dylib', '.bin'], }; } // Default for unknown files return { type: 'unknown', icon: '📄', color: '#6c757d', extensions: [] }; } export function formatFileSize(bytes: number): string { return filesize(bytes, { base: 2 }); } export function formatDate(date: Date): string { return moment(date).format('MMM DD, YYYY HH:mm'); } export function formatRelativeDate(date: Date): string { return moment(date).fromNow(); } export function getFileExtension(filename: string): string { const ext = path.extname(filename).toLowerCase(); // Handle hidden files that start with a dot if (filename.startsWith('.') && !ext) { return filename; } return ext; } export function isTextFile(filename: string): boolean { const textExtensions = [ '.txt', '.md', '.markdown', '.json', '.xml', '.yaml', '.yml', '.toml', '.ini', '.cfg', '.conf', '.js', '.ts', '.jsx', '.tsx', '.vue', '.svelte', '.py', '.java', '.cpp', '.cc', '.cxx', '.hpp', '.h', '.go', '.rs', '.php', '.rb', '.swift', '.kt', '.scala', '.html', '.htm', '.css', '.scss', '.sass', '.less', '.sql', '.sh', '.bash', '.zsh', '.fish', '.ps1', '.bat', '.cmd', '.env', '.gitignore', '.gitattributes', '.dockerignore', 'dockerfile', ]; const ext = getFileExtension(filename).toLowerCase(); return textExtensions.includes(ext); } export function getFileIcon(filename: string): string { const fileTypeInfo = getFileTypeInfo(filename); return fileTypeInfo.icon; } export function getFileColor(filename: string): string { const fileTypeInfo = getFileTypeInfo(filename); return fileTypeInfo.color || '#6c757d'; } export function sanitizeFileName(filename: string): string { return filename.replace(/[<>:"/\\|?*]/g, '_'); } export function isHiddenFile(filename: string): boolean { return filename.startsWith('.') || filename.includes('~'); } export function getDisplayName(filename: string): string { // Handle special files - return plain text for tests (case-insensitive) const lowerFilename = filename.toLowerCase(); if (lowerFilename === 'package.json') return 'package.json'; if (lowerFilename === 'readme.md') return 'README.md'; if (lowerFilename === '.gitignore') return '.gitignore'; if (lowerFilename === 'dockerfile') return 'Dockerfile'; if (lowerFilename === '.env') return '.env'; // Return just the filename without path return path.basename(filename); }