
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A modern SQLite wrapper for Bun with query builder, schema management, and transaction support.
import { createMemoryDatabase } from "bunely";
// Create a database
const db = createMemoryDatabase();
// Enable foreign keys
db.enableForeignKeys();
// Create tables using schema builder
await db.schema.createTable("users")
.ifNotExists(true)
.addColumn({
name: "id",
type: "INTEGER",
primaryKey: true,
autoIncrement: true
})
.addColumn({
name: "username",
type: "TEXT",
notNull: true,
unique: true
})
.addColumn({
name: "email",
type: "TEXT",
notNull: true,
unique: true
})
.execute();
// Insert data using query builder
const user = await db.insert("users")
.values({
username: "alice",
email: "alice@example.com"
})
.execute();
// Query data
const users = await db.select()
.from("users")
.where({ username: "alice" })
.execute();
// Use transactions
await db.transaction(async (tx) => {
await tx.insert("users").values({ username: "bob", email: "bob@example.com" }).execute();
await tx.insert("users").values({ username: "charlie", email: "charlie@example.com" }).execute();
});
bun add bunely
import { createMemoryDatabase, createFileDatabase, createDatabase } from "bunely";
import { Database as SQLiteDatabase } from "bun:sqlite";
// In-memory database
const db = createMemoryDatabase();
// File-based database
const db = createFileDatabase("database.sqlite");
// From existing SQLite database
const sqliteDb = new SQLiteDatabase("database.sqlite");
const db = createDatabase(sqliteDb);
// Simple select
const users = await db.select()
.from("users")
.execute();
// Select with conditions (object syntax)
const alice = await db.select()
.from("users")
.where({ username: "alice" })
.first();
// Select with explicit where conditions
const aliceExplicit = await db.select()
.from("users")
.where("username", "=", "alice")
.first();
// Select with joins
const postsWithUsers = await db.select([
"p.title",
"u.username"
])
.from("posts as p")
.join("users as u", "p.user_id = u.id")
.execute();
// Complex queries
const recentPosts = await db.select()
.from("posts")
.where({ status: "published" })
.orderBy(["created_at DESC"])
.limit(10)
.execute();
// Explicit where conditions with operators
const adults = await db.select()
.from("users")
.where("age", ">", 18)
.where("is_active", "=", true)
.execute();
// LIKE operators
const aliceUsers = await db.select()
.from("users")
.where("username", "LIKE", "alice%")
.execute();
// IN operators
const specificUsers = await db.select()
.from("users")
.where("id", "IN", [1, 2, 3])
.execute();
// BETWEEN operators
const middleAged = await db.select()
.from("users")
.where("age", "BETWEEN", 25, 65)
.execute();
// NULL operators
const usersWithEmail = await db.select()
.from("users")
.where("email", "IS NOT NULL")
.execute();
Bunely supports the following operators for explicit where conditions:
Comparison Operators:
= - Equal to!= or <> - Not equal to< - Less than> - Greater than<= - Less than or equal to>= - Greater than or equal toPattern Matching:
LIKE - Pattern matching (use % for wildcards)NOT LIKE - Negated pattern matchingSet Operations:
IN - Value is in a listNOT IN - Value is not in a listRange Operations:
BETWEEN - Value is between two values (inclusive)NOT BETWEEN - Value is not between two valuesNull Operations:
IS NULL - Value is nullIS NOT NULL - Value is not nullExamples:
// Comparison
.where("age", ">", 18)
.where("price", "<=", 100)
// Pattern matching
.where("name", "LIKE", "John%")
.where("email", "NOT LIKE", "%@spam.com")
// Set operations
.where("status", "IN", ["active", "pending"])
.where("category", "NOT IN", ["deleted", "archived"])
// Range operations
.where("age", "BETWEEN", 18, 65)
.where("price", "NOT BETWEEN", 10, 50)
// Null operations
.where("description", "IS NULL")
.where("email", "IS NOT NULL")
// Single insert
const result = await db.insert("users")
.values({
username: "alice",
email: "alice@example.com"
})
.execute();
// Multiple inserts
const results = await db.insert("users")
.values([
{ username: "bob", email: "bob@example.com" },
{ username: "charlie", email: "charlie@example.com" }
])
.execute();
// Insert with returning
const user = await db.insert("users")
.values({ username: "david", email: "david@example.com" })
.returning(["id", "username"])
.execute();
// Update with conditions (object syntax)
const result = await db.update("users")
.set({ age: 30 })
.where({ username: "alice" })
.execute();
// Update with explicit where conditions
const resultExplicit = await db.update("users")
.set({ age: 30 })
.where("username", "=", "alice")
.execute();
// Update multiple records
const result = await db.update("posts")
.set({ status: "published" })
.where("status", "=", "draft")
.execute();
// Update with comparison operators
const adultUsers = await db.update("users")
.set({ verified: true })
.where("age", ">=", 18)
.execute();
// Delete with conditions (object syntax)
const result = await db.delete("users")
.where({ username: "alice" })
.execute();
// Delete with explicit where conditions
const resultExplicit = await db.delete("users")
.where("username", "=", "alice")
.execute();
// Delete with comparison operators
const oldPosts = await db.delete("posts")
.where("created_at", "<", "2023-01-01")
.execute();
// Delete with returning
const deleted = await db.delete("posts")
.where("status", "=", "draft")
.returning(["id", "title"])
.execute();
await db.schema.createTable("users")
.ifNotExists(true)
.addColumn({
name: "id",
type: "INTEGER",
primaryKey: true,
autoIncrement: true
})
.addColumn({
name: "username",
type: "TEXT",
notNull: true,
unique: true
})
.addColumn({
name: "email",
type: "TEXT",
notNull: true,
unique: true
})
.addColumn({
name: "created_at",
type: "DATETIME",
defaultValue: "CURRENT_TIMESTAMP"
})
.addForeignKey({
column: "profile_id",
references: {
table: "profiles",
column: "id"
},
onDelete: "CASCADE"
})
.execute();
await db.schema.createIndex("idx_users_email")
.on("users")
.columns(["email"])
.unique(true)
.ifNotExists(true)
.execute();
await db.schema.createIndex("idx_posts_user_id")
.on("posts")
.columns(["user_id"])
.ifNotExists(true)
.execute();
// Check if table exists
const hasTable = await db.schema.hasTable("users");
// Get table structure
const columns = await db.schema.getTableInfo("users");
// Get foreign keys
const foreignKeys = await db.schema.getForeignKeys("posts");
// Get indexes
const indexes = await db.schema.getIndexes("users");
// Simple transaction
await db.transaction(async (tx) => {
await tx.insert("users").values({ username: "alice" }).execute();
await tx.insert("posts").values({ user_id: 1, title: "My Post" }).execute();
});
// Transaction with options
await db.transaction(async (tx) => {
// Your operations here
}, {
tries: 3,
backoffMs: 100
});
// Nested transactions
await db.transaction(async (tx) => {
await tx.insert("users").values({ username: "alice" }).execute();
await tx.transaction(async (innerTx) => {
await innerTx.insert("posts").values({ user_id: 1, title: "Nested Post" }).execute();
});
});
// Find records
const users = await db.find("users", { status: "active" });
const user = await db.findOne("users", { username: "alice" });
// Create record
const result = await db.create("users", { username: "alice", email: "alice@example.com" });
// Update record
const result = await db.updateOne("users", { age: 30 }, { username: "alice" });
// Delete record
const result = await db.deleteOne("users", { username: "alice" });
// Execute raw SQL
const result = await db.run("INSERT INTO users (username) VALUES (?)", ["alice"]);
const users = await db.all("SELECT * FROM users WHERE age > ?", [25]);
const user = await db.get("SELECT * FROM users WHERE id = ?", [1]);
Bunely provides comprehensive TypeScript types for all operations:
import type {
ColumnDefinition,
ForeignKeyDefinition,
IndexDefinition,
WhereClause,
TransactionOptions
} from "bunely";
const column: ColumnDefinition = {
name: "id",
type: "INTEGER",
primaryKey: true,
autoIncrement: true
};
Check out the examples/ directory for comprehensive examples:
query-builder.ts - Complete query builder examplebasic-schema.ts - Basic schema operationsschema-example.ts - Schema utilities exampleschema-management.ts - Advanced migration managementThe library is organized into several modules:
src/core/ - Core database class and mutexsrc/query/ - Query builders (SELECT, INSERT, UPDATE, DELETE)src/schema/ - Schema builders (CREATE TABLE, ALTER TABLE, etc.)src/types/ - TypeScript type definitionsContributions are welcome! Please feel free to submit a Pull Request.
MIT
FAQs
A lightweight Query Builder for bun:sqlite
We found that bunely demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.