Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 232 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,232 @@
## [0.1.0] - 18-09-2025
### Added
- Engines and `sideEffects` fields to `package.json`
- Optional `peerDependencies` for drivers; kept `glob` as a runtime dependency
- Made the package MIT

### Changed
- Migrated to Bun
- Migrated to a Turbo monorepo (for future examples and docs)
- Rewrote README without LLM
- Build now via `tsup` (ESM + CJS + DTS)

### Fixed
- Tightened SQLite URL detection with env-specific cache keys
- Vitest mocks (20/20 tests passing)

### Removed
- `execute()` fire function

---

## [0.9.0] - xx-09-2025
### Added
- Comprehensive test suite
- Smart database driver connection supporting PostgreSQL (local + cloud), SQLite, and Turso libsql
- Database initialization for PostgreSQL
- `update()` and `destroy()` functions
- Initial `query()` and `mutate()` functions
# Test pipeline
# Drizzleasy
Drizzleasy is a library to make CRUD operations and database management ridiculously easy. 100% typesafe with full LSP support in your editor due to the chainable syntax.

### Quick Example
```ts
type TUser = { id: string; email: string; isPremium: boolean }
const read = readFn<TUser>()
const create = createFn<TUser>()

// Create new user
const { data: newUser } = await create('users')({
email: formData.get('email'),
isPremium: formData.get('premium') === 'true'
})

// Query premium users
const { data: premiumUsers } = await read('users').where({ isPremium: true })()

return { newUser, premiumUsers }
```

For full docs and examples visit [drizzleasy.vercel.app](https://drizzleasy.vercel.app)

![LSP Demo](premium-vscode-demo.gif)





[![npm version](https://badge.fury.io/js/drizzleasy.svg)](https://badge.fury.io/js/drizzleasy)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- **One-liner setup** - `initializeConnection(url)` replaces complex Drizzle setup
- **Auto-detection** - Reads your drizzle.config.ts automatically
- **Multi-database** - PostgreSQL (Neon, Vercel, Docker), SQLite, Turso
- **Simple syntax** - Natural operators like `age: '>18'` and `name: '*john*'`
- **100% type-safe** - Full TypeScript support with IntelliSense
- **Optimistic updates** - Built-in React hooks for smooth UX
- **Environment switching** - Development/production database configs
- **Connection caching** - Automatic connection reuse for performance
- **Dual module support** - Works with both ESM and CommonJS
- **Zero dependencies** - Only peer dependencies for database drivers

## Installation

```bash
npm install @remcostoeten/drizzleasy
```

## Quick Start

### Replace 7 lines with 1 line

**Before:**
```typescript
import { drizzle } from 'drizzle-orm/neon-http'
import { neon } from '@neondatabase/serverless'
import * as schema from './schema'

const sql = neon(process.env.DATABASE_URL!)
export const db = drizzle(sql, { schema, logger: true })
```

**After:**
```typescript
import { initializeConnection } from '@remcostoeten/drizzleasy'
export const db = await initializeConnection(process.env.DATABASE_URL!)
```

### Database Support

```typescript
// PostgreSQL (Neon, Vercel, Supabase)
const db = await initializeConnection('postgresql://neon.tech/db')

// Local PostgreSQL (Docker)
const db = await initializeConnection('postgresql://localhost:5432/mydb')

// SQLite (Local file)
const db = await initializeConnection('file:./dev.db')

// Turso (with auth token)
const db = await initializeConnection('libsql://my-db.turso.io', {
authToken: process.env.TURSO_AUTH_TOKEN
})

// Environment switching
const db = await initializeConnection({
development: 'file:./dev.db',
production: process.env.DATABASE_URL!
})

// Multiple databases
const dbs = await initializeConnection({
main: process.env.DATABASE_URL!,
analytics: process.env.ANALYTICS_URL!,
cache: 'file:./cache.db'
})
```

### CRUD Operations

```typescript
import { readFn, createFn, updateFn, destroyFn } from '@remcostoeten/drizzleasy'

type User = {
id: string
name: string
email: string
age: number
status: 'active' | 'inactive'
}

// Create factory functions
const read = readFn<User>()
const create = createFn<User>()
const update = updateFn<User>()
const destroy = destroyFn<User>()

// Read all records
const { data: users } = await read('users')()

// Read with natural WHERE syntax
const { data: activeUsers } = await read('users')
.where({ status: 'active' })
.where({ age: '>18' })
.where({ name: '*john*' })()

// Create
const { data, error } = await create('users')({
name: 'John',
email: 'john@example.com',
age: 25,
status: 'active'
})

// Update
await update('users')('user-123', { status: 'inactive' })

// Delete
await destroy('users')('user-123')
```

## Database Connection

### Auto-Detection
```typescript
// PostgreSQL (Neon, Vercel, Docker)
const db = initializeConnection('postgresql://...')

// SQLite (Local file)
const db = initializeConnection('file:./dev.db')

// Turso (with auth token)
const db = initializeConnection('libsql://...', {
authToken: process.env.TURSO_AUTH_TOKEN
})
```

### Environment Switching
```typescript
// Automatic environment detection
const db = initializeConnection({
development: 'file:./dev.db',
production: process.env.DATABASE_URL!
})

// Multiple databases
const dbs = initializeConnection({
main: process.env.DATABASE_URL!,
analytics: process.env.ANALYTICS_URL!,
cache: 'file:./cache.db'
})
```

## WHERE Syntax

```typescript
// Comparison
{ age: '>18' } // Greater than
{ price: '<=100' } // Less than or equal
{ status: '!inactive' } // Not equal

// String patterns
{ name: '*john*' } // Contains
{ name: 'john*' } // Starts with
{ email: '*@gmail.com' } // Ends with

// Arrays (IN)
{ role: ['admin', 'user'] }

// Direct equality
{ status: 'active' }
```

## Module Support

Works with both ESM and CommonJS:

```typescript
// ESM (recommended)
import { readFn, createFn, updateFn, destroyFn, initializeConnection } from '@remcostoeten/drizzleasy'

// CommonJS
const { readFn, createFn, updateFn, destroyFn, initializeConnection } = require('@remcostoeten/drizzleasy')
```

## Error Handling

All operations return a consistent result format:

```typescript
const create = createFn<User>()
const { data, error } = await create('users')({ name: 'John' })

if (error) {
console.error('Operation failed:', error.message)
return
}

console.log('Success:', data)
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT © [Remco Stoeten](https://github.com/remcostoeten)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"clean": "turbo run clean",
"type-check": "turbo run type-check",
"release": "python3 scripts/release-cli",
"gemini": "python3 scripts/gemini.py"
"gemini": "python3 scripts/gemini-cli"
},
"devDependencies": {
"turbo": "^2.0.0",
Expand Down
File renamed without changes.