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.

46 lines 2.67 kB
import { HttpContext } from '@adonisjs/core/http'; import { applyFilterFromRequest, } from './apply_from_request.js'; import { stashPagination } from './pagination_stash.js'; export function Filterable(superclass) { class FilterableModel extends superclass { /** The filter this model is read through. A thunk, so the filter may import the model back. */ static $filter; /** * Apply the model's filter to a fresh query and hand back the **query builder** plus the * pagination the request resolved to — filters, search and sort applied, nothing executed. * Compose whatever else the endpoint needs on the builder, then page it with * `filterPaginate()` (no arguments) or `paginate(page, size)`. */ static async filter(ctx, filter, options) { // `this` is the model the static was called on (a subclass of the mixin), which is exactly // what these helpers need — the rule's suggestion (name the class) would pin every model to // the anonymous mixin class instead. // biome-ignore lint/complexity/noThisInStatic: `this` is the calling model, by design. const model = this; const target = filter ?? model.$filter?.(); if (!target) { throw new Error( // biome-ignore lint/complexity/noThisInStatic: names the model the call was made on. `${this.name} has no filter — declare \`static $filter = () => YourFilter\` on the model, or pass one to filter().`); } // biome-ignore lint/complexity/noThisInStatic: the calling model builds its own query. const query = this.query(); const pagination = await applyFilterFromRequest(query, target, ctx ?? HttpContext.getOrFail(), options); stashPagination(query, pagination); return { query, page: pagination.page, size: pagination.size }; } /** * The same, then `paginate(page, size)` with the pagination the request resolved to — the * whole list endpoint in one call. */ static async filterPaginate(ctx, filter, options) { // biome-ignore lint/complexity/noThisInStatic: `this` is the calling model, by design. const model = this; // biome-ignore lint/complexity/noThisInStatic: forwards the call to the same model. const { query, page, size } = await model.filter.call(this, ctx, filter, options); return query.paginate(page, size); } } return FilterableModel; } //# sourceMappingURL=filterable_mixin.js.map