fabian-hiller / valibot

The modular and type safe schema library for validating structural data 🤖
https://valibot.dev
MIT License
6k stars 186 forks source link

Forward is changing the issues paths on flatten with an error in the forwarded property #616

Closed dusty closed 4 months ago

dusty commented 4 months ago

Using the following schema

const RegisterSchema = v.pipe(
  v.object({
    email: v.pipe(
      v.string(),
      v.nonEmpty('Please enter your email.'),
      v.email('The email address is badly formatted.')
    ),
    password1: v.pipe(
      v.string(),
      v.nonEmpty('Please enter your password.'),
      v.minLength(8, 'Your password must have 8 characters or more.')
    ),
    password2: v.string(),
  }),
  v.forward(
    v.check((input) => input.password1 === input.password2, 'The two passwords do not match.'),
    ['password2']
  )
)

If there isn't an error in the password1 property and you pass in a non-matching password2 property, the flatten output is as expected

const r2 = v.safeParse(RegisterSchema, {
  email: 'asdf@asdf.com',
  password1: 'asdfasdf',
  password2: 'asdfa',
})
console.log(JSON.stringify(v.flatten(r2.issues), null, 2))
{
  "nested": {
    "password2": [
      "The two passwords do not match."
    ]
  }
}

But, if there is an error in the password1 property, the flattened output becomes

const r1 = v.safeParse(RegisterSchema, {
  email: 'asdf@asdf.com',
  password1: 'asdf',
  password2: 'asdfa',
})
console.log(JSON.stringify(v.flatten(r1.issues), null, 2))
{
  "nested": {
    "password1.password2": [
      "Your password must have 8 characters or more."
    ],
    "password2": [
      "The two passwords do not match."
    ]
  }
}

Below is the entire code to reproduce with a copy paste

const v = require('valibot')

const RegisterSchema = v.pipe(
  v.object({
    email: v.pipe(
      v.string(),
      v.nonEmpty('Please enter your email.'),
      v.email('The email address is badly formatted.')
    ),
    password1: v.pipe(
      v.string(),
      v.nonEmpty('Please enter your password.'),
      v.minLength(8, 'Your password must have 8 characters or more.')
    ),
    password2: v.string(),
  }),
  v.forward(
    v.check((input) => input.password1 === input.password2, 'The two passwords do not match.'),
    ['password2']
  )
)

const r1 = v.safeParse(RegisterSchema, {
  email: 'asdf@asdf.com',
  password1: 'asdf',
  password2: 'asdfa',
})
console.log(JSON.stringify(v.flatten(r1.issues), null, 2))

console.log('---')

const r2 = v.safeParse(RegisterSchema, {
  email: 'asdf@asdf.com',
  password1: 'asdfasdf',
  password2: 'asdfa',
})
console.log(JSON.stringify(v.flatten(r2.issues), null, 2))
dusty commented 4 months ago

Didn't notice the playground. Here is one.

https://valibot.dev/playground/?code=JYWwDg9gTgLgBAKjgQwM5wG5wGZQiOAcg2QBtgAjCGQgKFoGMIA7VeAJQFMBzYNzqAGUGAC04hkcALyYAdGGBhOAClpw5ECgCtODGMoDea9XHHJgpAFxyFS1SZMZZbKMGbdlASgA0xh0+YWAFFwGABPZUIABVJONE5TZhgBODCIAFcoUwkLWUIfP0dZMwtIgBUxbPNSFAATWqhOVHQ+OApkWtIwnGgJGGTavM9CgocwNFQAd2hagEZrJ1sVQvUnFzcPUYc5QOYQsHDImLjUBM4klLTMuHHm6ahB-N9tuRA3ABlz7hgRZQAObxEACaGSytymMzgIHSbDgImQGASfzgomQUGQegE6GgUOgnCGI2eJnB91qACYFs4YK53F4iQBfLZObDQSZo2r2IqiXQAa2UyjcYHSME80gAfHBBcL5BNSbNpFIZFKYDK7jMyYDCBUEjBpjdZTN0LUIHBAvA+qIhkT1ABtQgk9WEAC6xmGw0YLFhUHlMjWyGwnCiaNOyi4vH4Qm5EkBRnUJSsRDQtWwAAEk9hZEwQIQiQ6HvNE6hkznjHnydZCOnkCXGbRgNg4MoAITe5zpBgMJqoUWxlGeiCxWSkCAeZmkZD9c7KVt8VDpJqeYb0+hMVgD-HDjyEAC0u-yK898CgZOkclQ-sDwZUYb4yUjYmjcF78Yr6bTRYzWZL6jLBcrH-Tb99TVB4KULZNq18Wt60bFsyTbDsux7YxV1QdchxHZQxwnZJmGneDZ3nbsl1oIA

fabian-hiller commented 4 months ago

I think you found a bug. That's my fault, I'm sorry. I will look into it as soon as possible and get back to you.

fabian-hiller commented 4 months ago

v0.31.0-rc.7 is available

dusty commented 4 months ago

Wow that was fast. Thanks!