npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lume-orm

v1.0.1

Published

ORM similar a Laravel Eloquent para Node.js con TypeScript y Turso

Downloads

4

Readme

🌟 Lume ORM

Un ORM moderno para TypeScript inspirado en Laravel Eloquent, diseñado específicamente para trabajar con Turso (SQLite en la nube).

npm version TypeScript License: MIT

✨ Características

  • 🎯 Patrón Active Record similar a Laravel Eloquent
  • 🚀 TypeScript nativo con tipado completo
  • 🔥 Optimizado para Turso (SQLite en la nube)
  • 🛠️ Query Builder potente y flexible
  • 📦 Sin dependencias pesadas - solo Knex para generar SQL
  • 🎨 API intuitiva y fácil de usar

📦 Instalación

npm install lume-orm

🚀 Configuración rápida

1. Variables de entorno

Crea un archivo .env con tus credenciales de Turso:

TURSO_DB_URL=libsql://your-database-name.turso.io
TURSO_DB_AUTH_TOKEN=your-auth-token

2. Configuración básica

import { createDatabase } from "lume-orm";

// Usando variables de entorno (recomendado)
const db = createDatabase();

// O configuración manual
const db = createDatabase({
  url: "libsql://your-database-name.turso.io",
  authToken: "your-auth-token",
});

📚 Uso básico

Crear un modelo

import { Model } from "lume-orm";

class User extends Model {
  protected static table = "users";
  protected static fillable = ["name", "email", "password"];
  protected static hidden = ["password"];

  // Tipado para autocompletado
  declare id: number;
  declare name: string;
  declare email: string;
  declare password: string;
  declare created_at: Date;
  declare updated_at: Date;
}

Crear la tabla (SQL)

CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL,
    password TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

🔧 Operaciones CRUD

Crear registros

// Crear un usuario
const user = await User.create({
  name: "Juan Pérez",
  email: "[email protected]",
  password: "secreto123",
});

console.log(user.id); // ID autogenerado
console.log(user.name); // 'Juan Pérez'

// Crear múltiples usuarios
const users = await User.createMany([
  { name: "Ana García", email: "[email protected]", password: "pass123" },
  { name: "Carlos López", email: "[email protected]", password: "pass456" },
]);

// Crear o actualizar
const user = await User.updateOrCreate(
  { email: "[email protected]" }, // Condición de búsqueda
  { name: "Juan Pérez Updated" } // Datos a actualizar/crear
);

Leer registros

// Obtener todos los usuarios
const allUsers = await User.all();

// Obtener por ID
const user = await User.find(1);
if (user) {
  console.log(user.name);
}

// Obtener por ID o lanzar error
const user = await User.findOrFail(1);

// Obtener múltiples por IDs
const users = await User.findMany([1, 2, 3]);

// Buscar el primero que coincida
const user = await User.query().where("email", "[email protected]").first();

Actualizar registros

// Actualizar una instancia
const user = await User.find(1);
if (user) {
  user.name = "Nuevo Nombre";
  user.email = "[email protected]";
  await user.save();
}

// Actualizar con fill()
const user = await User.find(1);
if (user) {
  user.fill({
    name: "Otro Nombre",
    email: "[email protected]",
  });
  await user.save();
}

// Actualización masiva
await User.query()
  .where("created_at", "<", "2023-01-01")
  .update({ updated_at: new Date() });

Eliminar registros

// Eliminar una instancia
const user = await User.find(1);
if (user) {
  await user.delete();
}

// Eliminar por ID(s)
await User.destroy(1); // Un solo ID
await User.destroy([1, 2, 3]); // Múltiples IDs

// Eliminación con condiciones
await User.query().where("created_at", "<", "2023-01-01").delete();

// Limpiar toda la tabla (¡Cuidado!)
await User.truncate();

🔍 Consultas avanzadas

Filtros y condiciones

// WHERE básico
const users = await User.where("name", "Juan");
const users = await User.where("age", ">", 18);
const users = await User.where("active", true);

// WHERE con objeto (múltiples condiciones)
const users = await User.where({
  active: true,
  role: "admin",
});

// Query builder para consultas complejas
const users = await User.query()
  .where("name", "like", "%Juan%")
  .where("age", ">=", 18)
  .whereNotNull("email")
  .whereIn("role", ["admin", "moderator"])
  .get();

// WHERE con OR
const users = await User.query()
  .where("role", "admin")
  .orWhere("role", "moderator")
  .get();

