UNPKG

@ry-krystal/kicad-converter

Version:

专业的KiCad符号文件与JSON互转工具

342 lines (341 loc) 8.66 kB
/** * 通用工具函数模块 * 提供文件操作、路径处理、配置管理等功能 */ import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, readdirSync } from 'fs'; import { join, dirname, extname, basename } from 'path'; /** * 文件工具类 */ export class FileUtils { /** * 安全读取文件 */ static readFile(filePath, encoding = 'utf8') { try { if (!existsSync(filePath)) { return null; } return readFileSync(filePath, encoding); } catch { return null; } } /** * 安全写入文件 */ static writeFile(filePath, content, encoding = 'utf8') { try { // 确保目录存在 const dir = dirname(filePath); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } writeFileSync(filePath, content, encoding); return true; } catch { return false; } } /** * 检查文件是否存在 */ static exists(filePath) { return existsSync(filePath); } /** * 获取文件信息 */ static getFileInfo(filePath) { try { const stats = statSync(filePath); return { size: stats.size, isFile: stats.isFile(), isDirectory: stats.isDirectory() }; } catch { return null; } } /** * 递归查找文件 */ static findFiles(dir, extensions, recursive = false) { const results = []; if (!existsSync(dir)) { return results; } try { const items = readdirSync(dir); for (const item of items) { const fullPath = join(dir, item); const stat = statSync(fullPath); if (stat.isDirectory() && recursive) { results.push(...this.findFiles(fullPath, extensions, recursive)); } else if (stat.isFile()) { const ext = extname(item).toLowerCase(); if (extensions.includes(ext)) { results.push(fullPath); } } } } catch { // 忽略错误,返回已找到的文件 } return results; } } /** * 路径工具类 */ export class PathUtils { /** * 标准化路径分隔符 */ static normalize(path) { return path.replace(/\\/g, '/'); } /** * 获取文件扩展名 */ static getExtension(filePath) { return extname(filePath).toLowerCase(); } /** * 获取文件名(不含扩展名) */ static getNameWithoutExt(filePath) { return basename(filePath, extname(filePath)); } /** * 更改文件扩展名 */ static changeExtension(filePath, newExt) { const dir = dirname(filePath); const name = this.getNameWithoutExt(filePath); const ext = newExt.startsWith('.') ? newExt : `.${newExt}`; return join(dir, `${name}${ext}`); } /** * 生成安全的文件名 */ static sanitizeFilename(filename) { return filename.replace(/[<>:"/\\|?*]/g, '_').replace(/\s+/g, '_'); } /** * 确保目录存在 */ static ensureDir(dirPath) { try { if (!existsSync(dirPath)) { mkdirSync(dirPath, { recursive: true }); } return true; } catch { return false; } } } /** * 配置管理类 */ export class ConfigManager { static configCache = new Map(); /** * 加载配置文件 */ static loadConfig(configPath, defaultConfig = {}) { if (this.configCache.has(configPath)) { return this.configCache.get(configPath); } let config = { ...defaultConfig }; if (existsSync(configPath)) { try { const content = readFileSync(configPath, 'utf8'); const loadedConfig = JSON.parse(content); config = { ...config, ...loadedConfig }; } catch (error) { console.warn(`配置文件加载失败: ${configPath}`, error); } } this.configCache.set(configPath, config); return config; } /** * 保存配置文件 */ static saveConfig(configPath, config) { try { const dir = dirname(configPath); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } const content = JSON.stringify(config, null, 2); writeFileSync(configPath, content, 'utf8'); // 更新缓存 this.configCache.set(configPath, config); return true; } catch { return false; } } /** * 清理配置缓存 */ static clearCache(configPath) { if (configPath) { this.configCache.delete(configPath); } else { this.configCache.clear(); } } } /** * 日志工具类 */ export class Logger { verbose; quiet; constructor(verbose = false, quiet = false) { this.verbose = verbose; this.quiet = quiet; } info(message) { if (!this.quiet) { console.log(`ℹ️ ${message}`); } } success(message) { if (!this.quiet) { console.log(`✅ ${message}`); } } warn(message) { if (!this.quiet) { console.warn(`⚠️ ${message}`); } } error(message) { console.error(`❌ ${message}`); } debug(message) { if (this.verbose && !this.quiet) { console.log(`🔍 ${message}`); } } verboseLog(message) { if (this.verbose && !this.quiet) { console.log(`📝 ${message}`); } } } /** * 性能计时器 */ export class Timer { startTime; marks = new Map(); constructor() { this.startTime = performance.now(); } /** * 设置时间标记 */ mark(name) { this.marks.set(name, performance.now()); } /** * 获取从开始到现在的时间 */ elapsed() { return performance.now() - this.startTime; } /** * 获取两个标记之间的时间 */ measure(startMark, endMark) { const start = this.marks.get(startMark); if (!start) return 0; const end = endMark ? this.marks.get(endMark) : performance.now(); if (!end) return 0; return end - start; } /** * 格式化时间显示 */ static formatTime(ms) { if (ms < 1000) { return `${ms.toFixed(2)}ms`; } else if (ms < 60000) { return `${(ms / 1000).toFixed(2)}s`; } else { const minutes = Math.floor(ms / 60000); const seconds = ((ms % 60000) / 1000).toFixed(2); return `${minutes}m ${seconds}s`; } } } /** * 数据验证工具 */ export class Validator { /** * 验证文件路径 */ static validatePath(path, shouldExist = true) { if (!path || typeof path !== 'string') { return { valid: false, message: '路径不能为空' }; } if (shouldExist && !existsSync(path)) { return { valid: false, message: `文件或目录不存在: ${path}` }; } return { valid: true }; } /** * 验证文件扩展名 */ static validateExtension(filename, validExtensions) { const ext = extname(filename).toLowerCase(); return validExtensions.includes(ext); } /** * 验证JSON格式 */ static validateJson(content) { try { const data = JSON.parse(content); return { valid: true, data }; } catch (error) { return { valid: false, error: error instanceof Error ? error.message : 'JSON格式错误' }; } } } // 导出便捷函数 export const fileUtils = FileUtils; export const pathUtils = PathUtils; export const configManager = ConfigManager; // 创建默认实例 export function createLogger(verbose = false, quiet = false) { return new Logger(verbose, quiet); } export function createTimer() { return new Timer(); }