rowFields

tcmts.cli.data_pages.rowFields · #vg2b6oxl · term · runs anywhere

A table's row fields as a form edits them (RowField), from its row type; none if its rows aren't objects.

import type { RowField } from "#codebase/tcmts/cli/data_pages";
import { schemaText } from "#codebase/tcmts/core/schema";
import type { Schema, TableSchema } from "#codebase/tcmts/core/schema";

export function rowFields(t: TableSchema): RowField[] {
  const resolve = (s: Schema): Schema =>
    s.t === "ref" && t.defs[s.id] ? resolve(t.defs[s.id]!) : s;
  const row = resolve(t.s);
  if (row.t !== "object") return [];
  return Object.entries(row.props).map(([name, p]) => {
    let s = resolve(p.s);
    let nullable = false;
    let optional = p.optional;
    if (s.t === "union") {
      const rest = s.of.map(resolve).filter((m) => {
        if (m.t === "null") nullable = true;
        if (m.t === "undefined") optional = true;
        return m.t !== "null" && m.t !== "undefined";
      });
      s = rest.length === 1 ? rest[0]! : { t: "union", of: rest };
    }
    const literals =
      s.t === "union" && s.of.every((m) => m.t === "literal")
        ? s.of.map((m) => (m as { value: string | number | boolean }).value)
        : undefined;
    const input: RowField["input"] =
      s.t === "string"
        ? "text"
        : s.t === "number"
          ? "number"
          : s.t === "boolean"
            ? "boolean"
            : s.t === "date"
              ? "date"
              : literals || s.t === "literal"
                ? "choice"
                : "json";
    return {
      name,
      type: schemaText(p.s, t.defs).replace(/^undefined \| | \| undefined$/, ""),
      input,
      ...(input === "choice"
        ? { choices: literals ?? [(s as { value: string | number | boolean }).value] }
        : {}),
      optional,
      nullable,
    };
  });
}

uses

used by