Modelos
Fuente de verdad para tipos y queries
Sección titulada «Fuente de verdad para tipos y queries»Los modelos son la única fuente de verdad en jsorm. Una definición de modelo controla tanto los tipos TypeScript como el comportamiento de queries en runtime.
Definir un modelo
Sección titulada «Definir un modelo»import type { InferInput, InferModel } from 'jsorm';import { defineModel, t } from 'jsorm';
const User = defineModel('users', { id: t.number().primary(), name: t.string(), email: t.string().optional(), active: t.boolean().default(true), createdAt: t.date(), score: t.number().nullable(),});
type UserRecord = InferModel<typeof User>;// {// id: number;// name: string;// email?: string;// active: boolean;// createdAt: Date;// score: number | null;// }
type UserInput = InferInput<typeof User>;// {// name: string;// email?: string;// active?: boolean;// createdAt: Date;// score?: number | null;// }// Nota: claves primarias y campos de relación excluidos de InferInput; columnas FK se mantienenBuilders de campo
Sección titulada «Builders de campo»| Builder | Tipo TypeScript | Notas |
|---|---|---|
t.string() | string | Equivalente a VARCHAR |
t.text() | string | Texto sin límite / columna TEXT |
t.number() | number | Numérico / FLOAT |
t.boolean() | boolean | |
t.date() | Date | Solo fecha |
t.time() | string | Cadena de tiempo HH:MM:SS |
t.dateTime() | Date | Timestamp completo |
t.uuid() | string | Cadena UUID |
t.autoIncrement() | number | Entero auto-incremental |
t.enum(['a', 'b'] as const) | 'a' | 'b' | Unión de strings, verificada en runtime |
t.json() | unknown | Almacenado como JSON, retornado como objeto |
t.belongsTo(Model) | ModelRecord | FK → padre |
t.hasOne(Model) | ModelRecord | Inverso de belongsTo |
t.hasMany(Model) | ModelRecord[] | One-to-many |
t.manyToMany(Model) | ModelRecord[] | Many-to-many vía tabla junction |
Modificadores de campo
Sección titulada «Modificadores de campo»t.string() .optional() // undefined permitido; excluido de input requerido .nullable() // null permitido en tipo y DB .primary() // marca como clave primaria (excluido de InferInput) .default('unknown') // valor por defecto; hace el input opcional .unique() // constraint UNIQUE en migraciones .index() // INDEX en migracionesModelo con modificadores comunes
Sección titulada «Modelo con modificadores comunes»const Post = defineModel('posts', { id: t.autoIncrement().primary(), title: t.string(), slug: t.string().unique(), body: t.text().optional(), status: t.enum(['draft', 'published', 'archived'] as const).default('draft'), published: t.boolean().default(false), viewCount: t.number().default(0), publishedAt: t.dateTime().nullable(), deletedAt: t.date().nullable(), metadata: t.json(),});Relaciones
Sección titulada «Relaciones»const Role = defineModel('roles', { id: t.number().primary(), name: t.string().unique(),});
const User = defineModel('users', { id: t.number().primary(), name: t.string(), // belongsTo: columna FK en esta tabla role: t.belongsTo(Role, { onUpdate: 'cascade', onDelete: 'restrict', constraintName: 'fk_users_role_id', // nombre explícito para migraciones }).index(),});
const Tag = defineModel('tags', { id: t.number().primary(), name: t.string(),});
const Article = defineModel('articles', { id: t.number().primary(), title: t.string(), tags: t.manyToMany(Tag), author: t.belongsTo(User),});Organizar modelos
Sección titulada «Organizar modelos»Para proyectos grandes, co-ubica los modelos cerca de los límites de dominio:
src/ schema/ main/ user.ts ← defineModel('users', {...}) role.ts posts/ article.ts tag.ts index.ts ← re-exporta todos los modelosjsorm.config.ts ← define connectionSources, migrationSources, modelsBuenas prácticas
Sección titulada «Buenas prácticas»- Mantén los nombres de tabla estables y explícitos — renombra solo a través de migraciones.
- Usa
t.autoIncrement().primary()para PKs enteros auto-incrementales. - Usa
t.uuid()para claves primarias UUID. - Prefiere
InferModel/InferInputinferidos en lugar de interfaces manuales. - Un modelo por archivo en proyectos grandes; co-ubica modelos pequeños relacionados.
- Agrega
constraintNameexplícito enbelongsTocuando necesites nombres predecibles en migraciones.