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

import type { NautilusClient } from '../_internal/_client.js';
import type { CrudEventContext, ModelEventContexts, ModelEventToken } from '../_internal/_events.js';
{%- if has_enums %}
import type { {% for e in enum_imports %}{{ e }}{% if not loop.last %}, {% endif %}{% endfor %} } from '../enums.js';
{%- endif %}
{%- if has_composite_types %}
import type { {% for t in composite_type_imports %}{{ t }}{% if not loop.last %}, {% endif %}{% endfor %} } from '../types.js';
{%- endif %}
{%- if has_extension_types %}
{%- for ext in extension_imports %}
import type { {% for t in ext.types %}{{ t }}, {{ t }}Input{% if not loop.last %}, {% endif %}{% endfor %} } from '../extensions/{{ ext.module }}/types.js';
{%- endfor %}
{%- endif %}

export type JsonPrimitive = string | number | boolean | null;
export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
export interface JsonObject {
  [key: string]: JsonValue;
}
export type JsonScalarOrArray = JsonPrimitive | JsonValue[];
export type HstoreValue = Record<string, string | null>;

export interface StringFilter {
  contains?:   string;
  startsWith?: string;
  endsWith?:   string;
  in?:         string[];
  notIn?:      string[];
  not?:        string;
  isNull?:     boolean;
}

export interface NumberFilter {
  lt?:     number;
  lte?:    number;
  gt?:     number;
  gte?:    number;
  in?:     number[];
  notIn?:  number[];
  not?:    number;
  isNull?: boolean;
}

export interface DateFilter {
  lt?:     Date;
  lte?:    Date;
  gt?:     Date;
  gte?:    Date;
  in?:     Date[];
  notIn?:  Date[];
  not?:    Date;
  isNull?: boolean;
}

export interface JsonFilter {
  equals?: JsonValue;
  not?:    JsonValue;
  isNull?: boolean;
}

export interface HstoreFilter {
  equals?: {% if has_hstore_extension %}HstoreInput{% else %}HstoreValue{% endif %};
  not?:    {% if has_hstore_extension %}HstoreInput{% else %}HstoreValue{% endif %};
  isNull?: boolean;
}

export interface VectorFilter {
  equals?: {% if has_vector_extension %}VectorInput{% else %}number[]{% endif %};
  not?:    {% if has_vector_extension %}VectorInput{% else %}number[]{% endif %};
  isNull?: boolean;
}

export type VectorMetric = 'l2' | 'innerProduct' | 'cosine';
export type {{ model_name }}VectorFieldKeys = {% if has_vector_fields %}{% for name in vector_field_names %}'{{ name }}'{% if not loop.last %} | {% endif %}{% endfor %}{% else %}never{% endif %};
export interface {{ model_name }}NearestInput {
  field:  {{ model_name }}VectorFieldKeys;
  query:  {% if has_vector_extension %}VectorInput{% else %}number[]{% endif %};
  metric: VectorMetric;
}

export type SortOrder = 'asc' | 'desc';

export interface {{ model_name }}Model {
{%- for f in scalar_fields %}
{%- if f.doc_comment %}
  /** {{ f.doc_comment }} */
{%- endif %}
  {{ f.name }}: {{ f.ts_type }};
{%- endfor %}
{%- for f in relation_fields %}
{%- if f.doc_comment %}
  /** {{ f.doc_comment }} */
{%- endif %}
  {{ f.name }}?: {{ f.ts_type }};
{%- endfor %}
}

export interface {{ model_name }}WhereInput {
{%- for field in where_input_fields %}
{%- if field.where_ts_type %}
  {{ field.name }}?: {{ field.where_ts_type }};
{%- elif field.is_vector %}
  {{ field.name }}?: number[]{% if field.is_nullable %} | null{% endif %} | VectorFilter;
{%- elif field.base_type == "string" %}
  {{ field.name }}?: string{% if field.is_nullable %} | null{% endif %} | StringFilter;
{%- elif field.base_type == "number" %}
  {{ field.name }}?: number{% if field.is_nullable %} | null{% endif %} | NumberFilter;
{%- elif field.base_type == "Date" %}
  {{ field.name }}?: Date{% if field.is_nullable %} | null{% endif %} | DateFilter;
{%- elif field.base_type == "boolean" %}
  {{ field.name }}?: boolean{% if field.is_nullable %} | null{% endif %};
{%- elif field.base_type == "JsonValue" %}
  {{ field.name }}?: JsonScalarOrArray | JsonFilter;
{%- elif field.base_type == "HstoreValue" %}
  {{ field.name }}?: {% if field.is_nullable %}null | {% endif %}HstoreFilter;
{%- else %}
  {{ field.name }}?: {{ field.ts_type }};
{%- endif %}
{%- endfor %}
  AND?: {{ model_name }}WhereInput | {{ model_name }}WhereInput[];
  OR?:  {{ model_name }}WhereInput[];
  NOT?: {{ model_name }}WhereInput | {{ model_name }}WhereInput[];
}

