Skip to the content

Capsid menu

app/db/registry.ts

53 lines and 6 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of registry.ts
FunctionLinesComplexityCoveredCRAPMutation
listRegistry14 to 244No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
listPublishedRegistrySources27 to 331No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:32>32 to 321No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
getRegistryItem36 to 432No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
listRegistryRows46 to 591No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:58>58 to 581No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code

Imports

It imports app/db/client.ts, app/db/schema.ts, app/kb/registry/compile.mjs. Imported by app/kb/form.server.ts, app/kb/registry/save.server.ts, app/lab/inventory.server.ts, app/lib/carrel/registry-handler.server.ts, app/lib/operator/api.server.ts, app/lib/site-urls.server.ts, app/routes/admin.kb.tsx, app/routes/lab.kind.tsx, app/routes/lab.tsx, app/routes/lab[.md].ts, app/routes/protocols.tsx.

Source

// The registry table: read by the registry's pages and the operator API. Written only by writeRegistryRow in
// app/kb/registry/save.server.ts and by sync:content, from a compile (app/kb/registry/compile.mjs).
import { and, asc, eq } from "drizzle-orm";

import { itemFromRow, sortRegistry, type RegistryItem } from "~/kb/registry/compile.mjs";

import { getDb } from "./client";
import { registry } from "./schema";

/**
 * Every item, or one kind's, in the site's order. Drafts are the signed-in admin's alone, so a public read passes
 * `published: true`. An empty table is a valid answer: the registry has no records until a kind brings its own.
 */
export async function listRegistry(env: Env, options: { kind?: string; published?: boolean } = {}): Promise<RegistryItem[]> {
  const where = [
    ...(options.kind ? [eq(registry.kind, options.kind)] : []),
    ...(options.published ? [eq(registry.status, "published")] : []),
  ];
  const rows = await getDb(env)
    .select({ kind: registry.kind, id: registry.id, name: registry.name, status: registry.status, record: registry.record })
    .from(registry)
    .where(where.length > 0 ? and(...where) : undefined);
  return sortRegistry(rows.map(itemFromRow));
}

/** For the sitemap's dates (app/lib/site-urls.server.ts): every published item's source file, by `kind/id`. */
export async function listPublishedRegistrySources(env: Env) {
  const rows = await getDb(env)
    .select({ kind: registry.kind, id: registry.id, sourcePath: registry.sourcePath })
    .from(registry)
    .where(eq(registry.status, "published"));
  return new Map(rows.map((row) => [`${row.kind}/${row.id}`, row.sourcePath]));
}

/** One item by its address, or null. */
export async function getRegistryItem(env: Env, kind: string, id: string): Promise<RegistryItem | null> {
  const row = await getDb(env)
    .select({ kind: registry.kind, id: registry.id, name: registry.name, status: registry.status, record: registry.record })
    .from(registry)
    .where(and(eq(registry.kind, kind), eq(registry.id, id)))
    .get();
  return row ? itemFromRow(row) : null;
}

/** For list_registry and Carrel's list: every row, with when D1 last wrote it. */
export async function listRegistryRows(env: Env) {
  const rows = await getDb(env)
    .select({
      kind: registry.kind,
      id: registry.id,
      name: registry.name,
      status: registry.status,
      record: registry.record,
      syncedAt: registry.syncedAt,
    })
    .from(registry)
    .orderBy(asc(registry.kind), asc(registry.name));
  return rows.map(({ syncedAt, ...row }) => ({ ...itemFromRow(row), syncedAt }));
}