cook Template

The cook tagged template literal is the primary way to write genaql queries.

Import

import.ts
import { cook } from 'genaql';

Basic Usage

basic.ts
// Create a query
const query = cook`main:users slay:id,name,email sus:active=true`;

// Get SQL string
const sql = query.toSQL();
// → "SELECT id, name, email FROM users WHERE active = $1"

// Get SQL with parameters
const { sql, params } = query.toParams();
// → { sql: "SELECT ... WHERE active = $1", params: [true] }

Template Interpolation

interpolation.ts
// Variables are automatically parameterized
const userId = 42;
const status = 'active';

const query = cook`main:users slay:* sus:id=${userId} sus:status=${status}`;
// → { sql: "... WHERE id = $1 AND status = $2", params: [42, 'active'] }

// Arrays for IN clauses
const ids = [1, 2, 3];
const query = cook`main:users slay:* sus:id.in(${ids})`;
// → { sql: "... WHERE id IN ($1, $2, $3)", params: [1, 2, 3] }

Query Methods

MethodReturnsDescription
.toSQL()stringRaw SQL string with placeholders
.toParams(){ sql, params }SQL with parameter array
.toString()stringAlias for toSQL()
.clone()QueryCreate a copy of the query
.extend(str)QueryAppend additional clauses

Query Composition

composition.ts
// Base query
const baseQuery = cook`main:users slay:*`;

// Extend with conditions
const activeUsers = baseQuery.extend(cook`sus:active=true`);
const adminUsers = baseQuery.extend(cook`sus:role=admin`);

// Clone and modify
const paginatedQuery = baseQuery
  .clone()
  .extend(cook`vibe:created_at/desc bet:10 skip:20`);

Raw SQL

raw.ts
import { cook, raw } from 'genaql';

// Insert raw SQL (use with caution!)
const query = cook`main:users slay:${raw('COUNT(*)')} sus:created_at>${raw("NOW() - INTERVAL '7 days'")}`;
// → SELECT COUNT(*) FROM users WHERE created_at > NOW() - INTERVAL '7 days'

// Raw is NOT parameterized - only use for trusted values

With Database Client

with-client.ts
// Execute query directly
const users = await db.query(cook`main:users slay:* sus:active=true`);

// Query returns typed results when schema is provided
// users: Array<{ id: number, name: string, email: string, ... }>

Security

All interpolated values are automatically parameterized to prevent SQL injection. Only use raw() for trusted, static SQL fragments - never with user input.