createClient
Create a database client for executing queries with connection pooling and type safety.
Import
import.ts
import { createClient } from 'genaql';Basic Usage
basic.ts
import { createClient, cook } from 'genaql';
import { Pool } from 'pg';
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});
const db = createClient({
dialect: 'postgres',
pool
});
// Execute queries
const users = await db.query(cook`main:users slay:*`);Configuration Options
options.ts
const db = createClient({
// Required: Database dialect
dialect: 'postgres' | 'mysql' | 'sqlite',
// Connection (one of these)
pool: Pool, // pg or mysql2 pool
connection: Connection, // Single connection
database: string, // SQLite file path
// Optional: Schema for type safety
schema: Schema,
// Optional: Query logging
logging: true, // or custom function
// logging: (sql, params, duration) => console.log(sql)
// Optional: Runtime validation
validate: process.env.NODE_ENV === 'development',
// Optional: Soft delete behavior
softDelete: true, // Uses schema config
// Optional: Auto-timestamps
timestamps: true, // Uses schema config
});Client Methods
| Method | Returns | Description |
|---|---|---|
.query(q) | Promise<T[]> | Execute SELECT query, return rows |
.queryOne(q) | Promise<T | null> | Execute query, return first row |
.execute(q) | Promise<Result> | Execute INSERT/UPDATE/DELETE |
.raw(sql, params) | Promise<any> | Execute raw SQL |
.transaction(fn) | Promise<T> | Execute in transaction |
.beginTransaction() | Promise<Trx> | Start manual transaction |
.close() | Promise<void> | Close connection pool |
Query Methods
methods.ts
// Select multiple rows
const users = await db.query(cook`main:users slay:* sus:active=true`);
// users: User[]
// Select single row
const user = await db.queryOne(cook`main:users slay:* sus:id=1`);
// user: User | null
// Insert and return
const result = await db.execute(
cook`nocap:users drip:name,email fire:John,john@test.com flex:id`
);
// result: { id: 1 }
// Update
const updated = await db.execute(
cook`glow:users rizz:status=active sus:id=1 flex:*`
);
// updated: { id: 1, status: 'active', ... }
// Delete
const deleted = await db.execute(
cook`yeet:users sus:id=1 flex:id`
);
// deleted: { id: 1 }With Schema (Type Safe)
type-safe.ts
import { createClient, cook, defineSchema } from 'genaql';
const schema = defineSchema({
users: {
id: 'serial',
name: 'text',
email: 'text'
}
});
const db = createClient({
dialect: 'postgres',
pool,
schema
});
// TypeScript knows the return type!
const users = await db.query(cook`main:users slay:id,name`);
// users: Array<{ id: number; name: string }>
// Errors on invalid columns
const bad = await db.query(cook`main:users slay:invalid`);
// ^^^^^^^
// Type Error: Column 'invalid' does not existLifecycle
lifecycle.ts
// Create client at app startup
const db = createClient({ /* ... */ });
// Use throughout your app
export { db };
// Close on shutdown
process.on('SIGTERM', async () => {
await db.close();
process.exit(0);
});Important
Create the client once at application startup and reuse it. Don't create new clients per request — this wastes connections and hurts performance.