如何在Joi中比较自定义验证类型与自身?

时间:2018-02-02 08:16:48

标签: javascript validation datetime

我需要使用Joi验证对象,其中有两个键startend,它们是YYYY-MM-DD格式的日期字符串。

此对象需要的验证规则是:

  • 每个字段都是可选的
  • 如果提供,则每个字段应为有效日期(请参阅isValidDate
  • end应该是start之后的日期(如果同时提供了endstart

Joi没有时间提供日期比较的自定义验证,所以我需要扩展它,这是我的解决方案:

const date = Joi.extend({
    base: Joi.string(),
    name: 'string',
    language: {
        isValidDate: 'is not a valid date'
    },
    rules: [{
        name: 'isValidDate',
        validate(params, value, state, options) {
            if (!moment(value, 'YYYY-MM-DD', true).isValid()) {
                return this.createError('date.isValidDate', { v: value }, state, options);
            }

            return value;
        }
    }, {
        name: 'isDateAfter',
        params: {
            another: Joi.string().required() // This is where I'm stuck
        },
        validate(params, value, state, options) {
            if (!moment(value, 'YYYY-MM-DD', true).isAfter(params.another, 'day')) {
                return this.createError('date.isValidDate', { v: value }, state, options);
            }

            return value;
        }
    }]
});

我的架构描述如下:

Joi.object({
    start: datetime.string().isValidDate(),
    end: datetime.string().isValidDate()
        .isDateAfter(Joi.ref('start', { default: '0000-00-00' }))
}).optional()

如果我运行这个,我会收到一个错误:

ValidationError: {
  "another" [1]: "[ref:start]"
}

[1] "another" must be a string

103 |                     start: datetime.string().isValidDate(),
104 |                     end: datetime.string().isValidDate()
> 105 |                         .isDateAfter(Joi.ref('start', { default: '0000-00-00' }))
106 |                 }).optional()

如果'end'键与'start'键相同,如果它们是同一类型,我如何比较?

1 个答案:

答案 0 :(得分:0)

回答我自己的问题:

我发现有一个扩展来比较日期,来自Joi本身的维护者,称为joi-date-extensions。因此,我可以轻松地比较没有自定义验证的日期,例如:

date: Joi.object({
    start: Joi.date().format('YYYY-MM-DD'),
    end: Joi.date().format('YYYY-MM-DD').min(Joi.ref('start', { default: '0000-00-00' }))
}).optional()