// Generated by nautilus-codegen. Do not edit manually.

import { NautilusClient } from './_internal/_client';
import type { NautilusClientOptions, TransactionBatchOperation } from './_internal/_client';
import type { EnginePoolOptions } from './_internal/_engine';
import { IsolationLevel, TransactionClient } from './_internal/_transaction';
{%- for model in models %}
import { {{ model.delegate_name }} } from './models/{{ model.snake_name }}';
{%- endfor %}

const _SCHEMA_PATH = '{{ schema_path }}';

/**
 * Nautilus database client.
 *
 * Usage:
 *
 *   const db = new Nautilus();
 *   await db.connect();
 *
 *   const users = await db.user.findMany({ where: { role: 'ADMIN' } });
 *   const user  = await db.user.create({ data: { email: 'alice@example.com' } });
 *
 *   await db.disconnect();
 *
 * Transaction usage:
 *
 *   const result = await db.$transaction(async (tx) => {
 *     const user = await tx.user.create({ data: { email: 'alice@example.com' } });
 *     await tx.post.create({ data: { title: 'Hello', authorId: user!.id } });
 *     return user;
 *   });
 */
export class Nautilus extends NautilusClient {
{%- for model in models %}
  readonly {{ model.camel_name }}: {{ model.delegate_name }};
{%- endfor %}

  constructor(options?: NautilusClientOptions) {
    super(_SCHEMA_PATH, options);
{%- for model in models %}
    this.{{ model.camel_name }} = new {{ model.delegate_name }}(this);
    this._delegates['{{ model.camel_name }}'] = this.{{ model.camel_name }};
{%- endfor %}
  }

  /**
   * Execute a function inside a database transaction.
   *
   * The transaction is committed when the function resolves and rolled back
   * if it throws.
   *
   * @param fn      Async function that receives a transaction client.
   * @param options Optional timeout (ms) and isolation level.
   */
  async $transaction<T>(
    fn:       (tx: TransactionClient) => Promise<T>,
    options?: { timeout?: number; isolationLevel?: IsolationLevel },
  ): Promise<T> {
    return this._runTransactionCallback(fn, options);
  }

  /**
   * Execute a list of JSON-RPC operations atomically inside a server-managed transaction.
   */
  async $transactionBatch(
    operations: TransactionBatchOperation[],
    options?: { timeout?: number; isolationLevel?: IsolationLevel },
  ): Promise<unknown[]> {
    return this._runTransactionBatch(operations, options);
  }
}

export { IsolationLevel };
export type { EnginePoolOptions, NautilusClientOptions, TransactionBatchOperation, TransactionClient };
