Skip to content

@btravstack/contract


@btravstack/contract / zod

zod ​

Type Aliases ​

PageLimits ​

ts
type PageLimits = object;

Defined in: zod.ts:12

How large a page may be, and how large it is when the caller says nothing.

Both are the API's decision rather than the framework's, so both are overridable — the defaults are a listing that behaves reasonably when nobody has thought about it yet.

Properties ​

PropertyModifierTypeDescriptionDefined in
defaultLimit?readonlynumberThe size of a page whose caller named none. Default 20.zod.ts:14
maxLimit?readonlynumberThe largest page a caller may ask for. Default 100.zod.ts:16

SortOptions ​

ts
type SortOptions<Keys> = object;

Defined in: zod.ts:97

Type Parameters ​

Type Parameter
Keys extends readonly string[]

Properties ​

PropertyModifierTypeDescriptionDefined in
defaultSortreadonlySort<Keys[number]>The sort served when a caller names none. Required: an implicit default is a listing sorted by something nobody chose.zod.ts:101
sortableByreadonlyKeysThe keys this listing may be sorted on, from sortableBy.zod.ts:99

Functions ​

pageOf() ​

ts
function pageOf<Item>(item): ZodUnion<readonly [ZodObject<{
  hasNextPage: ZodLiteral<false>;
  hasPreviousPage: ZodLiteral<false>;
  items: ZodArray<Item>;
}, $strict>, ZodObject<{
  hasNextPage: ZodLiteral<true>;
  hasPreviousPage: ZodLiteral<false>;
  items: ZodArray<Item>;
  nextCursor: ZodString;
}, $strict>, ZodObject<{
  hasNextPage: ZodLiteral<false>;
  hasPreviousPage: ZodLiteral<true>;
  items: ZodArray<Item>;
  previousCursor: ZodString;
}, $strict>, ZodObject<{
  hasNextPage: ZodLiteral<true>;
  hasPreviousPage: ZodLiteral<true>;
  items: ZodArray<Item>;
  nextCursor: ZodString;
  previousCursor: ZodString;
}, $strict>]>;

Defined in: zod.ts:48

The schema of one page of item: the four pages that exist, as four closed objects.

A union rather than an intersection, because allOf of closed objects validates nothing in JSON Schema and the emitted OpenAPI document is an interop surface. strictObject, so a cursor on a closed side is refused rather than stripped: the arms differ by which fields they carry, and the schema this generates already says additionalProperties: false — a stripping parser would accept what its own published schema rejects.

What it parses to is assignable to Page<T>, which pagination.test-d.ts pins, and every page page builds parses against it, which pagination.spec.ts pins — so a field dropped, loosened or renamed on either side fails a check. Widening Page<T> with a field no page carries is the one drift neither sees.

Type Parameters ​

Type Parameter
Item extends ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>

Parameters ​

ParameterType
itemItem

Returns ​

ZodUnion<readonly [ZodObject<{ hasNextPage: ZodLiteral<false>; hasPreviousPage: ZodLiteral<false>; items: ZodArray<Item>; }, $strict>, ZodObject<{ hasNextPage: ZodLiteral<true>; hasPreviousPage: ZodLiteral<false>; items: ZodArray<Item>; nextCursor: ZodString; }, $strict>, ZodObject<{ hasNextPage: ZodLiteral<false>; hasPreviousPage: ZodLiteral<true>; items: ZodArray<Item>; previousCursor: ZodString; }, $strict>, ZodObject<{ hasNextPage: ZodLiteral<true>; hasPreviousPage: ZodLiteral<true>; items: ZodArray<Item>; nextCursor: ZodString; previousCursor: ZodString; }, $strict>]>


pageRequestOf() ​

Call Signature ​

ts
function pageRequestOf<Filters>(filters, limits?): ZodObject<{ [k in string | number | symbol]: ((("limit" | "after" | "before") & keyof Filters) extends never ? { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber> } & { -readonly [P in string | number | symbol]: Filters[P] } : { [K in "limit" | "after" | "before" as K extends keyof Filters ? never : K]: { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber> }[K] } & { [K in string | number | symbol]: { -readonly [P in string | number | symbol]: Filters[P] }[K] })[k] }>;

Defined in: zod.ts:167

The schema of a page input: a bounded limit, the two opaque cursors, at most one of them, whatever else this listing filters by, and — for a listing that names SortOptions.sortableBy — the sort it runs in.

