-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvisualize.ts
More file actions
47 lines (44 loc) · 1.79 KB
/
Copy pathvisualize.ts
File metadata and controls
47 lines (44 loc) · 1.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* Verify a set of concept files and render an offline HTML report.
*/
import { readFileSync, readdirSync, statSync } from "node:fs";
import { join, relative, basename } from "node:path";
import { verifyConcept, type VerifyOptions } from "@verifiable-okf/verifier";
import { splitConcept, parseFrontmatter } from "@verifiable-okf/canon";
import { renderReport, type ReportItem } from "./render.js";
/** Recursively collect `.md` concept files under a path (or the file itself). */
export function collectConcepts(path: string): string[] {
const st = statSync(path);
if (st.isFile()) return path.endsWith(".md") ? [path] : [];
const out: string[] = [];
for (const entry of readdirSync(path)) {
out.push(...collectConcepts(join(path, entry)));
}
return out.sort();
}
function declaredContentHash(raw: Uint8Array): string | undefined {
const { hasFrontmatter, frontmatterText } = splitConcept(raw);
if (!hasFrontmatter) return undefined;
const prov = parseFrontmatter(frontmatterText)["provenance"];
const ch = prov && typeof prov === "object" ? (prov as Record<string, unknown>)["content_hash"] : undefined;
return typeof ch === "string" ? ch : undefined;
}
/** Verify every concept under `path` and return the report items + HTML. */
export async function visualize(
path: string,
opts: VerifyOptions = {},
): Promise<{ items: ReportItem[]; html: string }> {
const files = collectConcepts(path);
const root = statSync(path).isDirectory() ? path : "";
const items: ReportItem[] = [];
for (const file of files) {
const raw = readFileSync(file);
const result = await verifyConcept(raw, opts);
items.push({
id: root ? relative(root, file) : basename(file),
result,
contentHash: declaredContentHash(raw),
});
}
return { items, html: renderReport(items) };
}