49 lines
2.1 KiB
JavaScript
49 lines
2.1 KiB
JavaScript
// innboks-relations.mjs
|
|
// Step 6: deterministisk relasjons-resolusjon innen KJOERINGENS konsept-sett
|
|
// (lukket lenke-vokabular). For hvert konsept oppdages referanser til ANDRE
|
|
// emitterte konsepter (exact-title substring, case-insensitivt) og emitteres som
|
|
// leading-'/' bundle-root-lenker bygd paa malet-konseptets destRel (satt i Step 5,
|
|
// kjent FOER skriv -- Pass-2 ordering-fiks). Asserterer zero-dangling mot de
|
|
// emitterte destRel-stiene og at hver generert lenke er trygg (delt okf-links-
|
|
// allow-list). v1-narrowing: kun innen-kjoering-settet -- lenking til pre-
|
|
// eksisterende tre-konsepter er v1.1. Zero npm dependencies.
|
|
|
|
import { isSafeBundleLink } from './okf-links.mjs';
|
|
|
|
const REL_HEADING = '## Relaterte dokumenter';
|
|
|
|
// concepts (beriket av projectFrontmatter, m/ destRel) -> samme konsepter m/
|
|
// relations[] + body utvidet med en deterministisk relasjons-seksjon.
|
|
export function resolveRelations(concepts) {
|
|
const emitted = new Set(concepts.map((c) => c.destRel));
|
|
|
|
return concepts.map((concept) => {
|
|
const haystack = `${concept.title}\n${concept.body}`.toLowerCase();
|
|
const found = new Map(); // target -> { title, target, destRel }
|
|
|
|
for (const other of concepts) {
|
|
if (other === concept) continue;
|
|
if (!other.title || !other.destRel) continue;
|
|
if (!haystack.includes(other.title.toLowerCase())) continue;
|
|
|
|
const target = `/${other.destRel}`;
|
|
if (!isSafeBundleLink(target)) {
|
|
throw new Error(`innboks-relations: utrygg generert lenke ${target}`);
|
|
}
|
|
if (!emitted.has(other.destRel)) {
|
|
throw new Error(`innboks-relations: dangling relasjon ${other.destRel}`);
|
|
}
|
|
found.set(target, { title: other.title, target, destRel: other.destRel });
|
|
}
|
|
|
|
const relations = [...found.values()].sort((a, b) => a.target.localeCompare(b.target));
|
|
|
|
let body = concept.body;
|
|
if (relations.length > 0) {
|
|
const links = relations.map((r) => `- [${r.title}](${r.target})`).join('\n');
|
|
body = `${concept.body}\n\n${REL_HEADING}\n\n${links}\n`;
|
|
}
|
|
|
|
return { ...concept, relations, body };
|
|
});
|
|
}
|