Closed afharo closed 3 months ago
Thanks, sorry for the delay.
This change seems to break a construct that I'm using in a lot of places. When I want to allow an object to contain additional properties, but have Joi strip them out, I have:
const Joi = require('joi');
const schema = Joi.object({ foo: Joi.string()} )
.unknown(false)
.options({ stripUnknown:true });
console.log(schema.validate({foo: 'abc', bar: 'def'}));
With this change the validation fails:
{
value: { foo: 'abc', bar: 'def' },
error: [Error [ValidationError]: "bar" is not allowed] {
_original: { foo: 'abc', bar: 'def' },
details: [ [Object] ]
}
}
... whereas before it succeeded and stripped out bar
from the value
:
{ value: { foo: 'abc' } }
I guess the reason why I'm using that construct is that I've liberally added .unknown(false).options({ stripUnknown: true })
to the top-level Joi.object
schemas, because I've run into the problem that this is fixing 😅
I'll adapt my code, but this change probably shouldn't have gone out in a patch.
I feared this would happen, but your schema is a bit self-contradictory, explicitly denying unknowns with the expectation that it would be stripped is in my opinion a bug, as local overrides should always have priority over options. I need to think about it a bit more before reverting (or not), but it really looks like you just got lucky that this bug was in your favor.
Yeah, I agree. I think it ended up like that because (a few years back) I found that it was the only way to get Joi.object
to work the way I needed it to :sweat_smile:
I've adopted the new version in all our projects now, so all good from me.
Hi there
I think the stripUnknown is broken since this fix. I have gone through the commit and I think the tests are wrong.
I have added a few additional tests (see zip attached), they all fail now, but this is how I interprete the manual and parameters. It is also closer to behavior <= 17.13.1
kind regards
Alexander
Just sharing my 2 cents, but I'll leave it to the owners to keep me honest.
stripUnknown: true
option.However, I tend to disagree on 3 and 4. Those objects explicitly allow extra properties to go through. The global option shouldn't affect those explicitly set flags.
A use case I can think of:
A logger requires message
and a meta
object containing any additional context to the logs. Inside the meta
, meta.trace_id
is required to be an alphanum of 16 chars.
You want your schema to define message
as string, and meta
as an object with the property trace_id
and an explicit local .unknown()
to allow extra fields to go through the validation.
I hope it makes sense.
I agree with this, as I previously mentioned, local overrides should always have priority over options, and this is what happens here, but we can indeed add a root property to demonstrate that fully.
Hi all
I disagree, I do not understand the use of stripUnknown if it never strips unknown properties. Neither with unknown(true) or unknown(false). Am I missing something obvious here?
kind regards
Alexander
It does when you don't give specific instructions for that schema, basically the default state. There is currently no way to go back to the default state but I think a unknown(null)
is not super hard to implement if that's your need.
When explicitly specifying
.unknown(false)
, running validations withstripUnknown: true
should respect the local override.