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

// Directory registers: a dir.yml at any directory inside the kb tree
// declares what its subtree is - personal notes, project docs, or
// vendor reference copies. Resolution is nearest-ancestor; unmarked
// content is notes, the natural resting state of a wiki.
import { existsSync, readFileSync, readdirSync } from "node:fs";
import { join } from "node:path";

export type Register = "notes" | "docs" | "reference";

export const DEFAULT_REGISTER: Register = "notes";

export interface DirManifest {
  register: Register;
  /** Display name for the subtree, e.g. a project name. */
  title?: string;
}

export interface RegisterInfo {
  register: Register;
  /** Manifest directory that decided the register; null when default. */
  root: string | null;
  title: string | null;
}

const REGISTERS: Register[] = ["notes", "docs", "reference"];

// dir.yml is two known keys - a tiny parser beats a yaml dependency
function parseManifest(text: string, at: string): DirManifest {
  const field = (key: string): string | null => {
    const m = text.match(new RegExp(`^${key}:\\s*["']?(.+?)["']?\\s*$`, "m"));
    return m ? m[1] : null;
  };
  const register = field("register") as Register | null;
  if (!register || !REGISTERS.includes(register)) {
    throw new Error(`[kb] ${at}: register must be one of ${REGISTERS.join(", ")}`)
;
  }
  return { register, title: field("title") ?? undefined };
}

/** Every dir.yml under the kb tree, keyed by directory id ("" root). */
export function readManifests(contentDir = "src/content/kb"): Map<string, DirManif
est> {
  const out = new Map<string, DirManifest>();
  if (!existsSync(contentDir)) return out;
  const walk = (dir: string, prefix: string) => {
    const manifest = join(dir, "dir.yml");
    if (existsSync(manifest)) {
      out.set(prefix, parseManifest(readFileSync(manifest, "utf8"), manifest));
    }
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
      if (entry.isDirectory()) {
        walk(join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.nam
e);
      }
    }
  };
  walk(contentDir, "");
  return out;
}

/** Register of a page id, from the nearest ancestor manifest. */
export function registerOf(id: string, manifests: Map<string, DirManifest>): Regis
terInfo {
  const segments = id.split("/").slice(0, -1);
  for (let i = segments.length; i >= 0; i--) {
    const dir = segments.slice(0, i).join("/");
    const m = manifests.get(dir);
    if (m) return { register: m.register, root: dir, title: m.title ?? null };
  }
  return { register: DEFAULT_REGISTER, root: null, title: null };
}

/** Display label for a register, as shown in chrome and search. */
export const registerLabel = (r: Register): string =>
  r === "notes" ? "NOTE" : r === "docs" ? "DOC" : "REF";

// Directory registers: a dir.yml at any dir
ectory inside the kb tree
// declares what its subtree is - personal n
otes, project docs, or
// vendor reference copies. Resolution is ne
arest-ancestor; unmarked
// content is notes, the natural resting sta
te of a wiki.
import { existsSync, readFileSync, readdirSy
nc } from "node:fs";
import { join } from "node:path";

export type Register = "notes" | "docs" | "r
eference";

export const DEFAULT_REGISTER: Register = "n
otes";

export interface DirManifest {
  register: Register;
  /** Display name for the subtree, e.g. a p
roject name. */
  title?: string;
}

export interface RegisterInfo {
  register: Register;
  /** Manifest directory that decided the re
gister; null when default. */
  root: string | null;
  title: string | null;
}

const REGISTERS: Register[] = ["notes", "doc
s", "reference"];

// dir.yml is two known keys - a tiny parser
 beats a yaml dependency
function parseManifest(text: string, at: str
ing): DirManifest {
  const field = (key: string): string | null
 => {
    const m = text.match(new RegExp(`^${key}
:\\s*["']?(.+?)["']?\\s*$`, "m"));
    return m ? m[1] : null;
  };
  const register = field("register") as Regi
ster | null;
  if (!register || !REGISTERS.includes(regis
ter)) {
    throw new Error(`[kb] ${at}: register mu
st be one of ${REGISTERS.join(", ")}`);
  }
  return { register, title: field("title") ?
? undefined };
}

/** Every dir.yml under the kb tree, keyed b
y directory id ("" root). */
export function readManifests(contentDir = "
src/content/kb"): Map<string, DirManifest> {
  const out = new Map<string, DirManifest>()
;
  if (!existsSync(contentDir)) return out;
  const walk = (dir: string, prefix: string)
 => {
    const manifest = join(dir, "dir.yml");
    if (existsSync(manifest)) {
      out.set(prefix, parseManifest(readFile
Sync(manifest, "utf8"), manifest));
    }
    for (const entry of readdirSync(dir, { w
ithFileTypes: true })) {
      if (entry.isDirectory()) {
        walk(join(dir, entry.name), prefix ?
 `${prefix}/${entry.name}` : entry.name);
      }
    }
  };
  walk(contentDir, "");
  return out;
}

/** Register of a page id, from the nearest 
ancestor manifest. */
export function registerOf(id: string, manif
ests: Map<string, DirManifest>): RegisterInf
o {
  const segments = id.split("/").slice(0, -1
);
  for (let i = segments.length; i >= 0; i--)
 {
    const dir = segments.slice(0, i).join("/
");
    const m = manifests.get(dir);
    if (m) return { register: m.register, ro
ot: dir, title: m.title ?? null };
  }
  return { register: DEFAULT_REGISTER, root:
 null, title: null };
}

/** Display label for a register, as shown i
n chrome and search. */
export const registerLabel = (r: Register): 
string =>
  r === "notes" ? "NOTE" : r === "docs" ? "D
OC" : "REF";
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET