suiteApps

tcmts.cli.suites.suiteApps · #7mge3okj · term · runs on the server

uses node:path

The apps the package at namespace ships (apps in its manifest), packed as tcm pack packs them, for its command run from this codebase (as suites run it, not from a package): a directory holding <name>/codebase.sqlite for each, made once for those apps' hashes, which the command finds by TCM_APPS. Undefined if it ships none.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { absolute, packagesIn } from "#codebase/tcmts/cli/manifests";
import { appRoutes, appSchedules, packApp } from "#codebase/tcmts/cli/pack";
import { createHash } from "node:crypto";
import fs from "node:fs";
import path from "node:path";

export function suiteApps(cb: Codebase, namespace: string): string | undefined {
  let pkg;
  try {
    pkg = packagesIn(cb, cb.store.names(undefined, true)).find((p) => p.namespace === namespace);
  } catch {
    return undefined;
  }
  const apps = Object.entries(pkg?.manifest.apps ?? {}).map(([name, rel]) => ({
    name,
    target: absolute(pkg!.namespace, rel),
  }));
  if (!apps.length) return undefined;
  // (and its jobs and routes, packed with it)
  const hashes = apps.map(
    (a) =>
      `${a.name}=${[cb.lookupOne(a.target, "value"), ...[...appSchedules(cb, a.target), ...appRoutes(cb, a.target)].map((s) => s.hash)].join(" ")}`,
  );
  const dir = path.join(
    cb.lay.cacheDir,
    "apps",
    createHash("sha256").update(hashes.join("\n")).digest("hex").slice(0, 16),
  );
  for (const a of apps)
    if (!fs.existsSync(path.join(dir, a.name, "codebase.sqlite")))
      packApp(cb, a.target, path.join(dir, a.name));
  return dir;
}

uses

used by