Download frontend/src/projectFiles.ts from SevdanurGenc/LLM-Automated-Test-Generation-Agent: direct link, hf CLI and curl.
- Browser
- Download file 5.08 kB
-
https://huggingface.co/SevdanurGenc/LLM-Automated-Test-Generation-Agent/resolve/main/frontend/src/projectFiles.ts
- Command line
-
hf download hf://SevdanurGenc/LLM-Automated-Test-Generation-Agent/frontend/src/projectFiles.ts
-
curl -L -o projectFiles.ts https://huggingface.co/SevdanurGenc/LLM-Automated-Test-Generation-Agent/resolve/main/frontend/src/projectFiles.ts
5.08 kB
| import { unzipSync, strFromU8 } from 'fflate'; | |
| import type { Language } from './types'; | |
| /** Çok dosyalı girdi: seçilen dosyaları ve zip arşivlerini okur, test edilecek dosyayı ve yardımcıları ayırır. */ | |
| export const EXT_LANG: Record<string, Language | 'html'> = { | |
| py: 'python', js: 'javascript', mjs: 'javascript', cjs: 'javascript', jsx: 'javascript', | |
| ts: 'typescript', tsx: 'typescript', java: 'java', html: 'html', htm: 'html', | |
| }; | |
| /** Test edilmez ama kodun okuyabilmesi için yanına konur */ | |
| const DATA_EXT = new Set(['json', 'txt', 'csv', 'css', 'xml', 'yaml', 'yml', 'properties', 'md']); | |
| const SKIP_DIR = /(^|\/)(node_modules|__pycache__|\.git|\.venv|venv|dist|build|target|out|\.idea|\.vscode)\//; | |
| export const ACCEPT = [...Object.keys(EXT_LANG), 'zip', ...DATA_EXT].map((e) => '.' + e).join(','); | |
| export const MAX_FILE = 200_000; | |
| export const MAX_TOTAL = 600_000; | |
| export const MAX_EXTRA = 30; | |
| export const extOf = (name: string) => (name.split('.').pop() || '').toLowerCase(); | |
| export const baseName = (p: string) => p.split('/').pop() || p; | |
| export const isTestFile = (p: string) => | |
| /(^|\/)(tests?|__tests__|spec)\//i.test(p) | |
| || /(^|\/)(test_[^/]*\.py|[^/]*_test\.py|[^/]*\.(test|spec)\.[jt]sx?|[^/]*Tests?\.java)$/i.test(p); | |
| /** Araç/yapılandırma dosyaları: koşucunun kendi dosyalarıyla çakışır, yardımcı olarak gönderilmez */ | |
| const isToolingFile = (p: string) => | |
| /(^|\/)(package(-lock)?\.json|yarn\.lock|pnpm-lock\.yaml|tsconfig\.json|jest\.config\.[cm]?[jt]s|babel\.config\.[cm]?js|\.babelrc|playwright\.config\.[jt]s|conftest\.py|pytest\.ini|setup\.cfg|tox\.ini|pyproject\.toml|pom\.xml|build\.gradle(\.kts)?|vite\.config\.[jt]s)$/i.test(p); | |
| export interface InFile { path: string; text: string } | |
| export interface ReadResult { files: InFile[]; skipped: string[]; tooBig: string[] } | |
| /** Dosyaları ve zip'leri okur; ikili/çok büyük/desteklenmeyen dosyaları ayıklar. */ | |
| export async function readInputs(list: FileList | File[]): Promise<ReadResult> { | |
| const files: InFile[] = []; | |
| const skipped: string[] = []; | |
| const tooBig: string[] = []; | |
| const add = (path: string, bytes: Uint8Array | string) => { | |
| const ext = extOf(path); | |
| if (SKIP_DIR.test(path + '/') || SKIP_DIR.test(path)) return; | |
| if (!EXT_LANG[ext] && !DATA_EXT.has(ext)) { skipped.push(path); return; } | |
| if (isToolingFile(path)) { skipped.push(path); return; } | |
| const size = typeof bytes === 'string' ? bytes.length : bytes.length; | |
| if (size > MAX_FILE) { (EXT_LANG[ext] ? tooBig : skipped).push(path); return; } | |
| const text = typeof bytes === 'string' ? bytes : strFromU8(bytes); | |
| if (text.includes('\u0000')) { skipped.push(path); return; } | |
| files.push({ path: path.replace(/\\/g, '/').replace(/^\.\//, ''), text }); | |
| }; | |
| for (const f of [...list]) { | |
| if (extOf(f.name) === 'zip') { | |
| const entries = unzipSync(new Uint8Array(await f.arrayBuffer())); | |
| for (const [p, data] of Object.entries(entries)) if (!p.endsWith('/')) add(p, data); | |
| } else { | |
| const rel = (f as File & { webkitRelativePath?: string }).webkitRelativePath || f.name; | |
| add(rel, await f.text()); | |
| } | |
| } | |
| // zip'teki ortak üst klasörü kaldır (proje/ src/a.py → src/a.py) | |
| const parts = files.map((f) => f.path.split('/')); | |
| while (parts.length && parts.every((p) => p.length > 1 && p[0] === parts[0][0])) parts.forEach((p) => p.shift()); | |
| files.forEach((f, i) => { f.path = parts[i].join('/'); }); | |
| return { files, skipped, tooBig }; | |
| } | |
| export const langOf = (path: string) => EXT_LANG[extOf(path)]; | |
| /** Varsayılan hedef: test dosyası olmayan, en uzun kaynak dosyası (çoğunlukla asıl modül). */ | |
| export function pickTarget(files: InFile[]): string | null { | |
| const code = files.filter((f) => { const l = langOf(f.path); return l && l !== 'html' && !isTestFile(f.path); }); | |
| const pool = code.length ? code : files.filter((f) => langOf(f.path) && langOf(f.path) !== 'html'); | |
| if (!pool.length) return null; | |
| return [...pool].sort((a, b) => b.text.length - a.text.length)[0].path; | |
| } | |
| /** Hedefe göre yardımcı dosyalar: aynı dil ailesindeki kaynaklar + veri dosyaları; yollar hedefin klasörüne göre. */ | |
| export function helpersFor(files: InFile[], target: string): { extra: Record<string, string>; ignored: string[] } { | |
| const tl = langOf(target); | |
| const family = (l: string | undefined) => (l === 'typescript' || l === 'javascript' ? 'js' : l); | |
| const dir = target.includes('/') ? target.slice(0, target.lastIndexOf('/') + 1) : ''; | |
| const extra: Record<string, string> = {}; | |
| const ignored: string[] = []; | |
| for (const f of files) { | |
| if (f.path === target) continue; | |
| const l = langOf(f.path); | |
| const ok = !l ? DATA_EXT.has(extOf(f.path)) : family(l) === family(tl) || (l === 'html' && tl === 'javascript'); | |
| if (!ok || isTestFile(f.path)) { ignored.push(f.path); continue; } | |
| const rel = dir && f.path.startsWith(dir) ? f.path.slice(dir.length) : f.path; | |
| if (Object.keys(extra).length < MAX_EXTRA) extra[rel] = f.text; else ignored.push(f.path); | |
| } | |
| return { extra, ignored }; | |
| } | |