elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
9.1k stars 193 forks source link

Transform type (include Date) won't transform in Array schema #671

Open drsmile1001 opened 1 month ago

drsmile1001 commented 1 month ago

What version of Elysia.JS is running?

1.0.22

What platform is your computer?

Linux 5.15.146.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

Date schema

bun run code below:

await new Elysia()
  .post("/inArrayOfObject", ({ body }) => body[0].time.getFullYear(), {
    body: t.Array(
      t.Object({
        time: t.Date(),
      })
    ),
  })
  .handle(
    new Request("http://localhost/inArrayOfObject", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: `[{"time":"2024-06-06T00:00:00.000Z"}]`,
    })
  )
  .then((res) => res.text())
  .then(console.log);

will throw

{"name":"TypeError","message":"body[0].time.getFullYear is not a function. (In 'body[0].time.getFullYear()', 'body[0].time.getFullYear' is undefined)"}

log body will get:

[
  {
    time: "2024-06-06T00:00:00.000Z",
  }
]

shows time doesn't transform to Date.

Custom Transform

bun run code below:

import { Elysia, t } from "elysia";

await new Elysia()
  .post("/customTransformInArrayOfObject", ({ body }) => body, {
    body: t.Array(
      t.Object({
        v: t
          .Transform(t.String())
          .Decode((value) => parseFloat(value))
          .Encode((value) => value.toString()),
      })
    ),
  })
  .handle(
    new Request("http://localhost/customTransformInArrayOfObject", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: `[{"v":"3.14"}]`,
    })
  )
  .then((res) => res.text())
  .then(console.log);

will got [{"v":"3.14"}]

shows string doesn't transform to number.

What is the expected behavior?

While Transform schema do not nest in array. It transform correctly.

import { Elysia, t } from "elysia";

await new Elysia()
  .post("/inObject", ({ body }) => body, {
    body: t.Object({
      v: t
        .Transform(t.String())
        .Decode((value) => parseFloat(value))
        .Encode((value) => value.toString()),
    }),
  })
  .handle(
    new Request("http://localhost/inObject", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: `{"v":"3.14"}`,
    })
  )
  .then((res) => res.text())
  .then(console.log); //got `{"v":3.14}`
import { Elysia, t } from "elysia";

await new Elysia()
  .post("/inObject", ({ body }) => body.time.getFullYear(), { //transform success
    body: t.Object({
      time: t.Date(),
    }),
  })
  .handle(
    new Request("http://localhost/inObject", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: `{"time":"2024-06-06T00:00:00.000Z"}`,
    })
  )
  .then((res) => res.text())
  .then(console.log); // got 2024
await new Elysia()
  .post("/inArrayOfObject", ({ body }) => body[0].time.getFullYear(), {
    body: t.Array(
      t.Object({
        time: t.Date(),
      })
    ),
  })
  .handle(
    new Request("http://localhost/inArrayOfObject", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: `[{"time":"2024-06-06T00:00:00.000Z"}]`,
    })
  )
  .then((res) => res.text())
  .then(console.log); //got 2024

So, Transform schema should transform nest in array. Like below:

import { Elysia, t } from "elysia";

await new Elysia()
  .post("/customTransformInArrayOfObject", ({ body }) => body, {
    body: t.Array(
      t.Object({
        v: t
          .Transform(t.String())
          .Decode((value) => parseFloat(value))
          .Encode((value) => value.toString()),
      })
    ),
  })
  .handle(
    new Request("http://localhost/customTransformInArrayOfObject", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: `[{"v":"3.14"}]`,
    })
  )
  .then((res) => res.text())
  .then(console.log); //got 3.14