Closed lomithrani closed 5 months ago
I've encountered the exact same problem, so I leave a report here for those who have met it too.
When receiving a response from an API endpoint, Eden Treaty v2 does not deserialize ISO8601 date strings into Date
instances based on the response schema defined using Elysia's t
utility. Instead, the current implementation simply returns the result of await response.json()
.
Consequently, the actual runtime value of the date field is a string
, which differs from its expected type definition of Date
as specified in the response schema.
Eden Treaty v2 should properly deserialize ISO8601 date strings into Date
instances, as indicated by the response schema, to maintain consistency between the runtime values and the type definitions.
To address this issue, consider the following approach:
Modify Elysia to send responses serialized using the superjson
library when the Use-Superjson
header is present in the request.
Update Eden Treaty v2 to include the Use-Superjson
header in its requests to the API endpoints.
Upon receiving the response, Eden Treaty v2 should deserialize the JSON payload using superjson
, which will automatically convert ISO8601 date strings into Date
instances based on the response schema.
By implementing this solution, Eden Treaty v2 will ensure that the deserialized response data aligns with the expected type definitions, including the proper handling of Date
instances.
I've written a simple workaround using the superjson library to address the issue of deserializing ISO8601 date strings to Date
instances. Let me share the solution with you.
First, install Superjson by running bun add superjson
. Then, add the following code snippets to the respective sides:
import { serverTiming } from '@elysiajs/server-timing';
import { swagger } from '@elysiajs/swagger';
import { Elysia, t } from 'elysia';
import { log } from './logger';
import { serialize } from 'superjson';
export const app = new Elysia() .use(swagger()) .use(serverTiming()) .use(log.into()) // ↓ Add this block .mapResponse(({ response, set }) => { const isJson = typeof response === 'object'; if (!isJson) return; const { json, meta } = serialize(response); set.headers['Elysia-Superjson-Meta'] = JSON.stringify(meta); log.info(json); return new Response(JSON.stringify(json)); }) // ...
- Eden Treaty v2 (client)
```ts
import { treaty } from '@elysiajs/eden';
import { deserialize } from 'superjson';
import { describe, expect, it } from 'bun:test';
import { app } from '../src';
const apiClient = treaty(app, {
// ↓ Add this block
onResponse: async (response) => {
const superJsonMeta = response.headers.get('Elysia-Superjson-Meta');
if (!superJsonMeta) return;
return deserialize({
json: await response.json(),
meta: JSON.parse(superJsonMeta),
});
},
});
// ...
According to the tests, seems like Date
and bigint
get parsed properly now.
Would like to get feedbacks👀
Faced the same issue. I believe I have addressed it in this branch of my fork feel free to install it by doing
npm install mrctrifork/eden#fix-serialization
I've noticed that the values of Date type in eden treaty don't match their types (In nested object, not sure about first level depth) Type inference works correctly and the type is Date but the actual value at runtime is a string and not a date (see following screenshots), I've checked server side and the type sent are indeed Dates
Types:
I use edenTreaty as such :
Server side :