hapijs / joi

The most powerful data validation library for JS
Other
20.94k stars 1.51k forks source link

Conditional options contain unknown keys: not #3044

Open klynchkurzawa opened 4 months ago

klynchkurzawa commented 4 months ago

Runtime

node.js

Runtime version

18, 20, 22

Module version

17.13.3

Last module version without issue

unknown

Used with

https://joi.dev/tester/

Any other relevant information

Hello,

After attempting to use conditionals in Joi, I believe there is an issue with .conditional() when I am invoking it. It appears as if when I attempt to invoke it per the docs .conditional(ref: string, options: WhenOptions[]) and what's defined on the interface, it attempts to invoke conditional(ref: Schema, options: WhenSchemaOptions)

Example schema:

Joi.object({
  x: Joi.string().min(1).max(5).required(),
  y: Joi.alternatives().conditional('x', [
    {
        is: 'foo',
        then: Joi.string().valid('bar').required()
    },
    {
       not: 'foo',
       then: Joi.string().optional(),
    },
  ]).match('one'),
})

Example payload:

{
  x: "foo2",
  y: "bar"
}

Expected behaviour:

Validation Passed

Actual behaviour:

An error is encountered stating that the key of not is unknown.

Error: Options contain unknown keys: not

Possible cause of the error

The conditional method appears to be invoking the incorrect overloaded method at https://github.com/hapijs/joi/blob/ed25e95c299190e9aace62569d4b8306b2d8e614/lib/index.d.ts#L1940 when it should be invoking https://github.com/hapijs/joi/blob/ed25e95c299190e9aace62569d4b8306b2d8e614/lib/index.d.ts#L1939 based off of the error that is being returned

What are you trying to achieve or the steps to reproduce?

I am trying to define a joi schema where there are alternatives using conditionals where the parameters are of the following corresponding types:

  1. string
  2. WhenOptions[]

What was the result you got?

I received an error:

Error: Options contain unknown keys: not

What result did you expect?

I expected to be able to define conditional alternatives by referencing an object's attribute using a string instead of a Reference object.

Marsup commented 4 months ago

Hi,

I can confirm the issue, it looks like it was designed to be only working with is/then, I'm looking for ways to alter the codebase to deal with that, but my time may be limited, so feel free to make a PR if you find a clever way to do it.

Marsup commented 4 months ago

By the way, I hope you're not using that exact construct to do a simple if/else, because it's obviously better written as is/then/otherwise in a single step.

klynchkurzawa commented 4 months ago

@Marsup Sorry, been busy the last few weeks and didn't see your reply. I did end up going with the is/then/otherwise approach to work around the issue.

I was using is/not/then for a more complicated structure but gave the above example as I thought it was the most simplistic and highlighted the issue I was seeing the best.