From cb2ffb03ccbd68893994c164f3dbfa2d96aa7967 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 1 Feb 2026 01:36:33 +0000 Subject: [PATCH] fix: resolve CI test failures --- app/src/utils/fileUtils.ts | 136 +++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 app/src/utils/fileUtils.ts diff --git a/app/src/utils/fileUtils.ts b/app/src/utils/fileUtils.ts new file mode 100644 index 0000000..3a77687 --- /dev/null +++ b/app/src/utils/fileUtils.ts @@ -0,0 +1,136 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { glob } from 'glob'; +import ignore from 'ignore'; +import yaml from 'js-yaml'; +import toml from 'toml'; + +export function readFileContent(filePath: string): string | null { + try { + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath, 'utf-8'); + } + return null; + } catch { + return null; + } +} + +export function parseJSONFile(filePath: string): T | null { + const content = readFileContent(filePath); + if (!content) return null; + try { + return JSON.parse(content) as T; + } catch { + return null; + } +} + +export function parseYAMLFile(filePath: string): Record | null { + const content = readFileContent(filePath); + if (!content) return null; + try { + return yaml.load(content) as Record; + } catch { + return null; + } +} + +export function parseTOMLFile(filePath: string): Record | null { + const content = readFileContent(filePath); + if (!content) return null; + try { + return toml.parse(content) as Record; + } catch { + return null; + } +} + +export async function globFiles( + patterns: string[], + directory: string, + ignorePatterns: string[] +): Promise { + const ig = ignore().add(ignorePatterns); + + const allFiles: string[] = []; + + for (const pattern of patterns) { + const files = await glob(pattern, { + cwd: directory, + absolute: true, + ignore: ['node_modules/**', 'dist/**', 'build/**', '.git/**'] + }); + + const filtered = files.filter(f => !ig.test(path.relative(directory, f))); + allFiles.push(...filtered); + } + + return [...new Set(allFiles)]; +} + +export function loadGitignorePatterns(directory: string): string[] { + const gitignorePath = path.join(directory, '.gitignore'); + const content = readFileContent(gitignorePath); + + if (!content) return []; + + return content + .split('\n') + .map(line => line.trim()) + .filter(line => line && !line.startsWith('#')); +} + +export function getAllFiles( + directory: string, + maxDepth: number = 10 +): string[] { + const files: string[] = []; + + function traverse(dir: string, depth: number) { + if (depth > maxDepth) return; + + const entries = fs.readdirSync(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + + if (entry.isDirectory()) { + if (!shouldIgnore(entry.name)) { + files.push(fullPath + '/'); + traverse(fullPath, depth + 1); + } + } else if (entry.isFile()) { + files.push(fullPath); + } + } + } + + traverse(directory, 0); + return files; +} + +function shouldIgnore(name: string): boolean { + const ignoreDirs = ['node_modules', '.git', 'dist', 'build', '__pycache__', '.venv', 'venv']; + return ignoreDirs.includes(name); +} + +export function getFileExtension(filePath: string): string { + return path.extname(filePath).toLowerCase(); +} + +export function getFileName(filePath: string): string { + return path.basename(filePath); +} + +export function getDirectoryName(filePath: string): string { + return path.dirname(filePath); +} + +export function isFileExists(filePath: string): boolean { + return fs.existsSync(filePath) && fs.statSync(filePath).isFile(); +} + +export function isDirectoryExists(filePath: string): boolean { + return fs.existsSync(filePath) && fs.statSync(filePath).isDirectory(); +}