Pagination API
Offset and cursor pagination across the repository and the query builder
paginate()
async paginate( page: number, pageSize: number, options: any = {}): Promise<{ data: T[]; total: number; page: number; pageSize: number }>Pages are 1-based. The options parameter is typed any and is currently unused. The result echoes page and pageSize back alongside the rows and the total count.
Parameters:
- page 1-based page number
- pageSize Rows per page
- options Typed any, currently unused
const result = await userRepo.paginate(2, 20);// { data: [...], total: 137, page: 2, pageSize: 20 }findAndCount()
async findAndCount( options: { relations?: string[] } = {}): Promise<{ data: T[]; total: number }>Returns every matching row plus the total count. No offset or limit is applied.
const { data, total } = await userRepo.findAndCount({ relations: ["posts"],});findAndCountAll()
async findAndCountAll(options?: { page?: number; pageSize?: number; conditions?: Partial<T>;}): Promise<{ data: T[]; total: number }>Defaults to page=1 and pageSize=20. It does NOT echo page and pageSize back — it returns only { data, total }.
const { data, total } = await userRepo.findAndCountAll({ page: 3, pageSize: 10, conditions: { active: true },});findMany()
async findMany(options?: { where?: Partial<T>; cursor?: { field: string; value: any; direction?: "forward" | "backward"; }; take?: number; skip?: number; orderBy?: { field: string; direction: "ASC" | "DESC" }; relations?: string[];}): Promise<T[]>Returns a plain array, NOT a { data, total } wrapper. The cursor emits a WHERE col > ? or WHERE col < ? predicate based on direction and orderBy.direction. take becomes LIMIT and skip becomes OFFSET.
const page = await userRepo.findMany({ where: { active: true }, orderBy: { field: "id", direction: "ASC" }, take: 20, skip: 40,});
const next = await userRepo.findMany({ cursor: { field: "id", value: lastId, direction: "forward" }, orderBy: { field: "id", direction: "ASC" }, take: 20,});QueryBuilder: limits
limit(limit: number): QueryBuilder<T>offset(offset: number): QueryBuilder<T>take(count: number): QueryBuilder<T> // alias for limitskip(count: number): QueryBuilder<T> // alias for offsetfirst(): QueryBuilder<T> // limit 1paginate(page: number, pageSize: number): QueryBuilder<T>orderBy(column: string, direction: "ASC" | "DESC" = "ASC"): QueryBuilder<T>Every method is chainable and returns the builder. paginate() sets limit and offset, but does NOT count — run countExec() separately if you need a total.
const rows = await userRepo .find() .where("active = ?", true) .orderBy("id", "ASC") .paginate(2, 20) .execute(orm.client);
const total = await userRepo .find() .where("active = ?", true) .countExec(orm.client);QueryBuilder: execution
async countExec(client: DBClient): Promise<number>async existsExec(client: DBClient): Promise<boolean>async execute(client: DBClient, cache?, cacheKey?): Promise<T[]>toSQL(): { query: string; params: any[] }toSQL() renders the built statement and its bound parameters without running it — useful for verifying the LIMIT and OFFSET a paginate call produced.
const { query, params } = userRepo .find() .where("active = ?", true) .limit(20) .offset(40) .toSQL();