/**
 * src/db/sqlite-client.ts
 *
 * A drop-in subset of the @supabase/supabase-js v2 client backed by better-sqlite3.
 * Implements the chained-query API surface actually used by the gateway (audited via
 * grep — see docs/SQLITE_PORT.md). Existing call sites don't change shape:
 *
 *   const { data, error } = await supabase
 *     .from('tenants')
 *     .select('id, business_name')
 *     .eq('owner_id', userId)
 *     .single();
 *
 * Why a shim instead of rewriting every call site to raw SQL or Kysely:
 * - Phase 1 ships device mode tonight. ~108 call sites would each need a rewrite.
 * - Shim is bounded — implements only what we use (audit captures real usage).
 * - control-plane mode keeps using @supabase/supabase-js verbatim, no divergence.
 *
 * Notable adaptations (Postgres → SQLite):
 * - JSON columns (settings/metadata/payload/delivery/items/tags/working_hours) are
 *   auto-stringified on write and parsed on read. List in JSON_COLUMNS below.
 * - UUID is generated via crypto.randomUUID() on insert when `id` is missing.
 * - Booleans collapse to 0/1 on write, expand to true/false on read for any column
 *   whose name appears in BOOL_COLUMNS or starts with `is_`/`has_`/`enabled`.
 * - .ilike falls back to LOWER(col) LIKE LOWER(pattern) — SQLite has no native ILIKE.
 * - .textSearch maps to LIKE '%term%' (good enough for the one call site).
 * - .rpc() implements the 4 known RPCs in TS: match_documents (vector cosine via
 *   sqlite-vec), upsert_daily_usage (INSERT...ON CONFLICT), increment_counter,
 *   exec_sql (fall-through to db.exec).
 */
import { type Database as DB } from 'better-sqlite3';
export interface Result<T> {
    data: T | null;
    error: {
        message: string;
        code?: string;
    } | null;
    count?: number | null;
}
declare class QueryBuilder<T = Record<string, unknown>> implements PromiseLike<Result<T>> {
    private readonly db;
    private readonly table;
    private filters;
    private orderBy;
    private limitN?;
    private rangeFromN?;
    private rangeToN?;
    private selectCols;
    private op;
    private singleMode;
    constructor(db: DB, table: string);
    select(cols?: string, opts?: {
        count?: 'exact' | 'planned' | 'estimated';
        head?: boolean;
    }): this;
    insert(rows: Record<string, unknown> | Record<string, unknown>[]): this;
    update(row: Record<string, unknown>): this;
    upsert(rows: Record<string, unknown> | Record<string, unknown>[], opts?: {
        onConflict?: string;
    }): this;
    delete(): this;
    eq(col: string, val: unknown): this;
    neq(col: string, val: unknown): this;
    gt(col: string, val: unknown): this;
    gte(col: string, val: unknown): this;
    lt(col: string, val: unknown): this;
    lte(col: string, val: unknown): this;
    like(col: string, pattern: string): this;
    ilike(col: string, pattern: string): this;
    in(col: string, vals: unknown[]): this;
    is(col: string, val: null | true | false): this;
    not(col: string, op: string, val: unknown): this;
    textSearch(col: string, query: string): this;
    order(col: string, opts?: {
        ascending?: boolean;
    }): this;
    limit(n: number): this;
    range(from: number, to: number): this;
    single(): PromiseLike<Result<T>>;
    maybeSingle(): PromiseLike<Result<T>>;
    then<R1 = Result<T>, R2 = never>(onfulfilled?: ((value: Result<T>) => R1 | PromiseLike<R1>) | null, onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
    private execute;
    private buildWhere;
    private buildOrderLimit;
    private runSelect;
    private runInsert;
    private runUpdate;
    private runUpsert;
    private runDelete;
}
declare class DeviceAuth {
    /**
     * Device mode is single-tenant. There's no JWT to verify — the device's
     * gateway is the privileged caller. Return a stable synthetic user so any
     * code path that expects an authenticated user keeps working.
     */
    getUser(_token?: string): Promise<{
        data: {
            user: {
                id: string;
                email: string | null;
                phone: string | null;
            } | null;
        };
        error: null;
    }>;
}
declare class DeviceStorage {
    createBucket(_name: string, _opts: unknown): Promise<{
        data: null;
        error: null;
    }>;
    from(_bucket: string): {
        upload: (path: string, data: unknown, opts?: unknown) => Promise<{
            data: null;
            error: null;
        }>;
        download: (path: string) => Promise<{
            data: null;
            error: {
                message: string;
            };
        }>;
    };
}
export declare class SqliteClient {
    private readonly db;
    readonly auth: DeviceAuth;
    readonly storage: DeviceStorage;
    constructor(db: DB);
    from<T = Record<string, unknown>>(table: string): QueryBuilder<T>;
    /**
     * RPC function bridge — translates the 4 known Supabase RPCs to TS.
     * Add new branches here as the gateway code introduces more RPC calls.
     */
    rpc(name: string, params?: Record<string, unknown>): Promise<Result<unknown>>;
}
export declare function getSqliteClient(dbPath: string): SqliteClient;
export {};
//# sourceMappingURL=sqlite-client.d.ts.map