export interface {{ model_name }}CreateInput {
{%- for field in create_input_fields %}
{%- if field.is_required %}
  {{ field.name }}: {{ field.ts_type }};
{%- else %}
  {{ field.name }}?: {{ field.ts_type }};
{%- endif %}
{%- endfor %}
}

export interface {{ model_name }}UpdateInput {
{%- for field in update_input_fields %}
  {{ field.name }}?: {{ field.ts_type }};
{%- endfor %}
}

export interface {{ model_name }}OrderByInput {
{%- for field in order_by_fields %}
  {{ field.name }}?: SortOrder;
{%- endfor %}
}

export interface {{ model_name }}SelectInput {
{%- for field in scalar_fields %}
  {{ field.name }}?: boolean;
{%- endfor %}
}

export type {{ model_name }}PrimaryKeyKeys = {% if primary_key_fields | length > 0 %}{% for f in primary_key_fields %}'{{ f }}'{% if not loop.last %} | {% endif %}{% endfor %}{% else %}never{% endif %};
export type {{ model_name }}TruthySelectKeys<S extends {{ model_name }}SelectInput> = {
  [K in keyof S]-?: S[K] extends true ? K : never;
}[keyof S] & keyof {{ model_name }}Model;
export type {{ model_name }}Selected<S extends {{ model_name }}SelectInput> = Pick<
  {{ model_name }}Model,
  {{ model_name }}PrimaryKeyKeys | {{ model_name }}TruthySelectKeys<S>
>;

{%- if has_includes %}

export interface {{ model_name }}IncludeInput {
{%- for field in include_fields %}
  {{ field.name }}?: boolean | FindMany{{ field.target_model }}ArgsFrom{{ model_name }};
{%- endfor %}
}

{%- for field in include_fields %}
export interface FindMany{{ field.target_model }}ArgsFrom{{ model_name }} {
  where?:    {{ field.target_model }}WhereInput;
  orderBy?:  {{ field.target_model }}OrderByInput;
{%- if field.is_array %}
  take?:     number;
  skip?:     number;
  cursor?:   Record<string, unknown>;
  distinct?: string[];
{%- endif %}
  include?:  {{ field.target_model }}IncludeInput;
}
{%- endfor %}

{%- endif %}

export interface {{ model_name }}UpsertInput {
  create: {{ model_name }}CreateInput;
  update: {{ model_name }}UpdateInput;
}

export type {{ model_name }}ScalarFieldKeys = {% for f in scalar_fields %}'{{ f.name }}'{% if not loop.last %} | {% endif %}{% endfor %};

export interface {{ model_name }}CreateEventArgs {
  data: {{ model_name }}CreateInput;
  returnData: boolean;
}

export interface {{ model_name }}CreateManyEventArgs {
  data: {{ model_name }}CreateInput[];
  returnData: boolean;
}

export interface {{ model_name }}UpdateEventArgs {
  where?: {{ model_name }}WhereInput;
  data: {{ model_name }}UpdateInput;
  returnData: boolean;
}

export interface {{ model_name }}DeleteEventArgs {
  where: {{ model_name }}WhereInput;
  returnData: boolean;
}

export interface {{ model_name }}DeleteManyEventArgs {
  where?: {{ model_name }}WhereInput;
  returnData: boolean;
}

export interface {{ model_name }}CreateEventPayload {
  protocolVersion: string;
  model: '{{ model_name }}';
  data: Record<string, unknown>;
  returnData: boolean;
}

export interface {{ model_name }}CreateManyEventPayload {
  protocolVersion: string;
  model: '{{ model_name }}';
  data: Record<string, unknown>[];
  returnData: boolean;
}

export interface {{ model_name }}UpdateEventPayload {
  protocolVersion: string;
  model: '{{ model_name }}';
  filter: Record<string, unknown>;
  data: Record<string, unknown>;
  returnData: boolean;
}

export interface {{ model_name }}DeleteEventPayload {
  protocolVersion: string;
  model: '{{ model_name }}';
  filter: Record<string, unknown>;
  returnData: boolean;
}

export type {{ model_name }}DeleteManyEventPayload = {{ model_name }}DeleteEventPayload;

export type {{ model_name }}CreateEventContext = CrudEventContext<
  ModelEventToken,
  'create',
  {{ model_name }}CreateEventArgs,
  {{ model_name }}CreateEventPayload,
  {{ model_name }}Model | null
>;
export type {{ model_name }}CreateManyEventContext = CrudEventContext<
  ModelEventToken,
  'createMany',
  {{ model_name }}CreateManyEventArgs,
  {{ model_name }}CreateManyEventPayload,
  {{ model_name }}Model[]
