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

MethodReturnsDescription
.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 exist

Lifecycle

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.