I would like to see an option to add my own predicate functions to validate input with them, for example check a specific ISO Date in this specific format "yyyy-mm-dd hh:mm:ss"
I have my own predicate function that checks that kind of input from a request, I can handle it in the old fashion but I have seen that this package is doing the things right so I want to give it a try.
Add a new method like this: .predicate(fn, msg)
Yes
Have you tried your hand at writing an extension yet? They provide the ability to write your own custom validation functions.
If you have, what are you trying to do that an extension is not providing?
I think https://github.com/hapijs/joi-date-extensions already covers that one, but if not, an extension is your best bet.
Hi guys! thank you for the feedback, I solved my doubts about how to do it.
@Marsup the problem with "joi-date-extensions" package is that it is only for Date Types Objects, in my case I cannot convert the input value to a Date object, the following is the format: "YYYY-MM-DD HH:MM:SS" allowed in the requirements, so if I convert it toISOString it will add +06:00 hours.
Anyway, these are the extensions that I made to solve it, if anybody wants to use it here it is, the idea is simple, it compares two strings, if a date is greaterThan other string in the schema it won't throw anything, otherwise it raises the errors:
/* joi_extensions.js */
export function datetime(joi) {
return {
name: 'string',
base: joi.string(),
language: {
datetime: 'must be a valid format, (e.g.): YYYY-MM-DD HH:MM:SS'
},
rules: [{
name: 'datetime',
validate(params, value, state, options) {
if (is.datetime(value)) {
return value;
} else {
return this.createError('string.datetime', { value }, state, options);
}
}
}]
}
}
export function greaterThan(joi) {
return {
name: 'string',
base: joi.string(),
language: {
greaterThan: 'must be greater than {{greaterThan}}'
},
rules: [{
name: 'greaterThan',
params: {
greaterThan: joi.func().ref().required()
},
validate(params, value, state, options) {
const prevName = params.greaterThan.root
const prev = state.parent[prevName]
const current = value
if (current < prev) {
return this.createError('string.greaterThan', { value, greaterThan: prevName }, state, options);
}
return value
}
}]
}
}
Usage:
/* index.js */
import BaseJoi from 'joi'
import { datetime, greaterThan } from './joi_extensions'
const Joi = BaseJoi.extend(datetime).extend(greaterThan);
/* ...skipped for brevity... */
const createdAt = Joi.string()
.datetime();
const updatedAt = Joi.string()
.datetime()
.greaterThan(Joi.ref('created_at'));
const deletedAt = Joi.string()
.datetime()
.greaterThan(Joi.ref('created_at'))
.greaterThan(Joi.ref('updated_at'));
const schema = Joi.object({
/* ...skipped for brevity... */
created_at: createdAt,
updated_at: updatedAt,
deleted_at: deletedAt
}).required().label('data')
const data = {
/* ...skipped for brevity... */
created_at: '2010-02-02 10:00:00',
updated_at: '2010-02-02 15:00:00',
deleted_at: '2010-02-02 04:00:00',
}
const result = schema.validate(data, { abortEarly: false })
console.log(result.error) // { ValidationError: child "deleted_at" fails because ["deleted_at" must be greater than created_at, "deleted_at" must be greater than updated_at]
By the way, I saw the package "joi-date-extensions" but I'd like to know if I could make the same things that I have achieved with my extensions, maybe only the part of compare a specific format.
It would be nice to add some extenstions like these to Joi or in "joi-date-extensions" package, what do you think?
Thanks.
Most helpful comment
Hi guys! thank you for the feedback, I solved my doubts about how to do it.
@Marsup the problem with "joi-date-extensions" package is that it is only for Date Types Objects, in my case I cannot convert the input value to a Date object, the following is the format: "YYYY-MM-DD HH:MM:SS" allowed in the requirements, so if I convert it toISOString it will add +06:00 hours.
Anyway, these are the extensions that I made to solve it, if anybody wants to use it here it is, the idea is simple, it compares two strings, if a date is greaterThan other string in the schema it won't throw anything, otherwise it raises the errors:
Usage:
By the way, I saw the package "joi-date-extensions" but I'd like to know if I could make the same things that I have achieved with my extensions, maybe only the part of compare a specific format.
It would be nice to add some extenstions like these to Joi or in "joi-date-extensions" package, what do you think?
Thanks.