>;
export type {{ model_name }}UpdateEventContext = CrudEventContext<
  ModelEventToken,
  'update',
  {{ model_name }}UpdateEventArgs,
  {{ model_name }}UpdateEventPayload,
  {{ model_name }}Model[] | number
>;
export type {{ model_name }}DeleteEventContext = CrudEventContext<
  ModelEventToken,
  'delete',
  {{ model_name }}DeleteEventArgs,
  {{ model_name }}DeleteEventPayload,
  {{ model_name }}Model | null
>;
export type {{ model_name }}DeleteManyEventContext = CrudEventContext<
  ModelEventToken,
  'deleteMany',
  {{ model_name }}DeleteManyEventArgs,
  {{ model_name }}DeleteManyEventPayload,
  {{ model_name }}Model[] | number
>;

export type {{ model_name }}EventContext =
  | {{ model_name }}CreateEventContext
  | {{ model_name }}CreateManyEventContext
  | {{ model_name }}UpdateEventContext
  | {{ model_name }}DeleteEventContext
  | {{ model_name }}DeleteManyEventContext;

export interface {{ model_name }}EventContexts extends ModelEventContexts {
  create: {{ model_name }}CreateEventContext;
  createMany: {{ model_name }}CreateManyEventContext;
  update: {{ model_name }}UpdateEventContext;
  delete: {{ model_name }}DeleteEventContext;
  deleteMany: {{ model_name }}DeleteManyEventContext;
}

export declare const {{ model_name }}: ModelEventToken<{{ model_name }}EventContexts>;

export interface {{ model_name }}CountAggregateInput {
  _all?: boolean;
{%- for f in scalar_fields %}
  {{ f.name }}?: boolean;
{%- endfor %}
}

{%- if has_numeric_fields %}
export interface {{ model_name }}AvgAggregateInput {
{%- for f in numeric_fields %}
  {{ f.name }}?: boolean;
{%- endfor %}
}
export interface {{ model_name }}SumAggregateInput {
{%- for f in numeric_fields %}
  {{ f.name }}?: boolean;
{%- endfor %}
}
{%- endif %}

export interface {{ model_name }}MinAggregateInput {
{%- for f in orderable_fields %}
  {{ f.name }}?: boolean;
{%- endfor %}
}

export interface {{ model_name }}MaxAggregateInput {
{%- for f in orderable_fields %}
  {{ f.name }}?: boolean;
{%- endfor %}
}

export interface {{ model_name }}GroupByOutput {
{%- for f in scalar_fields %}
  {{ f.name }}?: {{ f.ts_type }};
{%- endfor %}
  _count?: Record<string, number>;
  _avg?:   Record<string, number>;
  _sum?:   Record<string, unknown>;
  _min?:   Record<string, unknown>;
  _max?:   Record<string, unknown>;
}

export interface {{ model_name }}FindManyArgs {
  where?:    {{ model_name }}WhereInput;
  orderBy?:  {{ model_name }}OrderByInput | {{ model_name }}OrderByInput[];
{%- if has_vector_fields %}
  nearest?:  {{ model_name }}NearestInput;
{%- endif %}
  take?:     number;
  skip?:     number;
  select?:   {{ model_name }}SelectInput;
  include?:  {% if has_includes %}{{ model_name }}IncludeInput{% else %}Record<string, unknown>{% endif %};
  cursor?:   Record<string, unknown>;
  distinct?: string[];
  chunkSize?: number;
}

export interface {{ model_name }}FindFirstArgs {
  where?:   {{ model_name }}WhereInput;
  orderBy?: {{ model_name }}OrderByInput | {{ model_name }}OrderByInput[];
{%- if has_vector_fields %}
  nearest?: {{ model_name }}NearestInput;
{%- endif %}
  select?:  {{ model_name }}SelectInput;
  include?: {% if has_includes %}{{ model_name }}IncludeInput{% else %}Record<string, unknown>{% endif %};
}

export interface {{ model_name }}FindUniqueArgs {
  where:    {{ model_name }}WhereInput;
  select?:  {{ model_name }}SelectInput;
  include?: {% if has_includes %}{{ model_name }}IncludeInput{% else %}Record<string, unknown>{% endif %};
}

export declare class {{ delegate_name }} {
  client: NautilusClient;
  constructor(client: NautilusClient);

  /**
   * Fetch every matching row and resolve a final in-memory array.
   *
   * Prefer this for small or medium result sets, eager-loaded reads, and any
   * downstream path that already wants the whole collection before continuing.
   */
  findMany(args?: Omit<{{ model_name }}FindManyArgs, 'select'> & { select?: undefined }): Promise<{{ model_name }}Model[]>;
  findMany<const S extends {{ model_name }}SelectInput>(args: Omit<{{ model_name }}FindManyArgs, 'select'> & { select: S }): Promise<Array<{{ model_name }}Selected<S>>>;

