@lactose/milk-orm
v0.4.0
Published
Milk is an ORM built with bun! It aim's to be very lightweight, and simple... It’s designed for small projects, quick dev tools, and anyone who needs a quick schema def.
Downloads
37
Readme
🥛 @lactose/milk-orm
Milk is an ORM built with bun! It aim's to be very lightweight, and simple... It’s designed for small projects, quick dev tools, and anyone who needs a quick schema def.
🚩 Early Preview Milk is very, very early in development. Expect bugs and lots of missing features. Still - you're welcome to try it and help it grow! :)
Quick Start
Install Milk
bun add @lactose/milk-ormInit project
bunx @lactose/milk-orm initwhich will create:
milk.config.ts
milk/
├─ milk.db
├─ models/
│ └─ Example.ts
├─ seed.tsDefine a Model
import { Use } from "@lactose/milk-orm";
import { text, bool, integer, timestamped } from "@lactose/milk-orm/core";
@Use()
export class Task {
title = text(100, { unique: true });
is_done = bool({ default: false });
order = integer({ nullable: true });
createdAt = timestamped();
}Sync Schema
import { sync } from "@lactose/milk-orm";
await sync(); // Creates tables if they don't existInsert Data
import { insert } from "@lactose/milk-orm";
await insert("Task", {
title: "Ship Milk ORM",
is_done: false,
});Select Data
import { select } from "@lactose/milk-orm";
const openTasks = await select("Task").where({ is_done: false }).all();Query Operators
// Comparison operators
select("User").where("age", ">", 18).all();
select("User").where("age", ">=", 21).all();
select("User").where("age", "<", 65).all();
select("User").whereNot("status", "banned").all();
// IN / NOT IN
select("User").whereIn("role", ["admin", "mod"]).all();
select("User").whereNotIn("status", ["deleted", "banned"]).all();
// LIKE (pattern matching)
select("User").whereLike("email", "%@gmail.com").all();
// NULL checks
select("User").whereNull("deletedAt").all();
select("User").whereNotNull("email").all();
// OR conditions
select("User")
.where({ status: "active" })
.orWhere({ role: "admin" })
.all();
// Counting
const count = await select("Task").where({ is_done: false }).count();Update Data
import { update } from "@lactose/milk-orm";
// Update specific records
await update("Task")
.set({ is_done: true })
.where({ title: "Ship Milk ORM" })
.run();
// Update all (requires explicit .all() for safety)
await update("Task").set({ is_done: false }).all();Delete Data
import { remove } from "@lactose/milk-orm";
// Delete specific records
await remove("Task").where({ is_done: true }).run();
// Delete all (requires explicit .all() for safety)
await remove("Task").all();Transactions
import { transaction } from "@lactose/milk-orm";
// Automatically commits on success, rolls back on error
await transaction(async () => {
await insert("Order", { userId: 1, total: 99.99 });
await insert("OrderItem", { orderId: 1, product: "Widget" });
// If anything throws, both inserts are rolled back
});Roadmap
@Use()to support custom plugins ex.@Use(Timestamped, UUIDPrimaryKey)- Schema-aware validation
- Migrations (hopefully at some point)
- Type-safe
select()andinsert()and autocompletion
License
MIT - feel free to use, fork, do as you please :)
Contributing
HELLO, SO GLAD YOU'RE HERE 💖 -- I am not great at programming so feel free to suggest a full rework of anything.
Local Setup
Open a PR!! Suggest a feature, my discord is MrGandolfio 🍥
git clone [email protected]:parkerfreestone/milk-orm.git
cd milk-orm
bun install
# Make sure build runs
bun run build
# Run tests
bun test