Skip to content

Fails to parse query containing %2B ( urlencoded + ) when query mark as array of date/string. #1162

Open
@drsmile1001

Description

@drsmile1001

What version of Elysia is running?

1.2.25

What platform is your computer?

No response

What steps can reproduce the bug?

import { Elysia, t } from "elysia";

const app = new Elysia().get(
  "/",
  ({ query }) => {
    return query;
  },
  {
    query: t.Object({
      date: t.Array(t.Date()), // Array here!
    }),
  }
);

const url = new URL("http://localhost/");
url.searchParams.append("date", "2025-01-01T01:00:00+08:00");

const result = await app
  .handle(new Request(url.toString()))
  .then((res) => res.json());

console.log(result);

What is the expected behavior?

The array of date should be parsed correctly and the result should be:

{
  date: [ new Date("2025-01-01T01:00:00+08:00") ]
}

What do you see instead?

The array of date is not parsed correctly and the result is:

{
  type: "validation",
  on: "query",
  summary: "Property 'date' should be one of: 'ArrayString', 'array'",
  property: "/date",
  message: "Expected union value",
  expected: {},
  found: {
    date: [ "2025-01-01T01:00:00 08:00" ], // notice the missing '+' sign
  },
}

Additional information

I looked into issues related to encoding +, including:

I also saw an explanation of the behavior of URLSearchParams: #960 (comment).
I also believe following this behavior is correct. Therefore, the example code above generates the query string using URLSearchParams.

However, it seems that the Elysia parsing middleware still has some issues when dealing with arrays. If not wrapped in an array, the current behavior is correct.

Edited, give a sample to show current issue is about array of string has problem.

import Elysia, { t } from "elysia";

const api = new Elysia().get("", ({ query }) => query, {
  query: t.Object({
    array: t.Array(t.String()), // Mark as an array
    simple: t.String(), // Mark as not an array
  }),
});

const url = new URL("http://localhost/");
url.searchParams.append("array", "a+b");
url.searchParams.append("array", "c+d");
url.searchParams.append("simple", "e+f");
console.log(url.href); //http://localhost/?array=a%2Bb&array=c%2Bd&simple=e%2Bf  `+` encoded as `%2B`

const result = await api
  .handle(new Request(url.href))
  .then((response) => response.json());

console.log(result);

/**
  * Result:
  {
    array: [ "a b", "c d" ], // missing `+` in the array
    simple: "e+f", // correct when not an array
  }
 */

Have you try removing the node_modules and bun.lockb and try again yet?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions