UNPKG

ra-core

Version:

Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React

299 lines 10.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isRequired = exports.choices = exports.email = exports.regex = exports.number = exports.maxValue = exports.minValue = exports.maxLength = exports.minLength = exports.required = exports.composeSyncValidators = exports.composeValidators = exports.combine2Validators = exports.isEmpty = void 0; var memoize_1 = __importDefault(require("lodash/memoize")); /* @link http://stackoverflow.com/questions/46155/validate-email-address-in-javascript */ var EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // eslint-disable-line no-useless-escape var isEmpty = function (value) { return typeof value === 'undefined' || value === null || value === '' || (Array.isArray(value) && value.length === 0); }; exports.isEmpty = isEmpty; // type predicate, see https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates function isValidationErrorMessageWithArgs(error) { return error ? error.hasOwnProperty('message') : false; } var getMessage = function (message, messageArgs, value, values) { return typeof message === 'function' ? message({ args: messageArgs, value: value, values: values, }) : messageArgs ? { message: message, args: messageArgs, } : message; }; // If we define validation functions directly in JSX, it will // result in a new function at every render, and then trigger infinite re-render. // Hence, we memoize every built-in validator to prevent a "Maximum call stack" error. var memoize = function (fn) { return (0, memoize_1.default)(fn, function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return JSON.stringify(args); }); }; var isFunction = function (value) { return typeof value === 'function'; }; var combine2Validators = function (validator1, validator2) { return function (value, values, meta) { var result1 = validator1(value, values, meta); if (!result1) { return validator2(value, values, meta); } if (typeof result1 === 'string' || isValidationErrorMessageWithArgs(result1)) { return result1; } return result1.then(function (resolvedResult1) { if (!resolvedResult1) { return validator2(value, values, meta); } return resolvedResult1; }); }; }; exports.combine2Validators = combine2Validators; // Compose multiple validators into a single one for use with react-hook-form var composeValidators = function () { var validators = []; for (var _i = 0; _i < arguments.length; _i++) { validators[_i] = arguments[_i]; } var allValidators = (Array.isArray(validators[0]) ? validators[0] : validators).filter(isFunction); return allValidators.reduce(exports.combine2Validators, function () { return null; }); }; exports.composeValidators = composeValidators; // Compose multiple validators into a single one for use with react-hook-form var composeSyncValidators = function () { var validators = []; for (var _i = 0; _i < arguments.length; _i++) { validators[_i] = arguments[_i]; } return function (value, values, meta) { var allValidators = (Array.isArray(validators[0]) ? validators[0] : validators).filter(isFunction); for (var _i = 0, allValidators_1 = allValidators; _i < allValidators_1.length; _i++) { var validator = allValidators_1[_i]; var error = validator(value, values, meta); if (error) { return error; } } }; }; exports.composeSyncValidators = composeSyncValidators; /** * Required validator * * Returns an error if the value is null, undefined, or empty * * @param {string|Function} message * * @example * * const titleValidators = [required('The title is required')]; * <TextInput name="title" validate={titleValidators} /> */ exports.required = memoize(function (message) { if (message === void 0) { message = 'ra.validation.required'; } return Object.assign(function (value, values) { return (0, exports.isEmpty)(value) ? getMessage(message, undefined, value, values) : undefined; }, { isRequired: true }); }); /** * Minimum length validator * * Returns an error if the value has a length less than the parameter * * @param {integer} min * @param {string|Function} message * * @example * * const passwordValidators = [minLength(10, 'Should be at least 10 characters')]; * <TextInput type="password" name="password" validate={passwordValidators} /> */ exports.minLength = memoize(function (min, message) { if (message === void 0) { message = 'ra.validation.minLength'; } return function (value, values) { return !(0, exports.isEmpty)(value) && value.length < min ? getMessage(message, { min: min }, value, values) : undefined; }; }); /** * Maximum length validator * * Returns an error if the value has a length higher than the parameter * * @param {integer} max * @param {string|Function} message * * @example * * const nameValidators = [maxLength(10, 'Should be at most 10 characters')]; * <TextInput name="name" validate={nameValidators} /> */ exports.maxLength = memoize(function (max, message) { if (message === void 0) { message = 'ra.validation.maxLength'; } return function (value, values) { return !(0, exports.isEmpty)(value) && value.length > max ? getMessage(message, { max: max }, value, values) : undefined; }; }); /** * Minimum validator * * Returns an error if the value is less than the parameter * * @param {integer} min * @param {string|Function} message * * @example * * const fooValidators = [minValue(5, 'Should be more than 5')]; * <NumberInput name="foo" validate={fooValidators} /> */ exports.minValue = memoize(function (min, message) { if (message === void 0) { message = 'ra.validation.minValue'; } return function (value, values) { return !(0, exports.isEmpty)(value) && value < min ? getMessage(message, { min: min }, value, values) : undefined; }; }); /** * Maximum validator * * Returns an error if the value is higher than the parameter * * @param {integer} max * @param {string|Function} message * * @example * * const fooValidators = [maxValue(10, 'Should be less than 10')]; * <NumberInput name="foo" validate={fooValidators} /> */ exports.maxValue = memoize(function (max, message) { if (message === void 0) { message = 'ra.validation.maxValue'; } return function (value, values) { return !(0, exports.isEmpty)(value) && value > max ? getMessage(message, { max: max }, value, values) : undefined; }; }); /** * Number validator * * Returns an error if the value is not a number * * @param {string|Function} message * * @example * * const ageValidators = [number('Must be a number')]; * <TextInput name="age" validate={ageValidators} /> */ exports.number = memoize(function (message) { if (message === void 0) { message = 'ra.validation.number'; } return function (value, values) { return !(0, exports.isEmpty)(value) && isNaN(Number(value)) ? getMessage(message, undefined, value, values) : undefined; }; }); /** * Regular expression validator * * Returns an error if the value does not match the pattern given as parameter * * @param {RegExp} pattern * @param {string|Function} message * * @example * * const zipValidators = [regex(/^\d{5}(?:[-\s]\d{4})?$/, 'Must be a zip code')]; * <TextInput name="zip" validate={zipValidators} /> */ exports.regex = (0, memoize_1.default)(function (pattern, message) { if (message === void 0) { message = 'ra.validation.regex'; } return function (value, values) { return !(0, exports.isEmpty)(value) && typeof value === 'string' && !pattern.test(value) ? getMessage(message, { pattern: pattern }, value, values) : undefined; }; }, function (pattern, message) { return pattern.toString() + message; }); /** * Email validator * * Returns an error if the value is not a valid email * * @param {string|Function} message * * @example * * const emailValidators = [email('Must be an email')]; * <TextInput name="email" validate={emailValidators} /> */ exports.email = memoize(function (message) { if (message === void 0) { message = 'ra.validation.email'; } return (0, exports.regex)(EMAIL_REGEX, message); }); var oneOfTypeMessage = function (_a) { var args = _a.args; return ({ message: 'ra.validation.oneOf', args: args, }); }; /** * Choices validator * * Returns an error if the value is not among the list passed as parameter * * @param {array} list * @param {string|Function} message * * @example * * const genderValidators = [choices(['male', 'female'], 'Must be either Male or Female')]; * <TextInput name="gender" validate={genderValidators} /> */ exports.choices = memoize(function (list, message) { if (message === void 0) { message = oneOfTypeMessage; } return function (value, values) { return !(0, exports.isEmpty)(value) && list.indexOf(value) === -1 ? getMessage(message, { list: list }, value, values) : undefined; }; }); /** * Given a validator, returns a boolean indicating whether the field is required or not. */ var isRequired = function (validate) { if (validate && validate.isRequired) { return true; } if (Array.isArray(validate)) { return !!validate.find(function (it) { return it.isRequired; }); } return false; }; exports.isRequired = isRequired; //# sourceMappingURL=validate.js.map