Created
April 7, 2020 14:32
-
-
Save zeusdeux/125e3128c666a23ebd2632b117b6a857 to your computer and use it in GitHub Desktop.
Intense validations using yupjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const workingHoursSchema = yup | |
.object() | |
.shape( | |
{ | |
startHour: yup.number().when(["startMinute", "endHour", "endMinute"], { | |
is: (...args: string[]) => args.reduce((acc, v) => !!v || acc, false as boolean), // really typescript :| | |
then: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(23) | |
.required(), | |
otherwise: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(23) | |
}), | |
startMinute: yup.number().when(["startHour", "endHour", "endMinute"], { | |
is: (...args: string[]) => args.reduce((acc, v) => !!v || acc, false as boolean), | |
then: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(59) | |
.required(), | |
otherwise: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(59) | |
}), | |
endHour: yup.number().when(["startHour", "startMinute", "endMinute"], { | |
is: (...args: string[]) => args.reduce((acc, v) => !!v || acc, false as boolean), | |
then: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(23) | |
.required(), | |
otherwise: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(23) | |
}), | |
endMinute: yup.number().when(["startHour", "startMinute", "endHour"], { | |
is: (...args: string[]) => args.reduce((acc, v) => !!v || acc, false as boolean), | |
then: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(59) | |
.required(), | |
otherwise: yup | |
.number() | |
.integer() | |
.min(0) | |
.max(59) | |
}) | |
}, | |
[ | |
// for more info on these: https://github.com/jquense/yup/issues/176#issuecomment-369925782 | |
["startHour", "startMinute"], | |
["startHour", "endHour"], | |
["startHour", "endMinute"], | |
["startMinute", "endHour"], | |
["startMinute", "endMinute"], | |
["endHour", "endMinute"] | |
] | |
) | |
.test("validate-working-hours", "Start of working hours should be smaller than end", function(val) { | |
const workingHours = Object.values(val); | |
// when there are no more non-numeric values for working hours, validate end time > start time | |
if (workingHours.length && !workingHours.filter(v => typeof v !== "number" || Number.isNaN(v)).length) { | |
const startTime = Number.parseInt(`${val.startHour}${val.startMinute.toString().padEnd(2, "0")}`, 10); | |
const endTime = Number.parseInt(`${val.endHour}${val.endMinute.toString().padEnd(2, "0")}`, 10); | |
return startTime < endTime; | |
} | |
return true; | |
}) | |
// this transform lets the default `initialWorkingHours` value | |
// which contains strings instead of numbers | |
// (cuz react, see comment near initialWorkingHours) | |
.transform((v, ov) => { | |
if (!Object.values(ov).filter(val => val !== "").length) { | |
return {}; | |
} | |
return v; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment