valibot icon indicating copy to clipboard operation
valibot copied to clipboard

feat: add JSON parse and stringify actions

Open EskiMojo14 opened this issue 7 months ago • 12 comments

Adds actions to validate and parse/stringify JSON.

EskiMojo14 avatar Apr 08 '25 11:04 EskiMojo14

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
valibot ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 4, 2025 2:24am

vercel[bot] avatar Apr 08 '25 11:04 vercel[bot]

My two cents: It's not explicit clear that it parses json string into an object. Perhaps parseJSON action would be more suitable? And that would also allow to have stringifyJSON action which could help transforming string into an object (though probably wouldn't be needed as much)

muningis avatar Apr 11 '25 06:04 muningis

Thank you for this PR! I will try to review and merge it soon.

fabian-hiller avatar Apr 20 '25 00:04 fabian-hiller

Open in StackBlitz

npm i https://pkg.pr.new/valibot@1137

commit: 742e428

pkg-pr-new[bot] avatar Apr 20 '25 00:04 pkg-pr-new[bot]

Thank you for this PR! I will try to finalize it in the next 2 days.

fabian-hiller avatar Apr 27 '25 01:04 fabian-hiller

Right now we are using the following API design:

v.parseJson(reviver?, message?);
v.stringifyJson(replacer?, message?);

I think for stringifyJson we should also support the space argument of JSON.stringify(...). This would change it to:

v.parseJson(reviver?, message?);
v.stringifyJson(replacer?, space?, message?);

Therefore, I wonder if message should be the first or last optional argument. What are people more likely to use? Here is an example with message as the first optional argument:

v.parseJson(message?, reviver?);
v.stringifyJson(message?, replacer?, space?);

Another thing I am not sure about if whether we should use a general config object with reviver, replacer and space as keys to be more flexibel:

v.parseJson(message?, config?);     // config is { reviver?: ... }
v.stringifyJson(message?, config?); // config is { replacer?: ..., space?: ... }

I have nor clear opinion right now. What do you think? @EskiMojo14, @EltonLobo07, @muningis

fabian-hiller avatar Apr 27 '25 20:04 fabian-hiller

i'm leaning towards the config object - though are there many actions in Valibot that accept one?

EskiMojo14 avatar Apr 27 '25 22:04 EskiMojo14

Not yet. That's why I started this discussion. This is the first case where we have optional configurations for an action. My goal is to find a good API design for a unified implementation that also works for other actions we may add in the long run.

fabian-hiller avatar Apr 27 '25 22:04 fabian-hiller

generally i think config objects are more futureproof, and make it easier to provide different optional options without needing to provide others

EskiMojo14 avatar Apr 27 '25 22:04 EskiMojo14

If we were to choose the config object, would you choose config or message to be define first?

v.parseJson(config?, message?); // `message` as last optional argument
v.parseJson(message?, config?); // `message` as first optional argument

I ask because I would try to keep this consistent across our codebase.

fabian-hiller avatar Apr 27 '25 22:04 fabian-hiller

config first seems more consistent with the codebase

EskiMojo14 avatar Apr 27 '25 23:04 EskiMojo14

Ok. I will wait for @EltonLobo07 and @muningis. My goal would be to make a decision tomorrow or Tuesday and release both actions with Valibot v1.1 in the next few days. If the decision takes longer than that, I will have to reschedule it for Valibot v1.2.

fabian-hiller avatar Apr 27 '25 23:04 fabian-hiller

I agree with @EskiMojo14 . I think config objects are better for optionals, as we will have just one place to accept all optionals. I am a bit hesitant to recommend a config object for a single optional. Even though config objects are great to be extendable, if we never plan to extend the config with a single optional, it would be a bit unnecessary. The user will have to do a bit more work to spell out the key of the config object, but it's not a big issue because of the autocomplete feature. Do you think it's a better idea to follow a rule - use config objects only if the action has more than one option? Or do you prefer to strictly be consistent?

So I would prefer this:

v.parseJson(reviver?, message?);
v.stringifyJson(config?, message?); // config is { replacer?: ..., space?: ... }

If we decide to be strictly consistent, this would be my next best choice:

v.parseJson(config?, message?);     // config is { reviver?: ... }
v.stringifyJson(config?, message?); // config is { replacer?: ..., space?: ... }

EltonLobo07 avatar Apr 28 '25 17:04 EltonLobo07

Great feedback Elton! Thank you! @EskiMojo14 and @muningis what would you vote for?

fabian-hiller avatar Apr 29 '25 02:04 fabian-hiller

little conflicted, but I think the consistency and futureproofing is worth the increase in verbosity - i don't know how many people would actually need to use the reviver anyway.

EskiMojo14 avatar Apr 29 '25 10:04 EskiMojo14

You can ignore the CI errors. I will take care of it. Seems like deno check is broken.

fabian-hiller avatar May 03 '25 16:05 fabian-hiller

Valibot v1.1.0 is available!

fabian-hiller avatar May 06 '25 04:05 fabian-hiller