SQL a Zod
Modelado de esquemas y seguridad de tipos

SQL CREATE TABLE DDL to Zod Schema Converter

Traduzca esquemas de tablas SQL, tipos de datos, restricciones y columnas anulables a esquemas de objetos Zod fuertemente tipados en TypeScript.

Preajustes:
Opciones del compilador SQL a Zod y reglas de tipos
postgres•nullable•camel
Entrada(4 tablas)
import { z } from 'zod';

// ============================================================================
// Enums
// ============================================================================

userRoleSchema = z.enum(['SUPERADMIN', 'ORG_ADMIN', 'MEMBER', 'BILLING', 'GUEST']);
UserRole = z.infer<typeof userRoleSchema>;

subscriptionStatusSchema = z.enum(['TRIALING', 'ACTIVE', 'PAST_DUE', 'CANCELED']);
SubscriptionStatus = z.infer<typeof subscriptionStatusSchema>;

// ============================================================================
// Table: organizations
// ============================================================================
organizationsSchema = z.object({
  id: z.string().uuid(),
  slug: z.string().max(64),
  name: z.string().max(255),
  billingEmail: z.string().email().max(255),
  status: subscriptionStatusSchema,
  settings: z.record(z.string(), z.unknown()).nullable(),
  isActive: z.boolean(),
  createdAt: z.coerce.date(),
  updatedAt: z.coerce.date(),
});

Organization = z.infer<typeof organizationsSchema>;

// ============================================================================
// Table: users
// ============================================================================
usersSchema = z.object({
  id: z.string().uuid(),
  organizationId: z.string().uuid(),
  email: z.string().email().max(255),
  fullName: z.string().max(120).nullable(),
  avatarUrl: z.string().url().max(500).nullable(),
  role: userRoleSchema,
  phoneNumber: z.string().max(32).nullable(),
  isVerified: z.boolean(),
  lastLoginAt: z.coerce.date().nullable(),
  createdAt: z.coerce.date(),
});

User = z.infer<typeof usersSchema>;

// ============================================================================
// Table: api_keys
// ============================================================================
apiKeysSchema = z.object({
  id: z.coerce.number().int().positive(),
  organizationId: z.string().uuid(),
  userId: z.string().uuid().nullable(),
  keyPrefix: z.string().max(12),
  hashedSecret: z.string().max(128),
  scopes: z.record(z.string(), z.unknown()),
  expiresAt: z.coerce.date().nullable(),
  revokedAt: z.coerce.date().nullable(),
  createdAt: z.coerce.date(),
});

ApiKey = z.infer<typeof apiKeysSchema>;

// ============================================================================
// Table: audit_logs
// ============================================================================
auditLogsSchema = z.object({
  id: z.coerce.number().int().positive(),
  organizationId: z.string().uuid(),
  actorId: z.string().uuid().nullable(),
  eventName: z.string().max(100),
  ipAddress: z.string().ip().nullable(),
  userAgent: z.string().max(500).nullable(),
  payload: z.record(z.string(), z.unknown()).nullable(),
  createdAt: z.coerce.date(),
});

AuditLog = z.infer<typeof auditLogsSchema>;
Parsed Tables4 schemas ready
Columns Mapped36 campos tipados
Zod Schemas14 validadores inferidos

Ejecución Local de Conocimiento Cero

Todo el procesamiento, análisis y generación de código se ejecutan estrictamente en la memoria del navegador. Cero subidas a servidores externos.

Motor Reactivo de Submilisegundos

All data payloads remain strictly local with zero external server communication.

Production Ready Export

Clean, optimized output formats ready for immediate deployment.

Referencia técnica y guía de arquitectura

Guía para Desarrolladores del Conversor de SQL CREATE TABLE DDL a Esquema Zod — Guía de referencia

Traduzca esquemas de tablas SQL, tipos de datos, restricciones y columnas anulables a esquemas de objetos Zod fuertemente tipados en TypeScript.

Parámetros clave y controles

Dialecto SQLEnum (PostgreSQL | MySQL | SQLite | SQL Server | MariaDB)

Especifica el dialecto SQL de destino para interpretar tipos de datos específicos (como SERIAL, VARCHAR, DATETIME2, JSONB), entrecomillado de identificadores y cláusulas de restricción.

Por defecto: PostgreSQL
Estrategia de NulabilidadEnum (strict-nullable | nullish | optional-defaults)

Determina cómo se traducen las cláusulas NULL y DEFAULT de SQL en modificadores Zod: .nullable() estricto, .nullish() (acepta null o undefined), o .optional() para campos con valores predeterminados o claves autoincrementales.

Por defecto: strict-nullable
Modo de Coerción de TiposBoolean

Envuelve las validaciones primitivas con z.coerce (como z.coerce.number(), z.coerce.date(), z.coerce.boolean()) para convertir automáticamente cadenas de texto de formularios y parámetros de URL.

