Ir al contenido

Primeros pasos

Esta guía recorre un ejemplo completo: configurar jsorm.config.ts, definir modelos, insertar registros y ejecutar queries tipadas.

  1. Define modelos

    Importa defineModel y el builder de campos t. La misma definición controla los tipos TypeScript y el comportamiento de queries en runtime.

    // src/schema/main/user.ts
    import { defineModel, t } from 'jsorm';
    export const Role = defineModel('roles', {
    id: t.number().primary(),
    name: t.string().unique(),
    });
    export const User = defineModel('users', {
    id: t.number().primary(),
    name: t.string(),
    email: t.string().optional(),
    active: t.boolean().default(true),
    createdAt: t.date(),
    role: t.belongsTo(Role),
    });

    Exporta tipos inferidos cuando los necesites en otro lugar:

    import type { InferModel, InferInput } from 'jsorm';
    type UserRecord = InferModel<typeof User>;
    // { id: number; name: string; email?: string; active: boolean; createdAt: Date; role: RoleRecord }
    type UserInput = InferInput<typeof User>;
    // { name: string; email?: string; active?: boolean; createdAt: Date; role: { connect: number } | ... }
  2. Crea jsorm.config.ts

    Un archivo de configuración compartido por el singleton runtime y el CLI. Ejecuta jsorm init para generarlo, o escríbelo manualmente:

    // jsorm.config.ts
    import { defineConnectionSource, defineJsormConfig } from 'jsorm';
    import { pgAdapter } from 'jsorm-pg';
    const main = defineConnectionSource({
    adapter: pgAdapter({
    name: 'main',
    connectionString: process.env.DATABASE_URL!,
    pool: { min: 2, max: 10 },
    }),
    });
    export default defineJsormConfig({
    connectionSources: { main },
    defaults: {
    connectionSource: 'main',
    },
    });

    El singleton global jsorm carga este archivo automáticamente desde process.cwd() en el primer uso.

  3. Inserta datos

    Importa jsorm y llama jsorm.insert(). Las relaciones pueden conectarse o crearse inline.

    import { jsorm } from 'jsorm';
    import { User } from './src/schema/index.js';
    // Conectar a un rol existente por ID
    await jsorm.insert(User, {
    name: 'Alice',
    email: 'alice@example.com',
    createdAt: new Date(),
    role: { connect: 1 },
    });
    // Crear un nuevo rol y usuario juntos
    await jsorm.insert(User, {
    name: 'Bob',
    createdAt: new Date(),
    role: { create: { name: 'editor' } },
    });
  4. Lee datos

    Usa jsorm.get(). Cada campo y relación que selecciones está tipado exactamente.

    const users = await jsorm.get(User, {
    select: {
    id: true,
    name: true,
    email: true,
    role: { name: true },
    },
    where: {
    active: true,
    role: { name: { eq: 'admin' } },
    },
    orderBy: [{ name: 'asc' }],
    pagination: {
    perPage: 10,
    currentPage: 1,
    },
    });
    // users.data: Array<{ id: number; name: string; email?: string; role: { name: string } }>
    // users.pagination: { perPage, currentPage, total, lastPage, ... }
  5. Actualiza registros

    Siempre incluye where en operaciones de escritura.

    await jsorm.update(User, {
    data: { active: false },
    where: { role: { name: { eq: 'guest' } } },
    });
  6. Elimina registros

    Los cascades de relación siguen la config onDelete del modelo.

    await jsorm.delete(User, {
    where: { id: { eq: 10 } },
    });

Para queries que el DSL JSON no cubre, usa jsorm.executeSql(). Siempre usa placeholders parametrizados:

const result = await jsorm.executeSql(
'SELECT COUNT(*) AS total FROM users WHERE active = $1',
[true],
);

Usa jsorm.healthCheck() para verificar conectividad — útil en readiness probes y verificación de deploys:

const health = await jsorm.healthCheck();
// { main: 'ok' }

Llama jsorm.close() para drenar los pools de conexión al salir:

process.on('SIGTERM', async () => {
await jsorm.close();
process.exit(0);
});
  1. Importa jsorm una vez desde 'jsorm' — es un singleton global respaldado por jsorm.config.ts.
  2. Usa jsorm.use('name') para apuntar a un connection source diferente al default.
  3. Mantén las cláusulas where explícitas en todas las operaciones de escritura.
  4. Prefiere el DSL JSON tipado; reserva executeSql para queries que genuinamente no puedes expresar con él.
  5. Siempre cierra el pool en el apagado graceful.