104 lines · 2.7 KB · TypeScript
RawDownload
import { type AnyColumn, type AnySchema, IdColumn } from "../schema/create"; export interface ConvexConfig {  type: "convex";} function mapColumnToValidator(column: AnyColumn, tableName: string): string {  // Map FumaDB types to Convex validators  let validator: string;  if (column instanceof IdColumn) {    // Convex id type: v.id("tableName")    validator = `v.id("${tableName}")`;  } else if (    typeof column.type === "string" &&    column.type.startsWith("varchar")  ) {    validator = "v.string()";  } else {    switch (column.type) {      case "uuid":      case "string":        validator = "v.string()";        break;      case "integer":      case "decimal":        validator = "v.number()";        break;      case "bigint":        validator = "v.int64()";        break;      case "bool":        validator = "v.boolean()";        break;      case "json":        validator = "v.any()";        break;      case "binary":        validator = "v.bytes()";        break;      case "date":      case "timestamp":        validator = "v.number()"; // Convex stores timestamps as numbers        break;      default:        validator = "v.any()";    }  }  if (column.isNullable) {    validator = `v.optional(${validator})`;  }  return validator;} export function generateSchema(  schema: AnySchema,  _config: ConvexConfig): string {  // Header imports  const lines: string[] = [    'import { defineSchema, defineTable } from "convex/server";',    'import { v } from "convex/values";',    "",  ];   // Table definitions  const tableDefs: string[] = [];  const tableNames: string[] = [];   for (const table of Object.values(schema.tables)) {    tableNames.push(table.names.convex);    const fields: string[] = [];    for (const column of Object.values(table.columns)) {      const validator = mapColumnToValidator(column, table.names.convex);      fields.push(`  ${column.names.convex}: ${validator},`);    }    tableDefs.push(      `const ${table.names.convex}Table = defineTable({\n${fields.join("\n")}\n})` // indexes will be chained below    );  }   // Indexes  let tableIdx = 0;  for (const table of Object.values(schema.tables)) {    let indexLines = "";    for (const column of Object.values(table.columns)) {      if (column instanceof IdColumn) continue;       indexLines += `\n  .index("by_${column.names.convex}", ["${column.names.convex}"])`;    }    tableDefs[tableIdx] += `${indexLines};\n`;    tableIdx++;  }   // Schema export  lines.push(...tableDefs);  lines.push("");  lines.push(    `export default defineSchema({\n${tableNames      .map((t) => `  ${t}: ${t}Table,`)      .join("\n")}\n});`  );   return lines.join("\n");}