* List files using filesystem walk (fallback)
({
dir,
matchDirs,
maxDepth = 10,
maxFiles = 10000,
}: {
dir: string
matchDirs: boolean
maxDepth?: number
maxFiles?: number
})
| 273 | * List files using filesystem walk (fallback) |
| 274 | */ |
| 275 | function listFilesWithFs({ |
| 276 | dir, |
| 277 | matchDirs, |
| 278 | maxDepth = 10, |
| 279 | maxFiles = 10000, |
| 280 | }: { |
| 281 | dir: string |
| 282 | matchDirs: boolean |
| 283 | maxDepth?: number |
| 284 | maxFiles?: number |
| 285 | }): string[] { |
| 286 | const files: string[] = [] |
| 287 | const dirs: Set<string> = new Set() |
| 288 | |
| 289 | function walk(currentDir: string, depth: number, relativeBase: string): void { |
| 290 | if (depth > maxDepth || files.length >= maxFiles) return |
| 291 | |
| 292 | let entries: fs.Dirent[] |
| 293 | try { |
| 294 | entries = fs.readdirSync(currentDir, { withFileTypes: true }) |
| 295 | } catch (err) { |
| 296 | logger.debug('[Files] Error reading directory:', err) |
| 297 | return |
| 298 | } |
| 299 | |
| 300 | for (const entry of entries) { |
| 301 | if (files.length >= maxFiles) break |
| 302 | |
| 303 | // Skip common ignores |
| 304 | if ( |
| 305 | entry.name.startsWith(".") || |
| 306 | entry.name === "node_modules" || |
| 307 | entry.name === "__pycache__" || |
| 308 | entry.name === "dist" || |
| 309 | entry.name === "build" || |
| 310 | entry.name === "vendor" |
| 311 | ) { |
| 312 | continue |
| 313 | } |
| 314 | |
| 315 | const relativePath = relativeBase ? path.join(relativeBase, entry.name) : entry.name |
| 316 | |
| 317 | if (entry.isDirectory()) { |
| 318 | dirs.add(relativePath) |
| 319 | walk(path.join(currentDir, entry.name), depth + 1, relativePath) |
| 320 | } else if (entry.isFile()) { |
| 321 | files.push(relativePath) |
| 322 | } |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | walk(dir, 0, "") |
| 327 | |
| 328 | if (matchDirs) { |
| 329 | return Array.from(dirs).sort() |
| 330 | } |
| 331 | |
| 332 | return files |