paginate — pagination envelope
Imported from the facade: import { paginate, sql } from "@/core/facade.ts".
nexgen-style pagination over Drizzle. paginate is a namespace with three methods — paginate.query, paginate.table, paginate.model — that all return the same PaginatedResult envelope. It normalizes page/perPage, clamps to maxPerPage, computes the URL meta, and runs the count + paged select. See Database.
sql is re-exported alongside paginate so you can write where: sql filters without a second Drizzle import.
Signature
| Function | Signature | Description |
|---|---|---|
paginate.query | <T>(options: PaginateQueryOptions<T>) => Promise<PaginatedResult<T>> | Fully custom total() / data(limit, offset) pagination — joins, aggregates, anything. |
paginate.table | <T>(table: SQLiteTable, options?: PaginateTableOptions) => Promise<PaginatedResult<T>> | Paginate a whole schema table with optional where / orderBy. |
paginate.model | <T>(options: PaginateModelOptions<T>) => Promise<PaginatedResult<T>> | Paginate relational queries (db.query.<table>) with with / columns / extras. |
Which one do I use?
| You want to… | Use |
|---|---|
| Paginate the full rows of one table | paginate.table (paginate.table(schema.users, { page: 2 })) |
Paginate eager-loaded relations (db.query.<table>) | paginate.model (with: { posts: true }) |
| Own the count and data queries completely (joins, aggregates) | paginate.query (you supply total + data) |
Shared envelope
All four pages return the same shape — ready for the UI:
ts
type PaginatedResult<T> = {
current_page: number;
data: T[];
first_page_url: string | null;
from: number | null;
last_page: number;
last_page_url: string | null;
next_page_url: string | null;
path: string;
per_page: number;
prev_page_url: string | null;
to: number | null;
total: number;
};Common pagination input (each method accepts these):
ts
interface PaginateInput {
page?: number; // 1-indexed, clamped to last_page
perPage?: number; // items per page (default 15)
maxPerPage?: number;// clamp on perPage (default 100)
path?: string; // base path used in generated *_page_url links
}Notes
pagenever exceedslast_page;perPageis clamped bymaxPerPage(default 100).- The envelope uses the same field names as nexgen's paginator — ready for the UI.
- Each method is documented on its own page (query · table · model).
