Releases: adonisjs/http-transformers
Prevent subtype reduction from collapsing collection and paginator return types
2.3.1 (2026-02-27)
There was an issue with the BaseSerializer.serialize method, where returning a Union of collection or paginated data leads to TypeScript's subtype reduction on the inferred return type.
Each serialize call individually resolves to the correct overload:
serialize(UserTransformer.paginate(...))→Promise<{ data: UserData[]; metadata: SimplePaginatorMetaKeys }>serialize(UserTransformer.transform(...))→Promise<{ data: UserData[] }>
But when TypeScript infers the combined return type, it sees that { data: UserData[]; metadata: ... } is structurally assignable to { data: UserData[] } (an object with extra properties is always assignable to one with fewer). This means Promise<PaginatedType> is a subtype of Promise<CollectionType>. TypeScript's subtype reduction removes the more specific type from the union, collapsing it down to just, Promise<{ data: UserData[] }>.
The metadata variant gets swallowed entirely.
The fix was to add metadata?: never to the collection return type and make these two types structurally different.
Here's a reproduction with simple code.
Bug Fixes
- prevent subtype reduction from collapsing collection and paginator return types (0fa2d7d)
Full Changelog: v2.3.0...v2.3.1
Wrap bare objects in data property and add serializeWithoutWrapping variant
2.3.0 (2026-02-24)
Bug Fixes
- wrap bare object input in serializer wrap key (30fe13a)
Features
- add serializeWithoutWrapping method to base serializer (016a030)
Full Changelog: v2.2.0...v2.3.0
Trace transformers resolution using diagnostic channels
2.2.0 (2026-02-14)
Features
- add tracing channel for transformer serialization (9c59765)
Full Changelog: v2.1.2...v2.2.0
Bug fix for the omit method
Simplify ExtractTransformerVariants helper to avoid running into circular references
2.1.1 (2026-02-04)
Bug Fixes
- broken types (dfc28d0)
- simplify ExtractTransformerVariants helper to avoid running into circular references (063e142)
Full Changelog: v2.1.0...v2.1.1
Add useVariant and depth methods to the Paginator
Set pagination metadata to any
2.0.1 (2026-01-10)
Bug Fixes
- set paginator metadata to any (3049a88)
Full Changelog: v2.0.0...v2.0.1
Introduce BaseSerializer class and remove the serialize helper
2.0.0 (2026-01-10)
Breaking Changes
- Serialize function removed
- The standalone
serialize()function has been removed from the package exports. - You'll need to create your own serializer instance instead of using the exported function
- Projects will need to instantiate a serializer class (the tests show examples of
apiSerializerandwrappedApiSerializer)
- Pagination metadata renamed
- Paginated responses now use metadata instead of meta as the key
- If you're accessing response.meta, you'll need to change it to response.metadata
- Paginator API simplified
- The
setMetaData()method has been removed from the Paginator class - You can no longer chain
.setMetaData()to update or compute pagination metadata after
creating a paginator - Metadata must be provided upfront when creating the paginator
- Type system changes
- The Paginator class no longer has a generic MetaData type parameter - it now accepts any
Record<string, any> - Type inference for pagination metadata will be less specific (returns Record<string, any>
instead of your exact metadata shape)
New Features
Response wrapping support
- The type system now supports wrapping responses with a custom key (like wrapping data in a
data property) - This appears to be infrastructure for a new serializer configuration option
Migration Impact
Projects will need to:
- Replace calls to
serialize()with a serializer instance method - Update any code accessing .meta on paginated responses to use .metadata
- Remove any uses of
.setMetaData()and provide all metadata upfront - Adjust TypeScript types if they relied on the specific MetaData generic parameter
Creating a custom serializer
Assuming you are building an API and want control over two aspects of the response. One is wrapping top-level items, collections and pagination data inside a custom property and reshape the pagination metadata. Both are possible by creating a custom API serializer.
import { BaseSerializer } from '@adonisjs/core/transformers'
class ApiSerializer extends BaseSerializer<{
Wrap: 'data'
PaginationMetaData: {
totalItems: number
currentPage: number
}
}> {
wrap: 'data' = 'data'
definePaginationMetaData(metaData: any): {
totalItems: number
currentPage: number
} {
return { totalItems: metaData.total, currentPage: metaData.current }
}
}Now, all top-level responses will be wrapped within the data property and pagination metadata will have totalItems and currentPage properties. All this is type-safe and will be reflected in the Controller response type.
Features
- export helpers and BaseSerializer (79be943)
- Remove serialize method in favor of BaseSerializer (e0e93e8)
- update BaseSerialize.serialize method to always accept containerResolver (6777012)
BREAKING CHANGES
- BaseSerializer allows creating custom serializers with support for reshaping
the pagination metadata and wrapping top-level values inside a custom property
Full Changelog: v1.6.2...v2.0.0
Full Changelog: v1.6.2...v2.0.0
Release 1.6.2
Update the types package
1.6.1 (2025-12-03)
Full Changelog: v1.6.0...v1.6.1