elysiajs / elysia

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

Query params validation for array of string fail at 1.0.23 #677

Closed drsmile1001 closed 3 weeks ago

drsmile1001 commented 4 weeks ago

What version of Elysia.JS is running?

1.0.23

What platform is your computer?

Linux 5.15.146.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

import Elysia, { t } from "elysia";

const params = new URLSearchParams();
params.append("keys", "1");
params.append("keys", "2");

await new Elysia()
  .get("/", ({ query }) => query, {
    query: t.Object({
      keys: t.Array(t.String()),
    }),
  })
  .handle(new Request(`http://localhost/?${params.toString()}`))
  .then((res) => res.json())
  .then(console.log);

What is the expected behavior?

It should log

{
  keys: [ "1", "2" ],
}

What do you see instead?

It logs

{
  name: "SyntaxError",
  message: "JSON Parse error: Unable to parse JSON string",
}

Additional information

It's ok at 1.0.22. And if remove the vaildation. It can parse correctly.

import Elysia, { t } from "elysia";

const params = new URLSearchParams();
params.append("keys", "1");
params.append("keys", "2");

await new Elysia()
  .get("/", ({ query }) => query)
  .handle(new Request(`http://localhost/?${params.toString()}`))
  .then((res) => res.json())
  .then(console.log);

It logs

{
  keys: [ "1", "2" ],
}
MatthewAry commented 3 weeks ago

It's likely that the issue here has to do specifically with using t.Array for query string. This issue is likely getting caused by a change in the 1.0.23 release which changes the way Array elements are validated. This release unintentionally broke things. @SaltyAom I suspect the problem was introduced here. https://github.com/elysiajs/elysia/commit/d1a70fca7bec2e0ddc15ff90fa21825b2d74b69e#diff-9043fd343dba2fc691e6d1577d67b4c164b7cdc2ce399d3a3cc787e06dd81c32R957-R974 as now we can't use t.Array to validate in query strings, we just flat out get errors. In my case I'm getting:

99 | c.query['sortBy'] = JSON.parse(c.query['sortBy'])
                                   ^
SyntaxError: JSON Parse error: Unexpected identifier "undefined"

Where sortBy is:

sortBy: t.Array(t.Union([t.Literal('something'), ... t.Literal('SomethingElse')]))

Until this is resolved, I will be reverting to 1.0.22 as I don't experience this error with that release.

drsmile1001 commented 2 weeks ago

Thanks @SaltyAom, but I think it still has some issue.

While elysia@1.0.22

import Elysia, { t } from "elysia";

const api = new Elysia().get("/", ({ query }) => query, {
  query: t.Object({
    keys: t.Optional(t.Union([t.String(), t.Array(t.String())])),
  }),
});

const noParams = await api
  .handle(new Request(`http://localhost/`))
  .then((res) => res.json());
console.log(noParams); //output: {}

const oneParams = new URLSearchParams();
oneParams.append("keys", "1");

const oneParamsResult = await api
  .handle(new Request(`http://localhost/?${oneParams.toString()}`))
  .then((res) => res.json());
console.log(oneParamsResult); //output: { keys: "1" }

const arrayParams = new URLSearchParams();
arrayParams.append("keys", "1");
arrayParams.append("keys", "2");

const arrayParamsResult = await api
  .handle(new Request(`http://localhost/?${arrayParams.toString()}`))
  .then((res) => res.json());
console.log(arrayParamsResult); //output: { keys: ["1","2"] }

And elysia@1.0.24 It will output:

{}
{
  keys: "1",
}
{
  name: "SyntaxError",
  message: "JSON Parse error: Unable to parse JSON string",
}
ilijapuaca commented 2 weeks ago

Same as above, still having this issue that started happening with v1.0.23, parsing fails with the message below:

{"name":"SyntaxError","message":"JSON Parse error: Unexpected identifier \"active\""}

Should this issue be reopened?

ilijapuaca commented 2 weeks ago

Here's a minimum repro that I ran into:

import {Elysia, t} from 'elysia';

new Elysia()
  .get('/', ({query}) => {
    return 'Hello World';
  },
  {
    query: t.Object({
      status: t.Optional(t.Union([t.String(), t.Array(t.String())]))
    })
  })
  .listen(8000);

Navigating to http://localhost:8000/?status=1&status=2 shows the error above

MatthewAry commented 1 week ago

Still seeing this issue.

87 |                             Object.assign(c, transformed)
88 | 
89 | if(params.Check(c.params) === false) {
90 |                             c.set.status = 422; throw new ValidationError('params', params, c.params)
91 |                     }
92 | if(typeof c.query['ids'] === "object") c.query['ids'] = JSON.parse(c.query['ids'])
                                                                       ^
SyntaxError: JSON Parse error: Unable to parse JSON string

Where the validation is:

  query: t.Object({
    ids: t.Union([t.Array(t.Numeric()), t.Numeric()])
  })

On ElysiaJS 1.0.25