lume-orm
v1.0.1
Published
ORM similar a Laravel Eloquent para Node.js con TypeScript y Turso
Downloads
4
Maintainers
Readme
🌟 Lume ORM
Un ORM moderno para TypeScript inspirado en Laravel Eloquent, diseñado específicamente para trabajar con Turso (SQLite en la nube).
✨ 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-token2. 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:
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/nueva-funcionalidad) - Commit tus cambios (
git commit -am 'Añadir nueva funcionalidad') - Push a la rama (
git push origin feature/nueva-funcionalidad) - Abre un Pull Request
📄 Licencia
MIT - ver el archivo LICENSE para más detalles.
🔗 Enlaces
- Turso - Base de datos SQLite en la nube
- Knex.js - Query builder para JavaScript
- TypeScript - JavaScript tipado
Hecho con ❤️ por Juan Beresiarte