Por defecto: false
Formato de Destino de FechasEnum (Date Instance (z.date()) | ISO String (z.string().datetime()) | Coerced Date (z.coerce.date()))

Define cómo se validan los tipos TIMESTAMP, DATE y DATETIME de SQL: como instancias nativas de Date en JavaScript, cadenas ISO 8601 o fechas con coerción automática.

Por defecto: Date Instance (z.date())
Generar Tipos InferidosBoolean

Añade automáticamente declaraciones de tipos de TypeScript exportadas mediante z.infer<typeof schema> para operaciones de lectura (select) y creación (insert).

Por defecto: true

Consejos profesionales y mejores prácticas

En bases de datos relacionales

En bases de datos relacionales, las claves primarias con AUTO_INCREMENT o SERIAL y las columnas con DEFAULT se generan automáticamente. Defina un esquema base y derive un esquema de inserción utilizando .omit({ id: true, createdAt: true }) o marcando las columnas generadas como .optional().

El DDL de SQL suele definir datos

El DDL de SQL suele definir datos semiestructurados simplemente como JSON o JSONB, lo que por defecto genera z.record(z.any()) o z.unknown(). Sustitúyalos por subesquemas Zod específicos para garantizar la integridad tipográfica de extremo a extremo.

El tipo Number estándar de JavaScript

El tipo Number estándar de JavaScript pierde precisión más allá de 2^53 - 1. Al convertir columnas SQL BIGINT o NUMERIC / DECIMAL, asigne identificadores a z.bigint() o z.string() y valores monetarios a cadenas con validación regular (ej. z.string().regex(/^\d+\.\d{2}$/)).

Si su base de datos utiliza

Si su base de datos utiliza convenciones snake_case pero su código en TypeScript utiliza camelCase, utilice transformaciones de Zod (.transform((data) => ({ ... }))) o canalizaciones (.pipe()) para normalizar las claves en tiempo de ejecución sin alterar la estructura SQL.

Errores comunes y solución de problemas

ZodError: Expected date, received string al procesar cuerpos de solicitudes API o JSON

Los cuerpos JSON transmiten fechas como cadenas ISO 8601, las cuales fallan la validación directa con z.date(). Cambie el formato de destino de fechas a 'ISO String (z.string().datetime())' o active el Modo de Coerción de Tipos (z.coerce.date()) para instanciar objetos Date automáticamente.

Los tipos ENUM de PostgreSQL o dominios personalizados generan errores de análisis

Asegúrese de incluir las declaraciones CREATE TYPE previas o las restricciones CHECK de columna dentro del DDL de entrada. El conversor traducirá los enums de PostgreSQL y las cláusulas CHECK (col IN (...)) a z.enum([...]) automáticamente.

Las claves primarias autoincrementales fallan la validación en operaciones de inserción

Las columnas SERIAL o IDENTITY se definen como NOT NULL en la base de datos pero se omiten en las solicitudes de inserción del cliente. Configure la Estrategia de Nulabilidad en 'optional-defaults' o cree un esquema de inserción derivado con .omit({ id: true }).

Preguntas frecuentes (FAQ)

¿Cómo traduce el conversor las columnas anulables y NOT NULL de SQL a Zod?▼

Las columnas sin restricción NOT NULL son anulables en SQL y se marcan con .nullable() en Zod. Las columnas con cláusulas DEFAULT o autoincrementales pueden configurarse como .optional() o .nullish() (que acepta tanto null como undefined), adaptándose a las cargas útiles de creación de registros.

¿Cuál es la diferencia entre z.date(), z.coerce.date() y z.string().datetime()?▼

z.date() exige que la entrada sea ya una instancia de Date en JavaScript (habitual en resultados de ORMs como Drizzle o Prisma). z.string().datetime() valida cadenas con formato ISO 8601 sin transformarlas. z.coerce.date() acepta cadenas, números de timestamp o fechas e invoca internamente new Date(val).

¿Se pueden utilizar los esquemas generados con ORMs como Drizzle, Prisma o Kysely?▼

Sí, totalmente. Los esquemas generados proporcionan validación en tiempo de ejecución para endpoints de API, Server Actions o controladores antes de transferir datos tipados y verificados a las consultas de su ORM.

¿Se envía alguna definición DDL o esquema SQL a servidores externos?▼

No. El análisis sintáctico de SQL, la extracción de AST y la generación del código TypeScript se ejecutan al 100% en el navegador del cliente mediante Web Workers locales. Ningún esquema ni dato de base de datos sale de su equipo.

¿Cómo se gestionan las restricciones CHECK y las claves foráneas de SQL?▼

Las restricciones CHECK con listas de valores (por ejemplo, CHECK (status IN ('active', 'inactive'))) se convierten en z.enum(). Las restricciones numéricas se transforman en refinamientos como .min() o .max(). Las columnas de clave foránea conservan su tipo escalar base, como z.string().uuid() o z.number().int().

Herramientas y utilidades relacionadas

Todas las herramientas →