tableOptions

tcmts.core.analyze.tableOptions · #g36ycmx6 · term · runs anywhere

What a table's options literal says about migration steps, constraints and renames.

import { typeSchema } from "#codebase/tcmts/core/schema";
import type { TableSchema } from "#codebase/tcmts/core/schema";
import type { TypeChecker } from "#codebase/tcmts/core/ts";
import {
  isArrayLiteralExpression as ts_isArrayLiteralExpression, isIdentifier as ts_isIdentifier,
  isObjectLiteralExpression as ts_isObjectLiteralExpression, isPropertyAssignment as ts_isPropertyAssignment,
  isStringLiteralLikeNode as ts_isStringLiteralLike,
} from "typescript/ast";
import type { Expression as ts_Expression } from "typescript/ast";

export function tableOptions(opts: ts_Expression | undefined, checker: TypeChecker): Partial<TableSchema> {
  if (!opts || !ts_isObjectLiteralExpression(opts)) return {};
  const out: Partial<TableSchema> = {};
  const strings = (e: ts_Expression) => (ts_isArrayLiteralExpression(e) ? e.elements.filter(ts_isStringLiteralLike).map((x) => x.text) : []);
  for (const p of opts.properties) {
    if (!ts_isPropertyAssignment(p) || !ts_isIdentifier(p.name)) continue;
    const v = p.initializer;
    if (p.name.text === "migrate") {
      // each step's parameter type: what a row must look like for that step to take it
      const fns = ts_isArrayLiteralExpression(v) ? [...v.elements] : [v];
      out.steps = fns.map((f) => {
        const param = checker.getTypeAtLocation(f).getCallSignatures()[0]?.getParameters()[0];
        return param ? typeSchema(checker, checker.getTypeOfSymbolAtLocation(param, f)) : { s: { t: "any" }, defs: [] };
      });
    } else if (p.name.text === "unique" || p.name.text === "index") out[p.name.text] = strings(v);
    else if (p.name.text === "renamedFrom" && ts_isStringLiteralLike(v)) out.renamedFrom = v.text;
  }
  return out;
}

uses

used by