A currying function chain: field names, comparator, then direction
// Test single field sorting with GaffComparator
const sortValidator = TestValidator.sort(
"article sorting",
(sortable) => api.getArticles({ sort: sortable }),
)("created_at")(GaffComparator.dates((a) => a.created_at));
await sortValidator("+"); // ascending
await sortValidator("-"); // descending
// Test multi-field sorting with GaffComparator
const userSortValidator = TestValidator.sort(
"user sorting",
(sortable) => api.getUsers({ sort: sortable }),
)("lastName", "firstName")(
GaffComparator.strings((user) => [user.lastName, user.firstName]),
(user) => user.isActive, // only test active users
);
await userSortValidator("+", true); // ascending with trace logging
// Custom comparator for complex logic
const customSortValidator = TestValidator.sort(
"custom sorting",
(sortable) => api.getProducts({ sort: sortable }),
)(
"price",
"rating",
)((a, b) => {
const priceDiff = a.price - b.price;
return priceDiff !== 0 ? priceDiff : b.rating - a.rating; // price asc, rating desc
});
contracts/common.md#principled-implementation The API is called with the signed field names, its result is optionally filtered, and the comparator (reversed for the descending direction) is applied to adjacent pairs, so any adjacent pair out of order fails; checking adjacent pairs suffices for a total preorder.
contracts/common.md#clear-and-simple-design The function is curried in three steps so the request, the comparator, and the direction can be given at the moments each is known.
Validates sorting functionality of pagination APIs.
Tests sorting operations by calling the API with sort parameters and validating that results are correctly ordered. Supports multiple fields, ascending/descending order, and optional filtering. Provides detailed error reporting for sorting failures.
Processing cost: After one getter call, an optional filter scans N results and sortedness checks at most N minus one adjacent pairs. Signed field construction costs O(F); filter output costs O(N) space when requested.
Reuse: Each invocation must evaluate its supplied task or request to observe current behavior; prior results cannot replace these effectful checks.
Resource ownership: The returned promise retains invocation-local state until settlement. The callback owns its external resources, and this validator provides no cancellation or timeout.