UNPKG

@availity/yup

Version:

Additional methods for yup validation library

352 lines (345 loc) 10.8 kB
// src/index.ts import { addMethod, array, number, object, string } from "yup"; // src/isRequired.ts function isRequired(isRequired2 = true, msg) { return this.test({ name: "isRequired", exclusive: true, message: msg || "This field is required.", test(value) { if (isRequired2) { if (this.schema.type === "array") { return Array.isArray(value) ? value.length > 0 : value !== void 0; } if (this.schema.type === "string") { return value !== void 0 && value !== ""; } return value !== void 0; } return true; } }); } var isRequired_default = isRequired; // src/npi.ts var INTEGER_REGEX = /^\d*$/; function npi(msg) { return this.test({ name: "npi", exclusive: true, message: msg || "This field is invalid.", test(value) { if (!value) return true; value += ""; if (!INTEGER_REGEX.test(value) || value.length !== 10) { return false; } const firstDigit = value.charAt(0); if (["1", "2", "3", "4"].indexOf(firstDigit) < 0) { return false; } const digit = Number.parseInt(value.charAt(9), 10); value = value.substring(0, 9); value = `80840${value}`; let alternate = true; let total = 0; for (let i = value.length; i > 0; i--) { let next = Number.parseInt(value.charAt(i - 1), 10); if (alternate) { next *= 2; if (next > 9) { next = next % 10 + 1; } } total += next; alternate = !alternate; } const roundUp = Math.ceil(total / 10) * 10; const calculatedCheck = roundUp - total; return calculatedCheck === digit; } }); } var npi_default = npi; // src/phone.ts var NANP_REGEXP = /^(\+?1[\s.-]?)?\(?[2-9]\d{2}[\s).-]?\s?[2-9]\d{2}[\s.-]?\d{4}$/; function phone(msg) { return this.test({ name: "phone", exclusive: true, message: msg || "This field is invalid", test(value) { if (!value) return true; return NANP_REGEXP.test(value); } }); } var phone_default = phone; // src/date.ts import { MixedSchema } from "yup"; import moment from "moment"; var defaultFormats = ["YYYY-MM-DD", "YYYYMMDD", "MMDDYYYY", "MM-DD-YYYY", "MM/DD/YYYY"]; var MomentDateSchema = class extends MixedSchema { constructor({ format = [], typeError = "The date entered is in an invalid format." } = {}) { super({ type: "avDate" }); const formats2 = Array.isArray(format) ? format : [format]; this._validFormats = [...defaultFormats, ...formats2]; this.withMutation((schema) => { schema.typeError(typeError); schema.transform(function transform(value, originalValue) { if (value && this.isType(value)) { return value; } return moment(originalValue, schema._validFormats, true); }); }); } // Check if the date is a valid moment object or an empty string _typeCheck(value) { return moment.isMoment(value) && (value.isValid() || value._i === ""); } /** * Validate if the date is on or after a specified min */ min(min, message) { return this.test({ message: ({ min: minDate }) => message || `Date must be ${minDate} or later.`, name: "min", exclusive: true, params: { min }, test(value) { if (!min || !value || !value.isValid()) { return true; } return value.isSameOrAfter(min); } }); } /** * Validate if the date is on or before a specified max */ max(max, message) { return this.test({ message: ({ max: maxDate }) => message || `Date must be ${maxDate} or earlier.`, name: "max", exclusive: true, params: { max }, test(value) { if (!max || !value || !value.isValid()) { return true; } return value.isSameOrBefore(max); } }); } /** * Validate if the date is between a specified min or max * * For Inlcusivity: `[]` === include & `()` === exclude */ between(min, max, message, inclusivity = "()") { return this.test({ name: "between", exclusive: true, message: ({ min: minDate, max: maxDate }) => message || `Date must be between ${minDate} and ${maxDate}.`, params: { min, max }, test(value) { if (!value || !value.isValid() || !min || !max) { return true; } return value.isBetween(min, max, void 0, inclusivity); } }); } /** * Set if the field is required and add a custom message */ isRequired(isRequired2 = true, message) { return this.test({ name: "isRequired", exclusive: true, message: message || "This field is required.", test(value) { if (!isRequired2) { return true; } return value ? !!value._i : false; } }); } }; var avDate = (options) => new MomentDateSchema(options); // src/dateRange.ts import { MixedSchema as MixedSchema2, ValidationError } from "yup"; import moment2 from "moment"; import get from "lodash/get"; import merge from "lodash/merge"; var defaultOptions = { startKey: "startDate", endKey: "endDate", format: "MM/DD/YYYY" }; var formats = ["YYYY-MM-DD", "YYYYMMDD", "MMDDYYYY", "MM-DD-YYYY", "MM/DD/YYYY"]; var DateRangeSchema = class extends MixedSchema2 { constructor(options) { super({ type: "dateRange" }); const { startKey, endKey, format } = merge({}, defaultOptions, options); this.startKey = startKey; this.endKey = endKey; this.format = format; this.withMutation((schema) => { schema.transform(function mutate(value) { const start = get(value, startKey); const end = get(value, endKey); return { startDate: start ? schema.getValidDate(start) : start, endDate: end ? schema.getValidDate(end) : end, supportedFormats: [schema.format, ...formats] }; }); }); } /** * Convert the string to a moment object */ getValidDate(value) { return moment2(value, [this.format, ...formats], true); } /** * Validate based on min and max distance between dates */ distance({ min: { value: minValue, units: minUnits = "day", errorMessage: minErrorMessage } = { value: 0 }, max: { value: maxValue, units: maxUnits = "day", errorMessage: maxErrorMessage } = { value: 0 } } = {}) { return this.test({ name: "distance", exclusive: true, test({ endDate, startDate } = {}) { if (!minValue && !maxValue || !startDate || !endDate) return true; if (maxValue && endDate.isAfter(startDate.add(maxValue, maxUnits), "day")) { return new ValidationError( maxErrorMessage || `The end date must be within ${maxValue} ${maxUnits}${maxValue > 1 ? "s" : ""} of the start date`, { startDate, endDate }, this.path ); } if (minValue && endDate.isBefore(startDate.add(minValue, minUnits), "day")) { return new ValidationError( minErrorMessage || `The end date must be greater than ${minValue} ${minUnits}${minValue > 1 ? "s" : ""} of the start date`, { startDate, endDate }, this.path ); } return true; } }); } /** * Validate start date is after given min */ min(min, message) { return this.test({ message: message || (({ min: min2 }) => `Date Range must start on or after ${min2}`), name: "min", exclusive: true, params: { min }, test({ startDate, supportedFormats } = {}) { if (!startDate || !min) return true; const minDate = moment2(min, supportedFormats, true); return minDate.isValid() && minDate.isSameOrBefore(startDate); } }); } /** * Validate end date is before given max */ max(max, message) { return this.test({ message: message || (({ max: max2 }) => `Date Range must end on or before ${max2}`), name: "max", exclusive: true, params: { max }, test({ endDate, supportedFormats } = {}) { if (!endDate || !max) return true; const maxDate = moment2(max, supportedFormats, true); return maxDate.isValid() && maxDate.isSameOrAfter(endDate); } }); } /** * Validate dates are between the set min and max */ between(min, max, message) { return this.test({ message: message || (({ min: min2, max: max2 }) => `Date Range must be between ${min2} and ${max2}`), name: "between", exclusive: true, params: { min, max }, test({ startDate, endDate, supportedFormats } = {}) { if (!startDate || !endDate || !min || !max) return true; const minDate = moment2(min, supportedFormats, true); const maxDate = moment2(max, supportedFormats, true); return maxDate.isValid() && minDate.isValid() && maxDate.isSameOrAfter(endDate) && minDate.isSameOrBefore(startDate); } }); } /** * Set the field to be required or not */ isRequired(isRequired2 = true, msg) { return this.test({ name: "isRequired", exclusive: true, message: msg || "This field is required.", test({ startDate, endDate } = {}) { return !isRequired2 || !!(startDate && endDate); } }); } typeError({ message }) { return this.test({ name: "typeError", exclusive: true, test({ startDate, endDate } = {}) { const errors = []; if ((!startDate || !endDate) && (startDate || endDate)) { errors.push(message || "Start and End Date are required."); } if (startDate && endDate && !startDate.isSameOrBefore(endDate)) { errors.push("Start date must come before end date."); } if (startDate && !startDate.isValid()) { errors.push("Start Date is invalid."); } if (endDate && !endDate.isValid()) { errors.push("End Date is invalid."); } return errors.length > 0 ? new ValidationError(errors, { startDate, endDate }, this.path) : true; } }); } _typeCheck(range = {}) { const { startDate, endDate } = range; return !!startDate && !!endDate && startDate.isValid() && endDate.isValid(); } }; var dateRange = (opts) => new DateRangeSchema(opts); // src/index.ts addMethod(array, "isRequired", isRequired_default); addMethod(number, "isRequired", isRequired_default); addMethod(object, "isRequired", isRequired_default); addMethod(string, "isRequired", isRequired_default); addMethod(number, "npi", npi_default); addMethod(string, "npi", npi_default); addMethod(number, "phone", phone_default); addMethod(string, "phone", phone_default); export { avDate, dateRange };