(coreDir = CORE_SRC)
| 190 | * @returns {{ success: boolean; violations: Violation[]; output: string }} |
| 191 | */ |
| 192 | export function checkCorePortability(coreDir = CORE_SRC) { |
| 193 | const files = collectTsFiles(coreDir); |
| 194 | /** @type {Violation[]} */ |
| 195 | const allViolations = []; |
| 196 | |
| 197 | for (const file of files) { |
| 198 | const violations = checkFile(file); |
| 199 | allViolations.push(...violations); |
| 200 | } |
| 201 | |
| 202 | if (allViolations.length === 0) { |
| 203 | return { |
| 204 | success: true, |
| 205 | violations: [], |
| 206 | output: "check-core-portability: OK (no forbidden patterns found)\n", |
| 207 | }; |
| 208 | } |
| 209 | |
| 210 | // Sort by file, then line, then column for deterministic output |
| 211 | allViolations.sort((a, b) => { |
| 212 | if (a.file !== b.file) return a.file.localeCompare(b.file); |
| 213 | if (a.line !== b.line) return a.line - b.line; |
| 214 | return a.col - b.col; |
| 215 | }); |
| 216 | |
| 217 | const first = allViolations[0]; |
| 218 | const relPath = relative(ROOT, first.file); |
| 219 | const outputLines = [ |
| 220 | "check-core-portability: FAIL", |
| 221 | "", |
| 222 | `Found ${allViolations.length} forbidden pattern(s) in @rezi-ui/core:`, |
| 223 | "", |
| 224 | ]; |
| 225 | |
| 226 | for (const v of allViolations) { |
| 227 | const rel = relative(ROOT, v.file); |
| 228 | outputLines.push(` ${rel}:${v.line}:${v.col} - ${v.pattern}: ${v.match}`); |
| 229 | } |
| 230 | |
| 231 | outputLines.push(""); |
| 232 | outputLines.push(`First violation: ${relPath}:${first.line}:${first.col}`); |
| 233 | outputLines.push(`Pattern: ${first.pattern}`); |
| 234 | outputLines.push(`Match: ${first.match}`); |
| 235 | outputLines.push(""); |
| 236 | |
| 237 | return { |
| 238 | success: false, |
| 239 | violations: allViolations, |
| 240 | output: outputLines.join("\n"), |
| 241 | }; |
| 242 | } |
| 243 | |
| 244 | // Run as CLI if executed directly |
| 245 | const isMain = |
no test coverage detected