3.9 KiB
pagination
Purpose
Defines Zod schemas for pagination input and output shapes used across all Suaveplan list endpoints. These schemas serve as the single source of truth that is consumed by server route handlers, React data-fetching hooks, and OpenAPI document generators alike, ensuring cursor-based and offset-based pagination are expressed identically across every layer of the stack.
Features
PaginationInput— accepts an optional 1-basedpagenumber, alimit(clamped 1–200), and an opaquecursorstring; all fields optional so callers can omit what they don't needPaginationOutput— carries total count (nullable when unknown), current page, limit,hasNextPageflag, and opaquestartCursor/endCursorstrings for cursor-based traversal- Full TypeScript inference via
z.infer<>— no manual interface duplication - Both cursor-based and offset-based strategies represented in one schema set
- Zod v4 compatible
Usage: Basic Example
import { PaginationInput } from "@suaveplan/api-schemas/common";
// Parse a query-string object coming from an HTTP request
const params = PaginationInput.parse({ limit: 20, cursor: "eyJpZCI6IjEifQ==" });
// → { limit: 20, cursor: "eyJpZCI6IjEifQ==" }
Usage: Advanced Example
import { PaginationInput, PaginationOutput } from "@suaveplan/api-schemas/common";
// Validate request query params with safe parse
const result = PaginationInput.safeParse({ page: 2, limit: 50 });
if (!result.success) {
console.error(result.error.flatten());
} else {
const { page, limit } = result.data;
// Use page/limit to run a DB query, then build PaginationOutput:
const meta = PaginationOutput.parse({
total: 120,
page: 2,
limit: 50,
hasNextPage: true,
startCursor: "eyJpZCI6IjUxIn0=",
endCursor: "eyJpZCI6IjEwMCJ9",
});
}
API Reference
PaginationInput
Zod object schema. All fields optional.
| Field | Type | Description |
|---|---|---|
page |
number (int ≥ 1) |
1-based page index; ignored when cursor is present |
limit |
number (int 1–200) |
Maximum items per page |
cursor |
string (min length 1) |
Opaque cursor from a prior response |
Type export: type PaginationInput = z.infer<typeof PaginationInput>
PaginationOutput
Zod object schema. Returned as part of list responses.
| Field | Type | Description |
|---|---|---|
total |
number | null |
Total matching records; null when count is skipped |
page |
number | null |
Current page (null for pure cursor pagination) |
limit |
number (int ≥ 1) |
Items per page |
hasNextPage |
boolean |
Whether more items follow this page |
startCursor |
string | null |
Cursor pointing to first item in this page |
endCursor |
string | null |
Cursor pointing to last item in this page |
Type export: type PaginationOutput = z.infer<typeof PaginationOutput>
Implementation Notes
All fields in PaginationInput are optional to support partial query-string parsing in HTTP frameworks that pass unknown keys through. The limit field is hard-clamped to 200 to prevent accidental unbounded queries; services that require a different ceiling should create a refined schema via .superRefine(). The cursor is validated as a non-empty string but its internal encoding is opaque to this schema layer — encoding/decoding is the responsibility of the data adapter.