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.

92 lines 4.25 kB
import type { SortItem } from './types.js'; /** * A decoded keyset cursor: the ordered values of the keyset columns (the active * sort columns plus a stable primary-key tiebreaker) captured from a boundary * row. The values line up positionally with the keyset's {@link SortItem}[]. */ export type CursorValues = unknown[]; /** * Cursor (keyset) pagination parameters, as parsed from a request: * * - `after` — return the page immediately following this opaque cursor (forward). * - `before` — return the page immediately preceding this opaque cursor (backward). * - `first` / `last` — page size for forward / backward paging respectively. * * `after` and `before` are mutually exclusive; if both are given, `after` wins. */ export interface CursorParams { after?: string; before?: string; first?: number; last?: number; } /** * A single page of keyset-paginated results assembled by {@link buildCursorPage}. * * - `items` — the rows for this page, in the requested order. * - `nextCursor` — opaque cursor for the next forward page, or `null` when this * is the last page. * - `prevCursor` — opaque cursor for the previous (backward) page, or `null` * when this is the first page. * - `hasNext` / `hasPrev` — convenience booleans mirroring the cursors. */ export interface CursorPage<T> { items: T[]; nextCursor: string | null; prevCursor: string | null; hasNext: boolean; hasPrev: boolean; } /** * Encodes keyset cursor values into a compact, URL-safe opaque string * (base64url of a JSON array). The shape is intentionally opaque to clients — * only this module reads it back. * * `Date` values are encoded as `{ $d: <iso> }` so they round-trip to `Date` * instances on decode (plain JSON would yield a string and break date keyset * comparisons). */ export declare function encodeCursor(values: CursorValues): string; /** * Decodes an opaque cursor string back into its keyset values. Returns `null` * when the cursor is malformed (bad base64, bad JSON, or not an array) so the * caller can ignore an invalid cursor instead of crashing. */ export declare function decodeCursor(cursor: string): CursorValues | null; /** * Builds the keyset {@link SortItem}[] for cursor pagination: the caller's * effective sorts, with a stable primary-key tiebreaker appended if it is not * already present. The tiebreaker inherits the direction of the last sort column * so the overall ordering stays monotonic (important for a correct * `(cols, pk) > (...)` comparison). */ export declare function buildKeyset(sorts: SortItem[], primaryKey: string): SortItem[]; /** Flips every keyset column's direction (for backward cursor paging). */ export declare function reverseKeyset(keyset: SortItem[]): SortItem[]; /** * Extracts the keyset values from a fetched row, in keyset column order. * Supports dotted relation paths (e.g. `author.name`) by walking the object. */ export declare function extractCursorValues(row: Record<string, unknown>, keyset: SortItem[]): CursorValues; /** The keyset shape {@link applyCursor} resolves and hands to {@link buildCursorPage}. */ export interface ResolvedCursor { /** The base keyset (effective sort + primary-key tiebreaker), in forward order. */ keyset: SortItem[]; /** Effective page size — the number of rows to keep for this page. */ size: number; /** True when paging backward (a `before` cursor was supplied). */ backward: boolean; /** True when a cursor (`after`/`before`) was supplied — the opposite page is then known to exist. */ hasCursor: boolean; } /** * Assembles a {@link CursorPage} from the rows fetched for a keyset query. * * The query is expected to have been built by {@link applyCursor}, which fetches * one extra row (`limit = size + 1`) so we can detect a further page. For * backward paging the rows come back reversed and are flipped here to restore * the caller's requested order. Boundary cursors are computed from the base * keyset so they round-trip regardless of paging direction. */ export declare function buildCursorPage<T extends Record<string, unknown>>(rows: T[], resolved: ResolvedCursor): CursorPage<T>; //# sourceMappingURL=cursor.d.ts.map