elysiajs / eden

Fully type-safe Elysia client
MIT License
147 stars 37 forks source link

[treaty] Transform types don't work well with responses #91

Open rhuanbarreto opened 4 months ago

rhuanbarreto commented 4 months ago

Reposting from https://github.com/elysiajs/elysia/issues/629 as I think it was the wrong place.

What version of Eden is running?

1.0.11

What platform is your computer?

Darwin 23.4.0 arm64 arm

What steps can reproduce the bug?

import Elysia, { t } from "elysia";
import { treaty } from "@elysiajs/eden";
import { describe, expect, it, beforeAll, afterAll } from "bun:test";

const app = new Elysia().get("/", () => new Date("2021-01-01"), {
  response: {
    200: t
      .Transform(t.Date())
      .Decode((value) => (value instanceof Date ? value.toISOString() : value))
      .Encode((value) => new Date(value)),
  },
});

const api = treaty<typeof app>("http://localhost:3012");

describe("dateTimeSchema", () => {
  beforeAll(() => app.listen(3012));
  afterAll(() => app.stop());

  it("should encode the response correctly", async () => {
    const { data, status } = await api.index.get();
    expect(status).toBe(200);
    expect(data).not.toBeEmpty();
    // @ts-expect-error data should be a date but it isn't. data comes as an ArrayBuffer
    expect(new TextDecoder().decode(data)).toBe(
      "Fri Jan 01 2021 00:00:00 GMT+0000 (Coordinated Universal Time)"
    );
    expect(data instanceof Date).toBeTrue();
  });
});

What is the expected behavior?

The tests to pass.

What do you see instead?

Test fails

Additional information

Transform types works well for endpoint parameters. For example, this helper converts a value from query and correctly check types:

import Elysia, { t } from "elysia";
import { treaty } from "@elysiajs/eden";
import { describe, expect, it, beforeAll, afterAll } from "bun:test";

const app2 = new Elysia().get(
  "/",
  ({ query: { datetime } }) =>
    datetime instanceof Date ? "Success!" : "Failed!",
  {
    query: t.Object({
      datetime: t
        .Transform(t.String())
        .Decode((value) =>
          typeof value === "string" ? new Date(value) : value
        )
        .Encode((value) => value.toISOString()) as unknown as ReturnType<
        typeof t.Date
      >,
    }),
  }
);

const api2 = treaty<typeof app2>("http://localhost:3013");

describe("dateTimeParams", () => {
  beforeAll(() => app2.listen(3013));
  afterAll(() => app2.stop());

  it("should encode the response correctly", async () => {
    const { data, status } = await api2.index.get({
      query: { datetime: new Date("2021-01-01") },
    });
    expect(status).toBe(200);
    expect(data).not.toBeEmpty();
    expect(data).toBe("Success!");
  });
});
mrctrifork commented 3 months ago

Could this be related to #54 ? A new version of Eden was released yesterday with some fixes similar to what you're expecting #87

rhuanbarreto commented 3 months ago

It works well! No need to have transform type for dates anymore. Thanks a lot!

rhuanbarreto commented 3 months ago

The problem still persists. I added failing test cases in https://github.com/elysiajs/eden/pull/92