resolveLibrary

tcmts.cli.libraries.resolveLibrary · #yxt6fkst · term · runs anywhere

What what names on a remote: a release (geo@1.2.0, or geo for its newest), or a namespace by its whole hash (#…). A release is its package's namespace in the history entry it names.

import { releaseNamespace } from "#codebase/tcmts/cli/libraries";
import type { Remote } from "#codebase/tcmts/cli/sync";
import { UsageError } from "#codebase/tcmts/cli/ui";

export async function resolveLibrary(
  remote: Remote,
  what: string,
): Promise<{ namespace: string; release?: string }> {
  if (what.startsWith("#")) {
    const h = what.replace(/^#+/, "");
    if ((await remote.missingNamespaces([h])).length)
      throw new UsageError(
        `${remote.label} has no namespace #${h} (a library by hash is its namespace's whole hash)`,
      );
    return { namespace: h };
  }
  const at = what.lastIndexOf("@");
  const pkg = at > 0 ? what.slice(0, at) : what;
  const version = at > 0 ? what.slice(at + 1) : undefined;
  const releases = (await remote.releases())
    .filter((r) => r.package === pkg)
    .sort((a, b) => b.ts - a.ts);
  const r = version === undefined ? releases[0] : releases.find((x) => x.version === version);
  if (!r)
    throw new UsageError(
      releases.length
        ? `${remote.label} has no ${pkg}@${version}; it has ${releases.map((x) => x.version).join(", ")}`
        : `${remote.label} has no releases of ${pkg}`,
    );
  const namespace = await releaseNamespace(remote, r, remote.label);
  return { namespace, release: `${pkg}@${r.version}` };
}

uses

used by