  /**
   * Yield matching rows incrementally as an async iterable.
   *
   * Prefer this for exports, scans, and `for await ... of` pipelines where
   * keeping client memory flatter matters more than receiving one final array.
   * The underlying request keeps a pooled connection busy until iteration
   * finishes or the iterable is closed.
   */
  streamMany(args?: Omit<{{ model_name }}FindManyArgs, 'select'> & { select?: undefined }): AsyncIterable<{{ model_name }}Model>;
  streamMany<const S extends {{ model_name }}SelectInput>(args: Omit<{{ model_name }}FindManyArgs, 'select'> & { select: S }): AsyncIterable<{{ model_name }}Selected<S>>;

  findFirst(args?: Omit<{{ model_name }}FindFirstArgs, 'select'> & { select?: undefined }): Promise<{{ model_name }}Model | null>;
  findFirst<const S extends {{ model_name }}SelectInput>(args: Omit<{{ model_name }}FindFirstArgs, 'select'> & { select: S }): Promise<{{ model_name }}Selected<S> | null>;

  findUnique(args: Omit<{{ model_name }}FindUniqueArgs, 'select'> & { select?: undefined }): Promise<{{ model_name }}Model | null>;
  findUnique<const S extends {{ model_name }}SelectInput>(args: Omit<{{ model_name }}FindUniqueArgs, 'select'> & { select: S }): Promise<{{ model_name }}Selected<S> | null>;

  findUniqueOrThrow(args: Omit<{{ model_name }}FindUniqueArgs, 'select'> & { select?: undefined }): Promise<{{ model_name }}Model>;
  findUniqueOrThrow<const S extends {{ model_name }}SelectInput>(args: Omit<{{ model_name }}FindUniqueArgs, 'select'> & { select: S }): Promise<{{ model_name }}Selected<S>>;

  findFirstOrThrow(args?: Omit<{{ model_name }}FindFirstArgs, 'select'> & { select?: undefined }): Promise<{{ model_name }}Model>;
  findFirstOrThrow<const S extends {{ model_name }}SelectInput>(args: Omit<{{ model_name }}FindFirstArgs, 'select'> & { select: S }): Promise<{{ model_name }}Selected<S>>;

  create(args: {
    data:        {{ model_name }}CreateInput;
    returnData?: boolean;
  }): Promise<{{ model_name }}Model | null>;

  createMany(args: {
    data:        {{ model_name }}CreateInput[];
    returnData?: boolean;
  }): Promise<{{ model_name }}Model[]>;

  update(args: {
    where?:      {{ model_name }}WhereInput;
    data:        {{ model_name }}UpdateInput;
    returnData?: boolean;
  }): Promise<{{ model_name }}Model[] | number>;

  delete(args: {
    where:       {{ model_name }}WhereInput;
    returnData?: boolean;
  }): Promise<{{ model_name }}Model | null>;

  deleteMany(args?: {
    where?:      {{ model_name }}WhereInput;
    returnData?: boolean;
  }): Promise<{{ model_name }}Model[] | number>;

  count(args?: {
    where?:  {{ model_name }}WhereInput;
    take?:   number;
    skip?:   number;
    cursor?: Record<string, unknown>;
  }): Promise<number>;

  /** Execute a raw SQL string and return result rows as generic objects. */
  rawQuery(sql: string): Promise<Record<string, unknown>[]>;

  /** Execute a raw prepared-statement query with bound parameters. */
  rawStmtQuery(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;

  upsert(args: {
    where:       {{ model_name }}WhereInput;
    data:        {{ model_name }}UpsertInput;
    include?:    {% if has_includes %}{{ model_name }}IncludeInput{% else %}Record<string, unknown>{% endif %};
    returnData?: boolean;
  }): Promise<{{ model_name }}Model | null>;

  groupBy(args: {
    by:      {{ model_name }}ScalarFieldKeys[];
    where?:  {{ model_name }}WhereInput;
    having?: Record<string, unknown>;
    take?:   number;
    skip?:   number;
    count?:  boolean | {{ model_name }}CountAggregateInput;
{%- if has_numeric_fields %}
    avg?:    {{ model_name }}AvgAggregateInput;
    sum?:    {{ model_name }}SumAggregateInput;
{%- endif %}
    min?:    {{ model_name }}MinAggregateInput;
    max?:    {{ model_name }}MaxAggregateInput;
    order?:  Record<string, SortOrder> | Record<string, SortOrder>[];
  }): Promise<{{ model_name }}GroupByOutput[]>;
}

export type { NautilusClient };
