verify-doc-refs.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. /**
  2. * Verify root-relative `docs/*.md` tokens in repo-authored TypeScript. The
  3. * textual scan requires the extension, checks matching string literals too,
  4. * and excludes built declarations and vendored source.
  5. */
  6. import { existsSync } from 'node:fs'
  7. import { resolve } from 'node:path'
  8. import { findReferenceViolations, uniqueRepoFiles, type ReferenceViolation as Violation } from './repo-files.ts'
  9. const root = resolve(import.meta.dirname, '..')
  10. /** Repo-authored TypeScript that may cite docs in comments. */
  11. const PATTERNS = ['packages/**/*.ts', 'examples/**/*.ts']
  12. /** Paths excluded from the scan: built output and vendored upstream source. */
  13. const isExcluded = (p: string): boolean =>
  14. p.includes('/lib/') || p.endsWith('.d.ts') || p.startsWith('vendor/')
  15. /** Root-relative Markdown path token, excluding trailing prose. */
  16. const DOC_REF = /\bdocs\/[A-Za-z0-9._/-]+\.md/g
  17. /** Find every broken `docs/….md` reference in one TypeScript file. */
  18. function findViolations(absPath: string): Violation[] {
  19. return findReferenceViolations(root, absPath, DOC_REF, ref => ref, ref => !existsSync(resolve(root, ref)))
  20. }
  21. const files = uniqueRepoFiles(root, PATTERNS, isExcluded)
  22. const all = files.flatMap(file => findViolations(file.abs))
  23. const checked = files.length
  24. if (all.length === 0) {
  25. console.log(`verify-doc-refs: ${checked} file(s) checked, all docs/*.md references resolve.`)
  26. process.exit(0)
  27. }
  28. console.error('verify-doc-refs: broken docs/*.md references found in source comments (target does not exist):')
  29. for (const v of all) {
  30. console.error(` ${v.file}:${v.line} ${v.ref}`)
  31. }
  32. process.exit(1)