nameAt

tcmts.cli.main.nameAt · #d7qhjc2w · term · runs on the server

uses node:path

The codebase name of a definition declared as leaf at line of file: a definition's document (.tcm/src) is one name's, a generated module (.tcm/cache) a component's, a mirrored file its namespace's, and a scratch file's say where they go (// tcm: path, or its // tcm: namespace).

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { joinName, loadMirror } from "#codebase/tcmts/cli/mirror";
import { hashesOfViewFile, srcDir } from "#codebase/tcmts/cli/views";
import path from "node:path";

export function nameAt(cb: Codebase, file: string, text: string): (leaf: string, line: number) => string | undefined {
  const inside = (dir: string) => !path.relative(dir, file).startsWith("..");
  if (inside(srcDir(cb))) {
    const name = hashesOfViewFile(cb, file).map((h) => cb.store.pathsOf(h)[0]).find(Boolean);
    return () => name;
  }
  if (inside(cb.lay.cacheDir)) {
    const members = cb.store.componentMembers(path.basename(file).replace(/\.tsx?$/, "")).flatMap((m) => cb.store.pathsOf(m.hash));
    return (leaf) => members.find((p) => p.slice(p.lastIndexOf(".") + 1) === leaf);
  }
  const m = loadMirror(cb);
  const mirrored = m?.files[path.relative(m.dir, file)];
  if (mirrored) return (leaf) => joinName(mirrored.ns, leaf);
  const lines = text.split("\n");
  const ns = /^\/\/ tcm: namespace (\S+)/m.exec(text)?.[1] ?? "";
  return (leaf, line) => {
    // a `// tcm: path` line above the declaration (and its doc) says where it goes
    for (let i = line - 2; i >= 0 && i >= line - 40; i--) {
      const p = /^\/\/ tcm: path (\S+)/.exec(lines[i]!);
      if (p) return p[1];
      if (lines[i]!.trim() && !/^\s*(\/\/|\/\*|\*)/.test(lines[i]!)) break;
    }
    return joinName(ns, leaf);
  };
}

uses

used by