| 116 | } |
| 117 | |
| 118 | function collectFiles(target, extensions, out) { |
| 119 | const stat = fs.statSync(target, { throwIfNoEntry: false }); |
| 120 | if (!stat) { |
| 121 | console.error(`Not found: ${target}`); |
| 122 | return; |
| 123 | } |
| 124 | if (stat.isFile()) { |
| 125 | out.push(target); |
| 126 | return; |
| 127 | } |
| 128 | if (!stat.isDirectory()) return; |
| 129 | |
| 130 | for (const entry of fs.readdirSync(target, { withFileTypes: true })) { |
| 131 | if (entry.isDirectory()) { |
| 132 | if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.')) continue; |
| 133 | collectFiles(path.join(target, entry.name), extensions, out); |
| 134 | } else if (extensions.has(path.extname(entry.name))) { |
| 135 | out.push(path.join(target, entry.name)); |
| 136 | } |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | function validateFile(filePath, extensions, attrPattern, scriptPattern) { |
| 141 | const content = fs.readFileSync(filePath, 'utf-8'); |