UNPKG

@adonis-agora/filter

Version:

Server-side query filtering/sorting/pagination for AdonisJS — Spatie-style input, a Lucid adapter, and field allow-listing. Part of the Agora ecosystem.

49 lines 2.58 kB
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