@de-otio/bibcheck 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +147 -0
- package/dist/cache/fs-cache.d.ts +55 -0
- package/dist/cache/fs-cache.d.ts.map +1 -0
- package/dist/cache/fs-cache.js +264 -0
- package/dist/cache/fs-cache.js.map +1 -0
- package/dist/canonical.d.ts +29 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +132 -0
- package/dist/canonical.js.map +1 -0
- package/dist/check.d.ts +140 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +646 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +357 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +175 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +180 -0
- package/dist/config.js.map +1 -0
- package/dist/databases/crossref.d.ts +53 -0
- package/dist/databases/crossref.d.ts.map +1 -0
- package/dist/databases/crossref.js +138 -0
- package/dist/databases/crossref.js.map +1 -0
- package/dist/databases/index.d.ts +12 -0
- package/dist/databases/index.d.ts.map +1 -0
- package/dist/databases/index.js +9 -0
- package/dist/databases/index.js.map +1 -0
- package/dist/databases/openalex.d.ts +29 -0
- package/dist/databases/openalex.d.ts.map +1 -0
- package/dist/databases/openalex.js +117 -0
- package/dist/databases/openalex.js.map +1 -0
- package/dist/databases/openlibrary.d.ts +26 -0
- package/dist/databases/openlibrary.d.ts.map +1 -0
- package/dist/databases/openlibrary.js +79 -0
- package/dist/databases/openlibrary.js.map +1 -0
- package/dist/databases/worldcat.d.ts +33 -0
- package/dist/databases/worldcat.d.ts.map +1 -0
- package/dist/databases/worldcat.js +145 -0
- package/dist/databases/worldcat.js.map +1 -0
- package/dist/doctor.d.ts +44 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +386 -0
- package/dist/doctor.js.map +1 -0
- package/dist/existence.d.ts +70 -0
- package/dist/existence.d.ts.map +1 -0
- package/dist/existence.js +308 -0
- package/dist/existence.js.map +1 -0
- package/dist/http.d.ts +97 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +543 -0
- package/dist/http.js.map +1 -0
- package/dist/identifiers.d.ts +44 -0
- package/dist/identifiers.d.ts.map +1 -0
- package/dist/identifiers.js +111 -0
- package/dist/identifiers.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/linkage.d.ts +29 -0
- package/dist/linkage.d.ts.map +1 -0
- package/dist/linkage.js +73 -0
- package/dist/linkage.js.map +1 -0
- package/dist/markdown/blocks.d.ts +19 -0
- package/dist/markdown/blocks.d.ts.map +1 -0
- package/dist/markdown/blocks.js +69 -0
- package/dist/markdown/blocks.js.map +1 -0
- package/dist/markdown/citekeys.d.ts +22 -0
- package/dist/markdown/citekeys.d.ts.map +1 -0
- package/dist/markdown/citekeys.js +100 -0
- package/dist/markdown/citekeys.js.map +1 -0
- package/dist/markdown/glob.d.ts +18 -0
- package/dist/markdown/glob.d.ts.map +1 -0
- package/dist/markdown/glob.js +26 -0
- package/dist/markdown/glob.js.map +1 -0
- package/dist/markdown/prose.d.ts +19 -0
- package/dist/markdown/prose.d.ts.map +1 -0
- package/dist/markdown/prose.js +81 -0
- package/dist/markdown/prose.js.map +1 -0
- package/dist/output/json.d.ts +21 -0
- package/dist/output/json.d.ts.map +1 -0
- package/dist/output/json.js +24 -0
- package/dist/output/json.js.map +1 -0
- package/dist/output/markdown.d.ts +21 -0
- package/dist/output/markdown.d.ts.map +1 -0
- package/dist/output/markdown.js +194 -0
- package/dist/output/markdown.js.map +1 -0
- package/dist/output/sarif.d.ts +31 -0
- package/dist/output/sarif.d.ts.map +1 -0
- package/dist/output/sarif.js +322 -0
- package/dist/output/sarif.js.map +1 -0
- package/dist/output/text.d.ts +27 -0
- package/dist/output/text.d.ts.map +1 -0
- package/dist/output/text.js +212 -0
- package/dist/output/text.js.map +1 -0
- package/dist/phrases/load.d.ts +34 -0
- package/dist/phrases/load.d.ts.map +1 -0
- package/dist/phrases/load.js +148 -0
- package/dist/phrases/load.js.map +1 -0
- package/dist/phrases.d.ts +27 -0
- package/dist/phrases.d.ts.map +1 -0
- package/dist/phrases.js +116 -0
- package/dist/phrases.js.map +1 -0
- package/dist/schema/csl.d.ts +429 -0
- package/dist/schema/csl.d.ts.map +1 -0
- package/dist/schema/csl.js +101 -0
- package/dist/schema/csl.js.map +1 -0
- package/dist/schema/output.d.ts +1116 -0
- package/dist/schema/output.d.ts.map +1 -0
- package/dist/schema/output.js +419 -0
- package/dist/schema/output.js.map +1 -0
- package/dist/suppression.d.ts +106 -0
- package/dist/suppression.d.ts.map +1 -0
- package/dist/suppression.js +134 -0
- package/dist/suppression.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +14 -0
- package/dist/version.js.map +1 -0
- package/dist/worklist.d.ts +32 -0
- package/dist/worklist.d.ts.map +1 -0
- package/dist/worklist.js +211 -0
- package/dist/worklist.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper: extract prose lines from markdown content.
|
|
3
|
+
*
|
|
4
|
+
* Parses the content via remark/unified to an mdast AST and walks the tree,
|
|
5
|
+
* skipping nodes whose content should not be treated as prose (code blocks,
|
|
6
|
+
* inline code, raw HTML, YAML/TOML front-matter). Returns one ProseLine per
|
|
7
|
+
* source line that contains prose, sorted and deduplicated by line number.
|
|
8
|
+
*
|
|
9
|
+
* YAML/TOML front-matter is stripped before AST parsing because remark-parse
|
|
10
|
+
* alone does not emit yaml/toml AST nodes — the remark-frontmatter plugin is
|
|
11
|
+
* required for that. Instead, we detect the standard --- / +++ delimiters
|
|
12
|
+
* manually and record which lines to exclude from the result.
|
|
13
|
+
*/
|
|
14
|
+
import { unified } from 'unified';
|
|
15
|
+
import remarkParse from 'remark-parse';
|
|
16
|
+
const SKIP_TYPES = new Set(['code', 'inlineCode', 'html', 'yaml', 'toml']);
|
|
17
|
+
/** Returns the set of 1-based line numbers occupied by YAML/TOML front-matter. */
|
|
18
|
+
function frontMatterLines(sourceLines) {
|
|
19
|
+
const excluded = new Set();
|
|
20
|
+
if (sourceLines.length === 0)
|
|
21
|
+
return excluded;
|
|
22
|
+
const first = sourceLines[0] ?? '';
|
|
23
|
+
const delimiter = first === '---' ? '---' : first === '+++' ? '+++' : null;
|
|
24
|
+
if (delimiter === null)
|
|
25
|
+
return excluded;
|
|
26
|
+
// Mark line 1 (the opening delimiter)
|
|
27
|
+
excluded.add(1);
|
|
28
|
+
for (let i = 1; i < sourceLines.length; i++) {
|
|
29
|
+
// Lines inside and including the closing delimiter are excluded (1-based)
|
|
30
|
+
excluded.add(i + 1);
|
|
31
|
+
if (sourceLines[i] === delimiter) {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return excluded;
|
|
36
|
+
}
|
|
37
|
+
function collectLines(node, sourceLines, seen, excluded, result) {
|
|
38
|
+
if (SKIP_TYPES.has(node.type)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const pos = node.position;
|
|
42
|
+
if (pos !== undefined && pos !== null) {
|
|
43
|
+
const start = pos.start.line;
|
|
44
|
+
const end = pos.end.line;
|
|
45
|
+
const isParent = 'children' in node && Array.isArray(node.children);
|
|
46
|
+
if (!isParent) {
|
|
47
|
+
for (let ln = start; ln <= end; ln++) {
|
|
48
|
+
if (!seen.has(ln) && !excluded.has(ln)) {
|
|
49
|
+
seen.add(ln);
|
|
50
|
+
const text = sourceLines[ln - 1] ?? '';
|
|
51
|
+
result.push({ line: ln, text });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
for (const child of node.children) {
|
|
57
|
+
collectLines(child, sourceLines, seen, excluded, result);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function extractProseLines(content) {
|
|
63
|
+
const sourceLines = content.split('\n');
|
|
64
|
+
const excluded = frontMatterLines(sourceLines);
|
|
65
|
+
// Strip front-matter before parsing so that remark doesn't misinterpret it.
|
|
66
|
+
// We replace excluded lines with blank lines to preserve line numbers.
|
|
67
|
+
let parseContent = content;
|
|
68
|
+
if (excluded.size > 0) {
|
|
69
|
+
const stripped = sourceLines.map((line, idx) => excluded.has(idx + 1) ? '' : line);
|
|
70
|
+
parseContent = stripped.join('\n');
|
|
71
|
+
}
|
|
72
|
+
const tree = unified().use(remarkParse).parse(parseContent);
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
const result = [];
|
|
75
|
+
for (const child of tree.children) {
|
|
76
|
+
collectLines(child, sourceLines, seen, excluded, result);
|
|
77
|
+
}
|
|
78
|
+
result.sort((a, b) => a.line - b.line);
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=prose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prose.js","sourceRoot":"","sources":["../../src/markdown/prose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON renderer for bibcheck output.
|
|
3
|
+
*
|
|
4
|
+
* Round-trip property: the JSON produced by renderJson is guaranteed to
|
|
5
|
+
* validate against OutputSchema. Callers can safely parse the output back
|
|
6
|
+
* through OutputSchema.parse(JSON.parse(text)) and obtain an identical
|
|
7
|
+
* validated object.
|
|
8
|
+
*/
|
|
9
|
+
import type { Output } from '../schema/output.js';
|
|
10
|
+
/**
|
|
11
|
+
* Render a validated Output as a JSON string.
|
|
12
|
+
*
|
|
13
|
+
* @param output - A validated Output object.
|
|
14
|
+
* @param opts.pretty - When true (default), produce 2-space-indented JSON.
|
|
15
|
+
* When false, produce minified JSON.
|
|
16
|
+
* @returns The JSON string, always terminated with a trailing newline.
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderJson(output: Output, opts?: {
|
|
19
|
+
pretty?: boolean;
|
|
20
|
+
}): string;
|
|
21
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/output/json.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAK9E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON renderer for bibcheck output.
|
|
3
|
+
*
|
|
4
|
+
* Round-trip property: the JSON produced by renderJson is guaranteed to
|
|
5
|
+
* validate against OutputSchema. Callers can safely parse the output back
|
|
6
|
+
* through OutputSchema.parse(JSON.parse(text)) and obtain an identical
|
|
7
|
+
* validated object.
|
|
8
|
+
*/
|
|
9
|
+
import { OutputSchema } from '../schema/output.js';
|
|
10
|
+
/**
|
|
11
|
+
* Render a validated Output as a JSON string.
|
|
12
|
+
*
|
|
13
|
+
* @param output - A validated Output object.
|
|
14
|
+
* @param opts.pretty - When true (default), produce 2-space-indented JSON.
|
|
15
|
+
* When false, produce minified JSON.
|
|
16
|
+
* @returns The JSON string, always terminated with a trailing newline.
|
|
17
|
+
*/
|
|
18
|
+
export function renderJson(output, opts) {
|
|
19
|
+
// Validate first so the caller gets a clear error if they pass an invalid object.
|
|
20
|
+
const validated = OutputSchema.parse(output);
|
|
21
|
+
const pretty = opts?.pretty !== false; // default true
|
|
22
|
+
return JSON.stringify(validated, null, pretty ? 2 : 0) + '\n';
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/output/json.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,IAA2B;IACpE,kFAAkF;IAClF,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,eAAe;IACtD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown renderer for bibcheck output.
|
|
3
|
+
*
|
|
4
|
+
* Produces a sectioned human-readable report with tables for entry-level
|
|
5
|
+
* findings and lists for linkage failures, phrase flags, and worklist items.
|
|
6
|
+
* All sections are always present; empty sections show "No findings." rather
|
|
7
|
+
* than being omitted, so the document structure is stable across runs.
|
|
8
|
+
*/
|
|
9
|
+
import type { Output } from '../schema/output.js';
|
|
10
|
+
/**
|
|
11
|
+
* Render a validated Output as a Markdown string.
|
|
12
|
+
*
|
|
13
|
+
* The document always contains all sections, even when empty, so its structure
|
|
14
|
+
* is stable and predictable for downstream consumers. Sections with no findings
|
|
15
|
+
* show "No findings." rather than being omitted.
|
|
16
|
+
*
|
|
17
|
+
* Lists are sorted deterministically (alpha by citekey or file:line) so two
|
|
18
|
+
* renders of the same input produce byte-identical output.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderMarkdown(output: Output): string;
|
|
21
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/output/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiD,MAAM,qBAAqB,CAAC;AAyLjG;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYrD"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown renderer for bibcheck output.
|
|
3
|
+
*
|
|
4
|
+
* Produces a sectioned human-readable report with tables for entry-level
|
|
5
|
+
* findings and lists for linkage failures, phrase flags, and worklist items.
|
|
6
|
+
* All sections are always present; empty sections show "No findings." rather
|
|
7
|
+
* than being omitted, so the document structure is stable across runs.
|
|
8
|
+
*/
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Helpers
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/** Escape pipe characters so they don't break Markdown table cells. */
|
|
13
|
+
function escCell(s) {
|
|
14
|
+
return s.replace(/\|/g, '\\|').replace(/\n/g, ' ');
|
|
15
|
+
}
|
|
16
|
+
/** Format a file:line pair as a Markdown link for IDE/GitHub clickability. */
|
|
17
|
+
function fileLink(file, line) {
|
|
18
|
+
return `[${file}:${line}](${file}#L${line})`;
|
|
19
|
+
}
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Section builders
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
function renderSummaryTable(output) {
|
|
24
|
+
const { summary, tool } = output;
|
|
25
|
+
const lines = [
|
|
26
|
+
'## Summary',
|
|
27
|
+
'',
|
|
28
|
+
`**Schema version:** ${output.schemaVersion}`,
|
|
29
|
+
`**Tool:** ${tool.name}@${tool.version}`,
|
|
30
|
+
'',
|
|
31
|
+
'| Metric | Count |',
|
|
32
|
+
'|--------|-------|',
|
|
33
|
+
`| Total entries | ${summary.totalEntries} |`,
|
|
34
|
+
`| Verified | ${summary.verified} |`,
|
|
35
|
+
`| Metadata mismatches | ${summary.metadataMismatches} |`,
|
|
36
|
+
`| Not found in databases | ${summary.notFoundInDatabases} |`,
|
|
37
|
+
`| Malformed identifiers | ${summary.malformedIdentifiers} |`,
|
|
38
|
+
`| Unverifiable | ${summary.unverifiable} |`,
|
|
39
|
+
`| Canonical issues | ${summary.canonicalIssues} |`,
|
|
40
|
+
`| Linkage failures | ${summary.linkageFailures} |`,
|
|
41
|
+
`| Orphaned entries (informational) | ${summary.orphanedEntries ?? 0} |`,
|
|
42
|
+
`| Phrase flags | ${summary.phraseFlags} |`,
|
|
43
|
+
`| Worklist items | ${summary.worklistItems} |`,
|
|
44
|
+
'',
|
|
45
|
+
];
|
|
46
|
+
return lines.join('\n');
|
|
47
|
+
}
|
|
48
|
+
function renderEntriesTable(entries) {
|
|
49
|
+
const lines = ['## Bibliography entries', ''];
|
|
50
|
+
if (entries.length === 0) {
|
|
51
|
+
lines.push('No findings.');
|
|
52
|
+
lines.push('');
|
|
53
|
+
return lines.join('\n');
|
|
54
|
+
}
|
|
55
|
+
// Sort alphabetically by citekey.
|
|
56
|
+
const sorted = [...entries].sort((a, b) => a.citekey.localeCompare(b.citekey));
|
|
57
|
+
lines.push('| Citekey | Existence status | Evidence | Canonical status | Canonical URL |');
|
|
58
|
+
lines.push('|---------|-----------------|----------|-----------------|---------------|');
|
|
59
|
+
for (const entry of sorted) {
|
|
60
|
+
const existStatus = entry.existence?.status ?? 'not run';
|
|
61
|
+
const evidence = entry.existence?.evidence ?? '—';
|
|
62
|
+
const canonStatus = entry.canonical?.status ?? 'not run';
|
|
63
|
+
const canonUrl = entry.canonical?.url != null ? `[link](${entry.canonical.url})` : '—';
|
|
64
|
+
lines.push(`| ${escCell(entry.citekey)} | ${escCell(existStatus)} | ${escCell(evidence)} | ${escCell(canonStatus)} | ${canonUrl} |`);
|
|
65
|
+
}
|
|
66
|
+
lines.push('');
|
|
67
|
+
return lines.join('\n');
|
|
68
|
+
}
|
|
69
|
+
function renderLinkageSection(linkage) {
|
|
70
|
+
const lines = ['## Linkage', ''];
|
|
71
|
+
const unresolved = [...linkage]
|
|
72
|
+
.filter((l) => l.status === 'unresolved')
|
|
73
|
+
.sort((a, b) => a.citekey.localeCompare(b.citekey));
|
|
74
|
+
if (unresolved.length === 0) {
|
|
75
|
+
lines.push('No findings.');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
for (const entry of unresolved) {
|
|
79
|
+
lines.push(`- **@${entry.citekey}** — referenced in:`);
|
|
80
|
+
const sortedRefs = [...entry.references].sort((a, b) => {
|
|
81
|
+
const fc = a.file.localeCompare(b.file);
|
|
82
|
+
return fc !== 0 ? fc : a.line - b.line;
|
|
83
|
+
});
|
|
84
|
+
for (const ref of sortedRefs) {
|
|
85
|
+
lines.push(` - ${fileLink(ref.file, ref.line)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
lines.push('');
|
|
90
|
+
return lines.join('\n');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Orphaned bibliography entries (reverse linkage, H2): bibliography citekeys
|
|
94
|
+
* never referenced in any doc. Informational — a smell, not a failure — so the
|
|
95
|
+
* section is always present but plainly labelled non-gating.
|
|
96
|
+
*/
|
|
97
|
+
function renderOrphansSection(linkage) {
|
|
98
|
+
const lines = ['## Orphaned entries (informational)', ''];
|
|
99
|
+
const orphans = [...linkage]
|
|
100
|
+
.filter((l) => l.status === 'orphan')
|
|
101
|
+
.sort((a, b) => a.citekey.localeCompare(b.citekey));
|
|
102
|
+
if (orphans.length === 0) {
|
|
103
|
+
lines.push('No findings.');
|
|
104
|
+
lines.push('');
|
|
105
|
+
return lines.join('\n');
|
|
106
|
+
}
|
|
107
|
+
lines.push('These bibliography entries are never cited in any document. This is ' +
|
|
108
|
+
'informational only and does not affect the exit code.');
|
|
109
|
+
lines.push('');
|
|
110
|
+
for (const entry of orphans) {
|
|
111
|
+
lines.push(`- **@${entry.citekey}**`);
|
|
112
|
+
}
|
|
113
|
+
lines.push('');
|
|
114
|
+
return lines.join('\n');
|
|
115
|
+
}
|
|
116
|
+
function renderPhraseFlagsSection(phraseFlags) {
|
|
117
|
+
const lines = ['## Phrase flags', ''];
|
|
118
|
+
const flagged = [...phraseFlags]
|
|
119
|
+
.filter((f) => f.status === 'flagged')
|
|
120
|
+
.sort((a, b) => {
|
|
121
|
+
const fc = a.file.localeCompare(b.file);
|
|
122
|
+
if (fc !== 0)
|
|
123
|
+
return fc;
|
|
124
|
+
if (a.line !== b.line)
|
|
125
|
+
return a.line - b.line;
|
|
126
|
+
return a.patternKey.localeCompare(b.patternKey);
|
|
127
|
+
});
|
|
128
|
+
if (flagged.length === 0) {
|
|
129
|
+
lines.push('No findings.');
|
|
130
|
+
lines.push('');
|
|
131
|
+
return lines.join('\n');
|
|
132
|
+
}
|
|
133
|
+
for (const flag of flagged) {
|
|
134
|
+
const loc = fileLink(flag.file, flag.line);
|
|
135
|
+
lines.push(`- \`${flag.patternKey}\` in ${loc}: "${escCell(flag.matchedText)}"`);
|
|
136
|
+
if (flag.referenceUrl != null) {
|
|
137
|
+
lines.push(` - Reference: <${flag.referenceUrl}>`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
lines.push('');
|
|
141
|
+
return lines.join('\n');
|
|
142
|
+
}
|
|
143
|
+
function renderWorklistSection(worklist) {
|
|
144
|
+
const lines = ['## Worklist', ''];
|
|
145
|
+
if (worklist.length === 0) {
|
|
146
|
+
lines.push('No findings.');
|
|
147
|
+
lines.push('');
|
|
148
|
+
return lines.join('\n');
|
|
149
|
+
}
|
|
150
|
+
const sorted = [...worklist].sort((a, b) => {
|
|
151
|
+
const fc = a.file.localeCompare(b.file);
|
|
152
|
+
if (fc !== 0)
|
|
153
|
+
return fc;
|
|
154
|
+
if (a.line !== b.line)
|
|
155
|
+
return a.line - b.line;
|
|
156
|
+
return a.type.localeCompare(b.type);
|
|
157
|
+
});
|
|
158
|
+
for (const item of sorted) {
|
|
159
|
+
const loc = fileLink(item.file, item.line);
|
|
160
|
+
const verif = item.verificationUrl != null ? `<${item.verificationUrl}>` : 'manual';
|
|
161
|
+
lines.push(`- [${item.type}] ${loc} — ${escCell(item.recommendedAction)}`);
|
|
162
|
+
lines.push(` - Citation: \`${item.citation}\``);
|
|
163
|
+
lines.push(` - Verification: ${verif}`);
|
|
164
|
+
}
|
|
165
|
+
lines.push('');
|
|
166
|
+
return lines.join('\n');
|
|
167
|
+
}
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// Public API
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
/**
|
|
172
|
+
* Render a validated Output as a Markdown string.
|
|
173
|
+
*
|
|
174
|
+
* The document always contains all sections, even when empty, so its structure
|
|
175
|
+
* is stable and predictable for downstream consumers. Sections with no findings
|
|
176
|
+
* show "No findings." rather than being omitted.
|
|
177
|
+
*
|
|
178
|
+
* Lists are sorted deterministically (alpha by citekey or file:line) so two
|
|
179
|
+
* renders of the same input produce byte-identical output.
|
|
180
|
+
*/
|
|
181
|
+
export function renderMarkdown(output) {
|
|
182
|
+
const sections = [
|
|
183
|
+
'# bibcheck report',
|
|
184
|
+
'',
|
|
185
|
+
renderSummaryTable(output),
|
|
186
|
+
renderEntriesTable(output.entries),
|
|
187
|
+
renderLinkageSection(output.linkage),
|
|
188
|
+
renderOrphansSection(output.linkage),
|
|
189
|
+
renderPhraseFlagsSection(output.phraseFlags),
|
|
190
|
+
renderWorklistSection(output.worklist),
|
|
191
|
+
];
|
|
192
|
+
return sections.join('\n');
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/output/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF v2.1.0 renderer for bibcheck output.
|
|
3
|
+
*
|
|
4
|
+
* Uses node-sarif-builder for the structural boilerplate (tool/driver, rules,
|
|
5
|
+
* results) and then post-processes the resulting object to add:
|
|
6
|
+
* - originalUriBaseIds so that relative artifact URIs resolve correctly
|
|
7
|
+
* - partialFingerprints (sha256-based, stable across runs) for deduplication
|
|
8
|
+
*
|
|
9
|
+
* The library does not expose a first-class API for those two fields, so they
|
|
10
|
+
* are injected directly onto the mutable run/result objects that the builders
|
|
11
|
+
* expose as public properties (`.run` and `.result`). This is the documented
|
|
12
|
+
* escape hatch in node-sarif-builder.
|
|
13
|
+
*
|
|
14
|
+
* Worklist items are NOT emitted as SARIF results. They are informational and
|
|
15
|
+
* would cause spurious CI failures if surfaced as findings.
|
|
16
|
+
*/
|
|
17
|
+
import type { Output } from '../schema/output.js';
|
|
18
|
+
/**
|
|
19
|
+
* Render a validated Output as a SARIF v2.1.0 JSON string.
|
|
20
|
+
*
|
|
21
|
+
* The SARIF document contains one run with:
|
|
22
|
+
* - tool.driver with all applicable rules defined
|
|
23
|
+
* - originalUriBaseIds.PROJECTROOT so relative file URIs resolve correctly
|
|
24
|
+
* - one result per finding (existence mismatches, canonical errors, linkage
|
|
25
|
+
* unresolved, phrase flags), with partialFingerprints for deduplication
|
|
26
|
+
*
|
|
27
|
+
* Worklist items are not emitted as SARIF results (they are informational).
|
|
28
|
+
* Acknowledged phrase flags are not emitted (only status: 'flagged' entries).
|
|
29
|
+
*/
|
|
30
|
+
export declare function renderSarif(output: Output): string;
|
|
31
|
+
//# sourceMappingURL=sarif.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/output/sarif.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAwSlD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiDlD"}
|