@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.
50 lines • 2.84 kB
TypeScript
import type { ColumnFilter } from './operators.js';
import type { FilterInput, GroupByCountRequest, SortItem } from './types.js';
/** Map one `filter[field]=…` entry to `ColumnFilter[]` (Spatie/JSON:API shapes). */
export declare function toColumnFilters(field: string, value: unknown): ColumnFilter[];
/**
* Parse the `distinct` param into a de-duplicated list of field names. Accepts a
* comma-separated string (`distinct=afsc,base`) or a repeated/array form
* (`distinct[]=afsc&distinct[]=base`) — the shapes the client's `toQueryString()`
* and structured `build()` emit. Non-string entries are ignored.
*/
export declare function parseDistinct(distinct: unknown): string[];
/**
* Parse the `sort` param into ordered {@link SortItem}s. Accepts the string form
* (`-createdAt,name` or `sort[]=name`) and the already-structured
* `[{ field, direction }]` form the client builder's `build()` emits — the
* latter used to be filtered out entirely as "not a string", silently dropping
* the ordering.
*/
export declare function parseSort(sort: unknown): SortItem[];
/**
* Parse a decoded request query object — e.g. AdonisJS `ctx.request.qs()` — into
* a structured {@link FilterInput}. Understands the Spatie / JSON:API shapes the
* `@adonis-agora/filter-client` builder emits:
*
* - `filter[status]=active` → equals
* - `filter[id]=1,2,3` / `filter[id][]=1&filter[id][]=2` → IN
* - `filter[age][gte]=18` → operator filter
* - `sort=-createdAt,name` → sort items
* - `distinct=afsc,base` / `distinct[]=afsc&distinct[]=base` → distinct fields
* - `groupByCount[field]=tag&groupByCount[limit]=20` → value enumeration
* - `search=term`, `page`/`size` (or `page[number]`/`page[size]`)
*
* It also accepts the structured shape the client builder's `build()` returns —
* `{ filter: { where: [...] }, sort: [{ field, direction }], paginate: { page, size } }`
* — so a POST search body can be handed straight in, and so OR/AND groups (which
* serialize to a top-level `where[0][field]=…`) survive the round trip.
* `include` is not consumed here: eager-loading is the caller's `preload` call.
*
* Pure reshape — no validation or allow-listing here; that happens in
* {@link applyFilter} against the {@link FilterConfig}.
*/
export declare function parseFilterRequest(qs: Record<string, unknown>): FilterInput;
/**
* Parse the `groupByCount` block the client builder emits
* (`groupByCount[field]=tag&groupByCount[limit]=20&groupByCount[offset]=…&groupByCount[search]=…`).
* Returns `undefined` when no usable block is present. Pure reshape, like the rest of this
* module — field validation happens at execution, against the allow-list.
*/
export declare function parseGroupByCount(value: unknown): GroupByCountRequest | undefined;
//# sourceMappingURL=parse_request.d.ts.map