packApp

tcmts.cli.pack.packApp · #bt5mmluz · term · runs on the server

uses tcmts.cli.roles.manifestsIn, which uses tcmts.cli.config.configValue, which uses node:path

Ship an app of the codebase (app, a name) in a package: a codebase holding only it and what it uses, everything it runs on pinned as here, the app named app, written to out/codebase.sqlite. tcm start app there runs it (building it the first time), with the recurring jobs (every(...)) of its namespace, named as there (the app's ns.ingest as ingest), so tcm start runs them too, and its HTTP routes (appRoutes: ns.http.oauth.client as http.oauth.client), and the manifests giving what it uses a role (the react library's Stylesheet), named as here with what they give one, so its build treats them as here. Says how many definitions it holds.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { appRoutes, appSchedules, shipCodebase, SHIPPED_APP } from "#codebase/tcmts/cli/pack";
import { manifestsIn } from "#codebase/tcmts/cli/roles";

export function packApp(cb: Codebase, app: string, out: string): number {
  const hash = cb.lookupOne(app, "value");
  const schedules = appSchedules(cb, app);
  const routes = appRoutes(cb, app);
  const roots = [hash, ...schedules.map((s) => s.hash), ...routes.map((r) => r.hash)];
  const used = new Set(cb.closureComponents(roots));
  const rows = cb.store.names();
  const named = new Map(rows.filter((r) => r.kind !== "type").map((r) => [r.path, r.hash]));
  const roled = manifestsIn(cb, rows).flatMap(({ namespace, manifest }) => {
    const path = (n: string) => (namespace ? `${namespace}.${n}` : n);
    const given = Object.keys(manifest.roles ?? {})
      .map(path)
      .filter((p) => {
        const h = named.get(p);
        return h !== undefined && used.has(cb.store.getDef(h)!.componentHash);
      });
    return given.length ? [path("manifest"), ...given] : [];
  });
  return shipCodebase(cb, [...roots, ...roled.map((p) => named.get(p)!)], out, (target) => {
    target.store.addName(SHIPPED_APP, hash, "term", `add ${SHIPPED_APP} (${app})`);
    for (const s of schedules) {
      const leaf = s.path.slice(s.path.lastIndexOf(".") + 1);
      if (leaf !== SHIPPED_APP)
        target.store.addName(leaf, s.hash, "term", `add ${leaf} (${s.path})`);
    }
    const ns = app.includes(".") ? app.slice(0, app.lastIndexOf(".") + 1) : "";
    for (const r of routes) {
      const name = r.path.slice(ns.length);
      target.store.addName(name, r.hash, "term", `add ${name} (${r.path})`);
    }
    for (const p of roled) target.store.addName(p, named.get(p)!, "term", `add ${p}`);
  });
}

uses

used by