UNPKG

@mub22/validity

Version:

Lightweight JavaScript validation library inspired by Laravel's rule syntax. Validate fields and forms easily with built-in rules and error messages.

165 lines (148 loc) 4.43 kB
'use strict'; function required(value) { return value !== undefined && value !== null && value !== ""; } const min = (value, arg) => { return typeof value === "string" && value.length >= parseInt(arg || "0"); }; const max = (value, arg) => { return typeof value === "string" && value.length <= parseInt(arg || "0"); }; function email(value) { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return typeof value === "string" && regex.test(value); } function numeric(value) { const regex = /^-?\d+(\.\d+)?$/; return typeof value === "string" && regex.test(value); } function alpha(value) { const regex = /^[a-zA-Z]+$/; return typeof value === "string" && regex.test(value); } const rules = { required, min, max, email, numeric, alpha, }; function capitalize(str) { if (!str) return ""; return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); } const confirm = (value, arg, data) => { let isValidFnWithData = false; let args = {}; if (data) { const { __field__ } = data; const confirmField = `confirm${capitalize(__field__)}`; if (data[__field__] === data[confirmField]) { isValidFnWithData = true; } else { args = { arg1: __field__, arg2: `confirm ${__field__}` }; } } return { isValidFnWithData, args }; }; const rulesWithData = { confirm }; const messages$1 = { required: "El campo es obligatorio", min: "Debe tener al menos :arg caracteres", max: "Debe tener como máximo :arg caracteres", email: "El campo debe ser un correo válido", numeric: "El valor debe ser numérico", alpha: "Solo se permiten letras", }; const messages = { /* Rules */ required: "This field is required", min: "Must be at least :arg characters long", max: "Must be at most :arg characters long", email: "This field must be a valid email address", numeric: "The value must be numeric", alpha: "Only letters are allowed", /* rules with data */ confirm: "The :arg1 field must match the :arg2 field", }; const locales = { es: messages$1, en: messages, }; const defaultLocale = locales.en; function validate(value, ruleString, data) { const ruleList = ruleString.split("|"); const errors = []; for (const rule of ruleList) { /* Rules */ const [ruleName, arg] = rule.split(":"); const fn = rules[ruleName]; const fnWithData = rulesWithData[ruleName]; /* Validations */ if (!fn && !fnWithData) continue; /* Response */ if (fn) { let isValidFn = fn(value, arg); if (!isValidFn) { const template = defaultLocale[ruleName] || "Validation failed"; const message = template.replace(":arg", arg || ""); errors.push(message); } } else if (fnWithData) { const { isValidFnWithData, args } = fnWithData(value, arg, data); if (!isValidFnWithData) { const template = defaultLocale[ruleName] || "Validation failed"; let message = template; for (const [key, value] of Object.entries(args || {})) { message = message.replace(`:${key}`, value); } errors.push(message); } } } return { valid: errors.length === 0, errors, }; } function validateForm(data, rules) { let isFormValid = true; const errors = {}; for (const field in rules) { const value = data[field]; /* Validations */ /* Skip internal fields */ if (/^__/.test(field)) continue; const ruleList = rules[field].split("|"); if (!ruleList.length) continue; let result; if (ruleList.some(rule => rule in rulesWithData)) { data.__field__ = field; result = validate(value, rules[field], data); } else { result = validate(value, rules[field]); } if (!result.valid) { errors[field] = result.errors; isFormValid = false; } } return { valid: isFormValid, errors }; } exports.locales = locales; exports.rules = rules; exports.validate = validate; exports.validateForm = validateForm;