OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
master @ 111 LINES
 
[ HISTORY ]  [ UP ]
 

import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildBacklinks, buildWikiMap, extractWikiTargets, resolveWikilink } from 
"./wikilinks";
import { wikiNodes } from "./remark-wikilinks";

// fixture content dir - the graph tests must not depend on what the
// real collections currently hold
let dir: string;
const write = (rel: string, fm: string, body = "") => {
  const p = join(dir, rel);
  mkdirSync(join(p, ".."), { recursive: true });
  writeFileSync(p, `---\n${fm}\n---\n\n${body}`);
};

beforeAll(() => {
  dir = mkdtempSync(join(tmpdir(), "wiki-"));
  write("kb/nix/flakes.md", 'title: "FLAKES FIELD NOTES"', "cites [[windows/tss]] 
and [[Docs Page]].");
  write("kb/nix/draft.md", 'title: "DRAFT"\ndraft: true', "cites [[flakes field no
tes]].");
  write("kb/windows/tss.md", 'title: "TSS TOOLSET"\nsource: "MS"', "literal `[[fla
kes field notes]]` only.");
  writeFileSync(join(dir, "kb/windows/dir.yml"), "register: reference\n");
  write("kb/site/page.md", 'title: "Docs Page"', "self [[Docs Page]], live [[FLAKE
S FIELD NOTES]], dead [[nope]].");
  writeFileSync(join(dir, "kb/site/dir.yml"), "register: docs\n");
});
afterAll(() => rmSync(dir, { recursive: true, force: true }));

describe("buildWikiMap", () => {
  it("indexes every collection by id and title", () => {
    const map = buildWikiMap(dir);
    expect(resolveWikilink("nix/flakes", map)).toBe("/kb/nix/flakes/");
    expect(resolveWikilink("Flakes Field Notes", map)).toBe("/kb/nix/flakes/");
    expect(resolveWikilink("windows/tss", map)).toBe("/kb/windows/tss/");
    expect(resolveWikilink("Docs Page", map)).toBe("/kb/site/page/");
  });

  it("is case-insensitive and trims", () => {
    const map = buildWikiMap(dir);
    expect(resolveWikilink("  TSS TOOLSET  ", map)).toBe("/kb/windows/tss/");
  });

  it("excludes drafts", () => {
    expect(resolveWikilink("nix/draft", buildWikiMap(dir))).toBeNull();
  });

  it("returns null for unknown targets", () => {
    expect(resolveWikilink("A NOTE THAT DOES NOT EXIST", buildWikiMap(dir))).toBeN
ull();
  });
});

describe("wikiNodes", () => {
  const map = new Map([["docs page", "/kb/site/page/"]]);

  it("leaves plain text untouched", () => {
    expect(wikiNodes("no links here", map)).toBeNull();
  });

  it("splits text around a resolved link", () => {
    const nodes = wikiNodes("see [[Docs Page]] for glyphs", map)!;
    expect(nodes.map((n) => n.type)).toEqual(["text", "link", "text"]);
    expect(nodes[1].url).toBe("/kb/site/page/");
  });

  it("uses the alias as the label", () => {
    const nodes = wikiNodes("[[Docs Page|the page]]", map)!;
    expect((nodes[0].children as { value: string }[])[0].value).toBe("the page");
  });

  it("renders unresolved targets as dead-link spans", () => {
    const nodes = wikiNodes("[[missing]]", map)!;
    expect(nodes[0].type).toBe("html");
    expect(nodes[0].value).toContain("wikilink-dead");
  });
});

describe("extractWikiTargets", () => {
  it("collects targets, dropping aliases", () => {
    expect(extractWikiTargets("see [[a/b]] and [[X|the x]]")).toEqual(["a/b", "X"]
);
  });

  it("ignores wikilinks inside inline code and fences", () => {
    const body = "live [[a]], literal `[[b]]`\n```\n[[c]]\n```\ndone";
    expect(extractWikiTargets(body)).toEqual(["a"]);
  });
});

describe("buildBacklinks", () => {
  it("inverts the graph across the kb", () => {
    const bl = buildBacklinks(dir);
    const urls = (t: string) => (bl.get(t) ?? []).map((r) => r.url);
    expect(urls("/kb/windows/tss/")).toEqual(["/kb/nix/flakes/"]);
    expect(urls("/kb/nix/flakes/")).toEqual(["/kb/site/page/"]);
  });

  it("labels sources with their register", () => {
    const src = buildBacklinks(dir).get("/kb/windows/tss/")![0];
    expect(src.label).toBe("NOTE - FLAKES FIELD NOTES");
  });

  it("drops self-references, drafts, and code-span citations", () => {
    const bl = buildBacklinks(dir);
    for (const [target, list] of bl) {
      expect(list.map((r) => r.url)).not.toContain(target);
      expect(list.map((r) => r.url)).not.toContain("/kb/nix/draft/");
    }
    // the reference body only cites in a code span - it must not be a source
    const flakes = bl.get("/kb/nix/flakes/") ?? [];
    expect(flakes.map((r) => r.url)).not.toContain("/kb/windows/tss/");
  });
});

import { mkdtempSync, mkdirSync, rmSync, wri
teFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { afterAll, beforeAll, describe, expe
ct, it } from "vitest";
import { buildBacklinks, buildWikiMap, extra
ctWikiTargets, resolveWikilink } from "./wik
ilinks";
import { wikiNodes } from "./remark-wikilink
s";

// fixture content dir - the graph tests mus
t not depend on what the
// real collections currently hold
let dir: string;
const write = (rel: string, fm: string, body
 = "") => {
  const p = join(dir, rel);
  mkdirSync(join(p, ".."), { recursive: true
 });
  writeFileSync(p, `---\n${fm}\n---\n\n${bod
y}`);
};

beforeAll(() => {
  dir = mkdtempSync(join(tmpdir(), "wiki-"))
;
  write("kb/nix/flakes.md", 'title: "FLAKES 
FIELD NOTES"', "cites [[windows/tss]] and [[
Docs Page]].");
  write("kb/nix/draft.md", 'title: "DRAFT"\n
draft: true', "cites [[flakes field notes]].
");
  write("kb/windows/tss.md", 'title: "TSS TO
OLSET"\nsource: "MS"', "literal `[[flakes fi
eld notes]]` only.");
  writeFileSync(join(dir, "kb/windows/dir.ym
l"), "register: reference\n");
  write("kb/site/page.md", 'title: "Docs Pag
e"', "self [[Docs Page]], live [[FLAKES FIEL
D NOTES]], dead [[nope]].");
  writeFileSync(join(dir, "kb/site/dir.yml")
, "register: docs\n");
});
afterAll(() => rmSync(dir, { recursive: true
, force: true }));

describe("buildWikiMap", () => {
  it("indexes every collection by id and tit
le", () => {
    const map = buildWikiMap(dir);
    expect(resolveWikilink("nix/flakes", map
)).toBe("/kb/nix/flakes/");
    expect(resolveWikilink("Flakes Field Not
es", map)).toBe("/kb/nix/flakes/");
    expect(resolveWikilink("windows/tss", ma
p)).toBe("/kb/windows/tss/");
    expect(resolveWikilink("Docs Page", map)
).toBe("/kb/site/page/");
  });

  it("is case-insensitive and trims", () => 
{
    const map = buildWikiMap(dir);
    expect(resolveWikilink("  TSS TOOLSET  "
, map)).toBe("/kb/windows/tss/");
  });

  it("excludes drafts", () => {
    expect(resolveWikilink("nix/draft", buil
dWikiMap(dir))).toBeNull();
  });

  it("returns null for unknown targets", () 
=> {
    expect(resolveWikilink("A NOTE THAT DOES
 NOT EXIST", buildWikiMap(dir))).toBeNull();
  });
});

describe("wikiNodes", () => {
  const map = new Map([["docs page", "/kb/si
te/page/"]]);

  it("leaves plain text untouched", () => {
    expect(wikiNodes("no links here", map)).
toBeNull();
  });

  it("splits text around a resolved link", (
) => {
    const nodes = wikiNodes("see [[Docs Page
]] for glyphs", map)!;
    expect(nodes.map((n) => n.type)).toEqual
(["text", "link", "text"]);
    expect(nodes[1].url).toBe("/kb/site/page
/");
  });

  it("uses the alias as the label", () => {
    const nodes = wikiNodes("[[Docs Page|the
 page]]", map)!;
    expect((nodes[0].children as { value: st
ring }[])[0].value).toBe("the page");
  });

  it("renders unresolved targets as dead-lin
k spans", () => {
    const nodes = wikiNodes("[[missing]]", m
ap)!;
    expect(nodes[0].type).toBe("html");
    expect(nodes[0].value).toContain("wikili
nk-dead");
  });
});

describe("extractWikiTargets", () => {
  it("collects targets, dropping aliases", (
) => {
    expect(extractWikiTargets("see [[a/b]] a
nd [[X|the x]]")).toEqual(["a/b", "X"]);
  });

  it("ignores wikilinks inside inline code a
nd fences", () => {
    const body = "live [[a]], literal `[[b]]
`\n```\n[[c]]\n```\ndone";
    expect(extractWikiTargets(body)).toEqual
(["a"]);
  });
});

describe("buildBacklinks", () => {
  it("inverts the graph across the kb", () =
> {
    const bl = buildBacklinks(dir);
    const urls = (t: string) => (bl.get(t) ?
? []).map((r) => r.url);
    expect(urls("/kb/windows/tss/")).toEqual
(["/kb/nix/flakes/"]);
    expect(urls("/kb/nix/flakes/")).toEqual(
["/kb/site/page/"]);
  });

  it("labels sources with their register", (
) => {
    const src = buildBacklinks(dir).get("/kb
/windows/tss/")![0];
    expect(src.label).toBe("NOTE - FLAKES FI
ELD NOTES");
  });

  it("drops self-references, drafts, and cod
e-span citations", () => {
    const bl = buildBacklinks(dir);
    for (const [target, list] of bl) {
      expect(list.map((r) => r.url)).not.toC
ontain(target);
      expect(list.map((r) => r.url)).not.toC
ontain("/kb/nix/draft/");
    }
    // the reference body only cites in a co
de span - it must not be a source
    const flakes = bl.get("/kb/nix/flakes/")
 ?? [];
    expect(flakes.map((r) => r.url)).not.toC
ontain("/kb/windows/tss/");
  });
});
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET