| 46 | } |
| 47 | |
| 48 | function listFiles(root, predicate = () => true, limit = 50) { |
| 49 | if (!fs.existsSync(root)) return []; |
| 50 | const out = []; |
| 51 | const stack = [root]; |
| 52 | while (stack.length && out.length < limit) { |
| 53 | const current = stack.pop(); |
| 54 | for (const entry of fs.readdirSync(current, { withFileTypes: true })) { |
| 55 | const full = path.join(current, entry.name); |
| 56 | if (entry.isDirectory()) stack.push(full); |
| 57 | else if (predicate(full)) out.push(full); |
| 58 | if (out.length >= limit) break; |
| 59 | } |
| 60 | } |
| 61 | return out.sort(); |
| 62 | } |
| 63 | |
| 64 | function source(projectRoot, relativePath, reason) { |
| 65 | return { path: relativePath.replace(/\\/g, '/'), reason }; |