Changelog

Notable changes in each release.

All notable changes to ArturRios.Output are recorded in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

3.3.0 - 2026-10-13

Added

  • Token pagination: PaginateByToken and PaginateByTokenAsync page an IQueryable<T> by signed continuation token instead of page number. Each page resumes after the previous one with a keyset filter (WHERE key > @lastKey), so deep pages stay fast, rows added or removed between requests are neither repeated nor skipped, and the count query is skipped unless includeTotalCount is set. Overloads take a tiebreaker for keys that repeat, and a SortDirection.
  • Tokens are HMAC-SHA256 signed, so a caller can only reach a page with the token issued by the page before it: an edited or forged token is rejected. PageTokenOptions carries the signing key, an optional Lifetime and an optional Scope that binds tokens to one listing. A rejected token returns an empty output carrying one of the PageTokenErrors (Invalid, Expired, Mismatch) instead of throwing.
  • PaginatedOutput<T>.NextPageToken, HasNextPage and WithNextPageToken.

Fixed

  • Paginate and PaginateAsync return an empty page when (pageNumber - 1) * pageSize does not fit in an int. The offset used to overflow, usually to a negative number that LINQ and SQLite treat as no offset, so a request for a far-out page (for example pageNumber = int.MaxValue) came back holding the first page’s items.

3.2.0 - 2026-08-24

Changed

  • PaginateAsync strips the Convert(..., Object) node from the orderBy expression before ordering, as Paginate already did, so a relational provider can translate a value-type ordering key to SQL.
  • Paginate and PaginateAsync agree on a supplied totalCount: it is clamped to a minimum of 0, reported verbatim as TotalItems, and never suppresses the page query. The empty-result short circuit applies only when the count was computed by the method itself.
  • Paginate and PaginateAsync throw ArgumentNullException for a null query.
  • AddErrors / AddMessages, and the fluent WithErrors / WithMessages, accept a null collection and ignore it.
  • Microsoft.EntityFrameworkCore updated from 10.0.10 to 10.0.11.

3.1.0 - 2026-07-23

Changed

  • Data, Messages, Errors, Timestamp and PageSize have public setters, and the [JsonInclude] attributes are gone, so the output types round-trip under Newtonsoft.Json as well as System.Text.Json, in both cross-serializer directions.
  • Microsoft.EntityFrameworkCore updated from 10.0.1 to 10.0.10.

Fixed

  • Messages and Errors are never null: assigning null — as a deserializer does for an explicit "errors": null — resets them to an empty list instead of making Success throw.

3.0.0 - 2026-07-23

Changed

  • Breaking: PaginatedOutput.WithPagination takes the page size as its second argument: WithPagination(pageNumber, pageSize, totalItems).
  • Breaking: PaginatedOutput.PageSize is the requested page size rather than the number of items in the current page, and TotalPages is 0 when no page size has been set.
  • Microsoft.EntityFrameworkCore updated from 9.0.10 to 10.0.1.

Fixed

  • ProcessOutput and DataOutput round-trip through System.Text.Json; deserializing used to produce an empty envelope regardless of the JSON.
  • TotalPages was wrong on a partial last page and saturated to int.MaxValue on an empty page.

2.0.1 - 2025-12-04

Changed

  • Package metadata and the README shipped in the package refreshed. No library code changes.

2.0.0 - 2025-11-25

Changed

  • Package version moved to 2.0.0. No library code changes from 1.0.2.

1.0.2 - 2025-11-25

Changed

  • Targets net10.0 instead of net8.0.

1.0.1 - 2025-11-12

Added

  • ProcessOutput, DataOutput<T> and PaginatedOutput<T> to return messages, errors and typed or paginated payloads, with fluent helpers.
  • CustomException, a base exception carrying several messages.
  • Paginate and PaginateAsync extension methods to paginate an IQueryable<T> into a PaginatedOutput<T>.