joiful-ts / joiful

TypeScript Declarative Validation for Joi
239 stars 18 forks source link

Any way to support Joi `alternatives` statement or conditional in other way? #233

Closed zelid closed 2 years ago

zelid commented 2 years ago

Hello,

I have a need to make some properties mandatory depending on other properties. For example if country is US or CA than state is mandatory.

Joi has support through Joi.alternatives().conditional

const schema = Joi.object({
    type: Joi.number().required().valid(1, 2, 3),
    firstname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
    lastname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
    salary: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
    pension: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
    credit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
    debit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
}))

As I understand such decorator is not available with Joiful but what could be suitable way to validate conditions? Maybe read schema like const schema = jf.getSchema(Order) and extend it somehow with conditions.

Any help with ideas how to use both Joiful decorators for simple cases and extend special cases like conditions before performing POST body validation with:

const jfValidator = new jf.Validator({ abortEarly: false });
const jfResult = jfValidator.validateArrayAsClass(body, Order);

Thanks for any ideas and suggestions.

laurence-myers commented 2 years ago

Please try Joiful's custom decorator. This gives you access to the Joi instance, exposing more of the original Joi API.

Rough example:

class PersonalAccount {
    @jf.custom((Joi) => Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }))
    firstname?: string;
}

(This is similar to #216)