UNPKG

securesharkinputs

Version:

Advanced enterprise validation library with multi-layer security protection for SecureShark

163 lines 7.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.withValidationShark = exports.useValidationShark = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const enterpriseValidator_1 = require("../services/enterpriseValidator"); // Importación opcional de react-hook-form let useFormContext = null; try { const reactHookForm = require('react-hook-form'); useFormContext = reactHookForm.useFormContext; } catch (error) { // react-hook-form no está disponible console.warn('react-hook-form no está disponible, usando modo standalone'); } const ValidationShark = ({ name, type = 'text', placeholder, label, required = false, className = '', style, onValid, onInvalid, blockForm = true, showMessages = true }) => { const [validationState, setValidationState] = (0, react_1.useState)({ isValid: true, message: '', isVisible: false }); const inputRef = (0, react_1.useRef)(null); const formContext = useFormContext(); // Obtener register y errors del contexto del formulario const register = formContext?.register; const errors = formContext?.formState?.errors; const watch = formContext?.watch; const inputId = name; // Usar el name como id const findInput = () => { return document.getElementById(inputId); }; (0, react_1.useEffect)(() => { const input = findInput(); if (!input) { console.warn('ValidationShark: No se encontró el input para validar'); return; } inputRef.current = input; console.log('ValidationShark: Input encontrado:', input.id); const validator = (0, enterpriseValidator_1.createEnterpriseValidator)({ enableExternalValidation: false, enableLogging: true, maxInputLength: 1000 }); const preventSubmit = (e) => { if (!validationState.isValid) { e.preventDefault(); e.stopPropagation(); console.log('🚨 Form submission blocked due to validation failure'); return false; } return true; }; const validateInput = async (value) => { if (!value.trim()) { setValidationState({ isValid: true, message: '', isVisible: false }); onValid?.(); return; } try { const result = await validator.validate(value); if (result.isValid) { setValidationState({ isValid: true, message: '', isVisible: false }); onValid?.(); } else { setValidationState({ isValid: false, message: `⚠️ Contenido no permitido detectado`, isVisible: true }); onInvalid?.(); } } catch (error) { console.error('Error en validación:', error); setValidationState({ isValid: false, message: '❌ Error en validación', isVisible: true }); onInvalid?.(); } }; const handleInput = (event) => { const target = event.target; validateInput(target.value); }; const handleBlur = (event) => { const target = event.target; if (target.value.trim()) { validateInput(target.value); } }; // Agregar event listeners input.addEventListener('input', handleInput); input.addEventListener('blur', handleBlur); // Bloquear formulario si está configurado if (blockForm) { const form = input.closest('form'); if (form) { form.addEventListener('submit', preventSubmit); // Marcar el formulario como bloqueado si hay validación fallida if (!validationState.isValid) { form.setAttribute('data-validation-blocked', 'true'); } else { form.removeAttribute('data-validation-blocked'); } } } return () => { input.removeEventListener('input', handleInput); input.removeEventListener('blur', handleBlur); if (blockForm) { const form = input.closest('form'); if (form) { form.removeEventListener('submit', preventSubmit); } } }; }, [inputId, validationState.isValid, blockForm, onValid, onInvalid]); // Estilos base const inputClass = `w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black placeholder-gray-600 ${className}`; const labelClass = 'block text-sm font-medium text-gray-700 mb-1'; const errorClass = 'text-red-500 text-sm mt-1'; return ((0, jsx_runtime_1.jsxs)("div", { className: "mb-4", children: [label && ((0, jsx_runtime_1.jsxs)("label", { htmlFor: inputId, className: labelClass, children: [label, " ", required && '*'] })), (0, jsx_runtime_1.jsx)("input", { id: inputId, type: type, placeholder: placeholder, ...(register ? register(name, { required: required ? `${label || name} es requerido` : false }) : {}), className: inputClass, style: style }), errors && errors[name] && ((0, jsx_runtime_1.jsx)("span", { className: errorClass, children: errors[name]?.message })), showMessages && validationState.isVisible && !validationState.isValid && ((0, jsx_runtime_1.jsx)("span", { className: errorClass, children: validationState.message }))] })); }; // HOC para componentes con validación const useValidationShark = (config) => { const [isValid, setIsValid] = (0, react_1.useState)(true); const [message, setMessage] = (0, react_1.useState)(''); const validate = async (input) => { const validator = (0, enterpriseValidator_1.createEnterpriseValidator)(config); const result = await validator.validate(input); setIsValid(result.isValid); setMessage(result.isValid ? '' : 'Contenido no permitido'); return result; }; return { isValid, message, validate }; }; exports.useValidationShark = useValidationShark; // HOC para envolver componentes const withValidationShark = (Component, config) => { return (props) => { const validationProps = (0, exports.useValidationShark)(config); return (0, jsx_runtime_1.jsx)(Component, { ...props, ...validationProps }); }; }; exports.withValidationShark = withValidationShark; exports.default = ValidationShark; //# sourceMappingURL=ValidationShark.js.map