Skip to the content

Capsid menu

app/lab/actor.server.ts

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

Functions

The functions of actor.server.ts
FunctionLinesComplexityCoveredCRAPMutation
primaryOwnerSet15 to 171No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
labRules20 to 222No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
loadLabActor28 to 321No 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/members.ts, app/lab/titles.mjs. Imported by app/lab/members.server.ts, app/routes/workspace._index.tsx, app/routes/workspace.inventory.lot.tsx, app/routes/workspace.inventory.tsx, app/routes/workspace.members.tsx, app/routes/workspace.runs.run.tsx, app/routes/workspace.runs.tsx, app/routes/workspace.tsx.

Source

import { createContext } from "react-router";
import { normalizeEmail, resolveActor, type Actor } from "@dustinedwards/site-runtime/members";

import { getMember } from "~/db/members";

import { LAB_CATALOG } from "./titles.mjs";

/**
 * Who is asking in /lab, set by the workspace layout's middleware once Access and the person's row have both said yes.
 * Handlers ask `can(actor, PERMISSION.x)` of it and nothing else.
 */
export const labActorContext = createContext<Actor>();

/** Whether the Primary Owner is configured; without it /lab admits nobody, the Primary Owner included. */
export function primaryOwnerSet(env: Env): boolean {
  return !!env.PRIMARY_OWNER_EMAIL?.trim();
}

/** The lab's catalog and Primary Owner, as site-runtime's rules take them. */
export function labRules(env: Env, nowMs: number) {
  return { catalog: LAB_CATALOG, primaryOwnerEmail: env.PRIMARY_OWNER_EMAIL ?? "", nowMs };
}

/**
 * The person's row, read now and uncached, through site-runtime's `resolveActor`: the Primary Owner from
 * PRIMARY_OWNER_EMAIL, anyone else by an active, unexpired row. Null is "no access".
 */
export async function loadLabActor(env: Env, email: string, nowMs: number): Promise<Actor | null> {
  const who = normalizeEmail(email);
  const row = await getMember(env, who);
  return resolveActor(who, row, labRules(env, nowMs));
}