import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
import type { LucidModel, ModelPaginatorContract, ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
import { type ApplyFromRequestOptions, type FilterRequestContext } from './apply_from_request.js';
import type { FilterClass } from './filter_class.js';
import type { FilterSpec } from './filter_spec.js';
import type { ResolvedPagination } from './runner.js';
/**
 * Opt a Lucid model into filtering — the `adonis-lucid-filter` shape, with the rest of the
 * pipeline (search, sort, page bounds) included.
 *
 * ```ts
 * export default class User extends compose(BaseModel, Filterable) {
 *   static $filter = () => UserFilter
 * }
 * ```
 *
 * The model then answers two calls, and the first **hands the query builder back** — nothing is
 * executed until you say so:
 *
 * ```ts
 * // keep composing, then page it with what the request asked for
 * const { query } = await User.filter(ctx)
 * query.whereNotNull('confirmedAt').preload('team')
 * return query.filterPaginate()
 *
 * // or the one-liner
 * return User.filterPaginate(ctx)
 * ```
 *
 * The builder comes back inside an object rather than as the promise's own value on purpose: a
 * Lucid query builder is *thenable*, so `await`ing a promise that resolves to one would run the
 * query and hand you rows instead of the builder. Destructuring keeps the builder a builder.
 */
/**
 * What {@link Filterable} adds to a model, spelled out so the mixin's return type can be named
 * (an inferred anonymous class would drag Lucid's internals into every consumer's build).
 */
export interface FilteredQuery<M extends LucidModel> extends ResolvedPagination {
    /** The query builder, filtered/searched/sorted — yours to keep composing on, not yet executed. */
    query: ModelQueryBuilderContract<M>;
}
export interface FilterableModelStatics {
    /** The filter this model is read through. A thunk, so the filter may import the model back. */
    $filter?: () => FilterClass | FilterSpec;
    filter<M extends LucidModel>(this: M, ctx?: FilterRequestContext, filter?: FilterClass | FilterSpec, options?: ApplyFromRequestOptions): Promise<FilteredQuery<M>>;
    filterPaginate<M extends LucidModel>(this: M, ctx?: FilterRequestContext, filter?: FilterClass | FilterSpec, options?: ApplyFromRequestOptions): Promise<ModelPaginatorContract<InstanceType<M>>>;
}
export declare function Filterable<T extends NormalizeConstructor<LucidModel>>(superclass: T): T & FilterableModelStatics;
//# sourceMappingURL=filterable_mixin.d.ts.map