hapijs / joi

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

How to get resolved reference value of provided object instead of Ref Object in ValidationError ? #2996

Open Ahger opened 11 months ago

Ahger commented 11 months ago

Context

How can we help?

Hello, a little question. Im using schema like:

const validationResult = Joi.object({
  dateFrom: Joi.date().iso().max(Joi.ref('dateTo')).empty('').required(),
  dateTo: Joi.date().iso().empty('').required(),
}).validate({
  dateFrom: '2023-10-26',
  dateTo: '2023-10-25',
})

As expected it results with error like:

const { error } = validationResult;

expect(error).toBeInstanceOf(Error);
expect(error.name).toBe('ValidationError');
expect(error.details[0].context.limit).toEqual({
    adjust: null,
    in: false,
    iterables: null,
    map: null,
    separator: '.',
    type: 'value',
    render: true,
    ancestor: 1,
    path: ['dateTo'],
    depth: 1,
    key: 'dateTo',
    root: 'dateTo',
    display: 'ref:dateTo',
});

But that's a question: How can i get resolved value of reference ? In this case i expect to get somehow (not through render of error message or through error.local and ancestors hack) value of dateTo : new Date('2023-10-25'). Why do i need this: on client im taking limit value from error details context to format it and apply as localised value. (parsing through date-fns library becomes as Invalid Date cause of limit: {} - ref object, not a date value of reference.

I have forked repo to workaround and can fix my requirement by add extra field in the date base rule 'compare' like:

        compare: {
            method: false,
            validate(value, helpers, { date }, { name, operator, args }) {

                const to = date === 'now' ? Date.now() : date.getTime();
                if (Common.compare(value.getTime(), to, operator)) {
                    return value;
                }
                //   Adding extra property 'refValue' here
                return helpers.error('date.' + name, { limit: args.date, value, refValue: to });
            },
            args: [
                {
                    name: 'date',
                    ref: true,
                    normalize: (date) => {

                        return date === 'now' ? date : internals.parse(date);
                    },
                    assert: (date) => date !== null,
                    message: 'must have a valid date format'
                }
            ]
        },

Also, i need to fix ±25 tests with such changes.

manojmula commented 10 months ago

you have added lot of details to analyse, but I am not getting the exact output you are expecting here, so you are asking to get error to be more conscience in the user perspective?