clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat/141-demo-review-fixes
lofi / tools / doc_lint.ts
doc_lint.ts 1.6K
1import { entrypoints as catalog } from "./entrypoints.ts";23const entrypoints = catalog.map((entry) => entry.file);45const command = new Deno.Command(Deno.execPath(), {6 args: ["doc", "--lint", ...entrypoints],7 stdout: "piped",8 stderr: "piped",9});10const result = await command.output();11const decoder = new TextDecoder();12const diagnostics = `${decoder.decode(result.stdout)}\n${decoder.decode(result.stderr)}`;13const root = `${Deno.cwd()}/`;1415const blocks = diagnostics.split(/(?=^error\[)/m).filter((block) => block.startsWith("error["));16const failures = blocks.filter((block) => {17 const code = block.match(/^error\[([^\]]+)\]/)?.[1];18 const locations = [...block.matchAll(/^\s*-->\s+([^:]+):\d+:\d+$/gm)].map((match) => match[1]);19 if (code === "missing-jsdoc") return locations[0]?.startsWith(`${root}package/`) ?? true;20 if (code === "private-type-ref") {21 // `deno doc` cannot currently redirect npm dependency symbols, so a public22 // Playwright, Preact, or Jazz type is reported as private even though23 // `deno publish` resolves and fast-checks it. Keep local-to-local leaks fatal.24 return locations.slice(1).some((path) => path.startsWith(`${root}package/`));25 }26 return true;27});2829if (failures.length > 0) {30 console.error(failures.join("\n"));31 console.error(`Documentation lint failed with ${failures.length} local diagnostic(s).`);32 Deno.exit(1);33}3435const ignored = blocks.length - failures.length;36console.log(37 `Documentation lint passed for ${entrypoints.length} JSR entrypoints` +38 (ignored > 0 ? ` (${ignored} external type-reference diagnostic(s) ignored).` : "."),39);