Ordenamiento y límites

// Ordenar resultados
const users = await User.query()
  .orderBy("name", "asc")
  .orderBy("created_at", "desc")
  .get();

// Límites y paginación
const users = await User.query().limit(10).offset(20).get();

// Solo columnas específicas
const users = await User.query()
  .select("id", "name", "email")
  .where("active", true)
  .get();

Agregaciones

// Contar registros
const count = await User.query().count();
const activeCount = await User.query().where("active", true).count();

// Otras agregaciones
const avgAge = await User.query().avg("age");
const maxAge = await User.query().max("age");
const minAge = await User.query().min("age");
const totalAge = await User.query().sum("age");

// Verificar existencia
const hasAdmins = await User.query().where("role", "admin").exists();

Consultas útiles

// Obtener solo una columna
const emails = await User.query().pluck("email");
// Resultado: ['[email protected]', '[email protected]', ...]

// Buscar o crear
const user = await User.firstOrCreate(
  { email: "[email protected]" },
  { name: "Usuario Nuevo", password: "temporal" }
);

// Valores únicos
const users = await User.query().distinct("role").get();

🔧 Métodos de utilidad

Trabajo con atributos

const user = await User.find(1);

// Verificar cambios
if (user.isDirty()) {
  console.log("El modelo ha sido modificado");
}

if (user.isDirty("email")) {
  console.log("El email ha sido modificado");
}

// Obtener cambios
const changes = user.getDirty();
console.log(changes); // { email: '[email protected]' }

// Obtener atributos
const attributes = user.getAttributes();
const original = user.getOriginal();

// Recargar desde la base de datos
await user.refresh();

Serialización

const user = await User.find(1);

// A JSON (excluye campos hidden)
const json = user.toJSON();
console.log(json); // No incluye 'password'

// A array (alias de toJSON)
const array = user.toArray();

⚙️ Configuración avanzada

Cliente de base de datos personalizado

import { createDatabase, Model } from "lume-orm";

// Crear cliente personalizado
const customDb = createDatabase({
  url: "libsql://other-database.turso.io",
  authToken: "other-token",
});

// Configurar para un modelo específico
User.setDatabaseClient(customDb);

// O para todos los modelos
Model.setDatabaseClient(customDb);

Múltiples conexiones

// Base de datos principal
const mainDb = createDatabase({
  url: process.env.MAIN_DB_URL,
  authToken: process.env.MAIN_DB_TOKEN,
});

// Base de datos de analytics
const analyticsDb = createDatabase({
  url: process.env.ANALYTICS_DB_URL,
  authToken: process.env.ANALYTICS_DB_TOKEN,
});

// Modelos usando diferentes conexiones
class User extends Model {
  protected static table = "users";
  protected static dbClient = mainDb;
}

class Event extends Model {
  protected static table = "events";
  protected static dbClient = analyticsDb;
}

🔒 Campos fillable y hidden

Fillable (campos asignables masivamente)

class User extends Model {
  protected static fillable = ["name", "email"];

  // Solo estos campos se pueden asignar con fill() o create()
}

const user = new User();
user.fill({
  name: "Juan",
  email: "[email protected]",
  password: "secreto", // ❌ Ignorado, no está en fillable
  role: "admin", // ❌ Ignorado, no está en fillable
});

Hidden (campos ocultos en serialización)

class User extends Model {
  protected static hidden = ["password", "secret_token"];
}

const user = await User.find(1);
const json = user.toJSON();
// json no incluirá 'password' ni 'secret_token'

📊 Debugging

Ver SQL generado

// Obtener SQL sin ejecutar
const query = User.query().where("active", true).orderBy("name");

const { sql, bindings } = query.toSql();
console.log(sql); // SELECT * FROM users WHERE active = ? ORDER BY name ASC
console.log(bindings); // [true]

🤝 Contribuir

¡Las contribuciones son bienvenidas! Por favor:

  1. Fork el proyecto
  2. Crea una rama para tu feature (git checkout -b feature/nueva-funcionalidad)
  3. Commit tus cambios (git commit -am 'Añadir nueva funcionalidad')
  4. Push a la rama (git push origin feature/nueva-funcionalidad)
  5. Abre un Pull Request

📄 Licencia

MIT - ver el archivo LICENSE para más detalles.

🔗 Enlaces


Hecho con ❤️ por Juan Beresiarte