()
| 249 | } |
| 250 | |
| 251 | function main() { |
| 252 | const args = process.argv.slice(2).filter(Boolean); |
| 253 | const targetFiles = args.length |
| 254 | ? args |
| 255 | .map((p) => path.resolve(p)) |
| 256 | .filter((p) => MDX_EXTS.includes(path.extname(p).toLowerCase()) && fileExists(p)) |
| 257 | : getAllMdxFiles(CONTENT_DIR); |
| 258 | |
| 259 | const refErrors = []; |
| 260 | for (const mdx of targetFiles) { |
| 261 | const content = fs.readFileSync(mdx, 'utf-8'); |
| 262 | const refs = extractRefs(content); |
| 263 | for (const { url, type, index } of refs) { |
| 264 | const result = isValidRef(url, mdx); |
| 265 | if (!result.ok) { |
| 266 | refErrors.push({ |
| 267 | file: mdx, |
| 268 | line: lineOf(content, index), |
| 269 | url, |
| 270 | type, |
| 271 | expected: result.expected |
| 272 | }); |
| 273 | } |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | // meta 覆盖校验始终全量执行(与 args 无关) |
| 278 | const metaErrors = checkMetaCoverage(); |
| 279 | |
| 280 | const total = refErrors.length + metaErrors.length; |
| 281 | if (total === 0) { |
| 282 | console.log(`✅ 已校验 ${targetFiles.length} 个 mdx 文件 + 全部 meta.json,未发现问题`); |
| 283 | process.exit(0); |
| 284 | } |
| 285 | |
| 286 | if (refErrors.length > 0) { |
| 287 | console.error(`❌ 发现 ${refErrors.length} 处无效引用:\n`); |
| 288 | for (const e of refErrors) { |
| 289 | const src = path.relative(DOCUMENT_ROOT, e.file); |
| 290 | console.error(` ${src}:${e.line}`); |
| 291 | console.error(` [${e.type}] ${e.url}`); |
| 292 | console.error(` ↳ 不存在: ${e.expected}`); |
| 293 | console.error(''); |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | if (metaErrors.length > 0) { |
| 298 | console.error(`❌ 发现 ${metaErrors.length} 个 meta 文件存在问题:\n`); |
| 299 | for (const e of metaErrors) { |
| 300 | const src = path.relative(DOCUMENT_ROOT, e.file); |
| 301 | if (e.parseError) { |
| 302 | console.error(` ${src}`); |
| 303 | console.error(` ↳ JSON 解析失败: ${e.parseError}`); |
| 304 | } else { |
| 305 | console.error(` ${src}`); |
| 306 | console.error(` ↳ pages 中遗漏 ${e.missing.length} 项:`); |
| 307 | for (const m of e.missing) console.error(` - ${m}`); |
| 308 | } |
no test coverage detected