The pair is refused by the schema rather than by the handler, so the refusal is published in the OpenAPI document and answered as a validation error rather than as application logic. What survives it is still two optional fields; pageRequest is what turns a parsed input into the one-direction PageRequest a port takes.

filters is required, and {} is how a listing says it has none — an absent argument and an empty shape would be the same call spelled two ways. limit, after, before and sort are the page's own and cannot be among them: a filter replacing one would silently unbound the limit, re-type a cursor or shadow the sort, so the shape refuses it at the call.

Type Parameters ​
Type Parameter
Filters extends ReservedKeysFree
Parameters ​
ParameterType
filtersFilters
limits?PageLimits
Returns ​

ZodObject<{ [k in string | number | symbol]: ((("limit" | "after" | "before") & keyof Filters) extends never ? { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber> } & { -readonly [P in string | number | symbol]: Filters[P] } : { [K in "limit" | "after" | "before" as K extends keyof Filters ? never : K]: { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber> }[K] } & { [K in string | number | symbol]: { -readonly [P in string | number | symbol]: Filters[P] }[K] })[k] }>

Call Signature ​

ts
function pageRequestOf<Filters, Keys>(filters, options): ZodObject<{ [k in string | number | symbol]: ((("limit" | "after" | "before" | "sort") & keyof Filters) extends never ? { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber>; sort: ZodPrefault<ZodObject<{ direction: ZodEnum<{ asc: ...; desc: ... }>; field: ZodEnum<{ [k in (...)]: (...) }> }, $strict>> } & { -readonly [P in string | number | symbol]: Filters[P] } : { [K in "limit" | "after" | "before" | "sort" as K extends keyof Filters ? never : K]: { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber>; sort: ZodPrefault<ZodObject<{ direction: ...; field: ... }, $strict>> }[K] } & { [K in string | number | symbol]: { -readonly [P in string | number | symbol]: Filters[P] }[K] })[k] }>;

Defined in: zod.ts:171

The schema of a page input: a bounded limit, the two opaque cursors, at most one of them, whatever else this listing filters by, and — for a listing that names SortOptions.sortableBy — the sort it runs in.

The pair is refused by the schema rather than by the handler, so the refusal is published in the OpenAPI document and answered as a validation error rather than as application logic. What survives it is still two optional fields; pageRequest is what turns a parsed input into the one-direction PageRequest a port takes.

filters is required, and {} is how a listing says it has none — an absent argument and an empty shape would be the same call spelled two ways. limit, after, before and sort are the page's own and cannot be among them: a filter replacing one would silently unbound the limit, re-type a cursor or shadow the sort, so the shape refuses it at the call.

Type Parameters ​
Type Parameter
Filters extends ReservedKeysFree
Keys extends readonly [string, string]
Parameters ​
ParameterType
filtersFilters
optionsPageLimits & SortOptions<Keys>
Returns ​

ZodObject<{ [k in string | number | symbol]: ((("limit" | "after" | "before" | "sort") & keyof Filters) extends never ? { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber>; sort: ZodPrefault<ZodObject<{ direction: ZodEnum<{ asc: ...; desc: ... }>; field: ZodEnum<{ [k in (...)]: (...) }> }, $strict>> } & { -readonly [P in string | number | symbol]: Filters[P] } : { [K in "limit" | "after" | "before" | "sort" as K extends keyof Filters ? never : K]: { after: ZodOptional<ZodString>; before: ZodOptional<ZodString>; limit: ZodPrefault<ZodNumber>; sort: ZodPrefault<ZodObject<{ direction: ...; field: ... }, $strict>> }[K] } & { [K in string | number | symbol]: { -readonly [P in string | number | symbol]: Filters[P] }[K] })[k] }>


sortableBy() ​

ts
function sortableBy<Item, Keys>(_item, keys): Keys;

Defined in: zod.ts:89

The sortable vocabulary of a listing, checked against the item it answers.

A curated set rather than every key: what a listing sorts on is an index decision, and publishing every column invites a caller to sort by one with no index behind it. A name outside the item's shape is a compile error here, so a typo cannot reach the wire as a 400.

Type Parameters ​

Type Parameter
Item extends ZodObject<Readonly<{ [k: string]: $ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>; }>, $strip>
Keys extends readonly [SortableKeys<Item["shape"]>, SortableKeys<Item["shape"]>]

Parameters ​

ParameterType
_itemItem
keysKeys

Returns ​

Keys

Released under the MIT License.