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