easy-forms-core 1.1.3 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ type FieldType = 'text' | 'email' | 'number' | 'password' | 'textarea' | 'select
5
5
  /**
6
6
  * Tipos de validaciones soportadas
7
7
  */
8
- type ValidationType = 'required' | 'email' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'custom';
8
+ type ValidationType = 'required' | 'email' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'custom' | 'noInjection';
9
9
  /**
10
10
  * Operadores de condición
11
11
  */
@@ -50,10 +50,13 @@ interface CustomValidation extends BaseValidation {
50
50
  type: 'custom';
51
51
  validator: (value: any) => boolean | Promise<boolean>;
52
52
  }
53
+ interface NoInjectionValidation extends BaseValidation {
54
+ type: 'noInjection';
55
+ }
53
56
  /**
54
57
  * Unión de todas las validaciones
55
58
  */
56
- type Validation = RequiredValidation | EmailValidation | MinLengthValidation | MaxLengthValidation | MinValidation | MaxValidation | PatternValidation | CustomValidation;
59
+ type Validation = RequiredValidation | EmailValidation | MinLengthValidation | MaxLengthValidation | MinValidation | MaxValidation | PatternValidation | CustomValidation | NoInjectionValidation;
57
60
  /**
58
61
  * Condición individual para campos
59
62
  */
@@ -109,6 +112,8 @@ interface BaseField {
109
112
  disabled?: boolean;
110
113
  hidden?: boolean;
111
114
  description?: string;
115
+ /** Si true, no se aplica validación anti-inyección automática */
116
+ skipInjectionValidation?: boolean;
112
117
  dependencies?: FieldDependencies;
113
118
  conditionalValidations?: Array<{
114
119
  condition: FieldCondition | FieldCondition[];
@@ -302,6 +307,19 @@ interface FormColors {
302
307
  * Template names available
303
308
  */
304
309
  type TemplateName = 'login' | 'register' | 'otp' | 'contact' | 'password-reset' | 'password-change' | 'profile' | 'checkout' | 'feedback' | 'subscription' | 'booking' | 'review';
310
+ /**
311
+ * Configuración del botón de submit
312
+ */
313
+ interface SubmitButtonConfig {
314
+ /** Si false, no se muestra el botón (submit programático) */
315
+ visible?: boolean;
316
+ /** Texto del botón (default: "Enviar") */
317
+ text?: string;
318
+ /** Ancho del botón: "auto", "100%", "200px", etc. (default: "auto") */
319
+ width?: string;
320
+ /** Alineación: "left" | "center" | "right" (default: "left") */
321
+ align?: 'left' | 'center' | 'right';
322
+ }
305
323
  /**
306
324
  * Schema del formulario
307
325
  */
@@ -309,6 +327,8 @@ interface FormSchema {
309
327
  fields?: Field[];
310
328
  steps?: Step[];
311
329
  initialData?: Record<string, any>;
330
+ /** Configuración del botón de submit (también puede definirse vía atributo submit-button) */
331
+ submitButton?: SubmitButtonConfig;
312
332
  }
313
333
  /**
314
334
  * Estado del formulario
@@ -388,6 +408,8 @@ declare class EasyForm extends BrowserHTMLElement {
388
408
  protected shadow: ShadowRoot;
389
409
  private customComponents;
390
410
  private isRendering;
411
+ private attemptsLock;
412
+ private lockCountdownInterval;
391
413
  static get observedAttributes(): string[];
392
414
  constructor();
393
415
  /**
@@ -414,6 +436,30 @@ declare class EasyForm extends BrowserHTMLElement {
414
436
  * Establece los campos adicionales para extender el template
415
437
  */
416
438
  set templateExtend(value: Field[] | null);
439
+ /**
440
+ * Máximo de intentos antes de bloquear (para AttemptsLock)
441
+ */
442
+ get maxAttempts(): number | null;
443
+ set maxAttempts(value: number | null);
444
+ /**
445
+ * Duración del bloqueo en minutos (default: 5)
446
+ */
447
+ get blockDurationMinutes(): number | null;
448
+ set blockDurationMinutes(value: number | null);
449
+ /**
450
+ * Clave para persistir intentos en sessionStorage
451
+ */
452
+ get attemptsStorageKey(): string | null;
453
+ set attemptsStorageKey(value: string | null);
454
+ /**
455
+ * Configuración del botón de submit (desde atributo o schema)
456
+ */
457
+ get submitButton(): SubmitButtonConfig | null;
458
+ set submitButton(value: SubmitButtonConfig | null);
459
+ /**
460
+ * Obtiene la configuración efectiva del botón submit (atributo > schema > defaults)
461
+ */
462
+ private getSubmitButtonConfig;
417
463
  /**
418
464
  * Se llama cuando el componente se conecta al DOM
419
465
  */
@@ -422,6 +468,10 @@ declare class EasyForm extends BrowserHTMLElement {
422
468
  * Se llama cuando un atributo cambia
423
469
  */
424
470
  attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
471
+ /**
472
+ * Configura el AttemptsLock según los atributos actuales
473
+ */
474
+ private setupAttemptsLock;
425
475
  /**
426
476
  * Maneja el cambio de schema
427
477
  */
@@ -434,6 +484,11 @@ declare class EasyForm extends BrowserHTMLElement {
434
484
  * Renderiza el formulario
435
485
  */
436
486
  private render;
487
+ /**
488
+ * Actualiza el overlay de bloqueo por intentos
489
+ */
490
+ private updateLockOverlay;
491
+ private stopLockCountdown;
437
492
  /**
438
493
  * Actualiza el overlay de loading sobre el formulario
439
494
  */
@@ -516,6 +571,28 @@ declare class EasyForm extends BrowserHTMLElement {
516
571
  * Resetea el formulario a sus valores iniciales
517
572
  */
518
573
  reset(): void;
574
+ /**
575
+ * Incrementa el contador de intentos (para bloqueo por intentos fallidos).
576
+ * El consumidor debe llamar esto cuando la API/login falle.
577
+ */
578
+ incrementAttempts(): void;
579
+ /**
580
+ * Resetea el contador de intentos y desbloquea el formulario.
581
+ */
582
+ resetAttempts(): void;
583
+ /**
584
+ * Retorna true si el formulario está bloqueado por intentos.
585
+ */
586
+ isLocked(): boolean;
587
+ /**
588
+ * Retorna los milisegundos restantes del bloqueo, o 0 si no está bloqueado.
589
+ */
590
+ getRemainingBlockTimeMs(): number;
591
+ /**
592
+ * Dispara el submit del formulario programáticamente.
593
+ * Útil cuando el botón submit está oculto (visible: false).
594
+ */
595
+ requestSubmit(): void;
519
596
  /**
520
597
  * Limpia todos los valores del formulario
521
598
  */
@@ -793,6 +870,10 @@ declare class ValidationEngine {
793
870
  * Valida patrón regex
794
871
  */
795
872
  private validatePattern;
873
+ /**
874
+ * Valida que el valor no contenga patrones de inyección (SQL, XSS, etc.)
875
+ */
876
+ private validateNoInjection;
796
877
  /**
797
878
  * Valida con función personalizada
798
879
  */
@@ -942,6 +1023,68 @@ declare const PREDEFINED_MASKS: Record<PredefinedMask, CustomMask>;
942
1023
  */
943
1024
  declare function getPredefinedMask(type: PredefinedMask): CustomMask;
944
1025
 
1026
+ /**
1027
+ * Validación contra patrones de inyección (SQL, XSS, command injection, etc.)
1028
+ */
1029
+ /** Mensaje de error por defecto para validación de inyección */
1030
+ declare const INJECTION_VALIDATION_MESSAGE = "El valor contiene caracteres o patrones no permitidos";
1031
+ /**
1032
+ * Verifica si un valor string contiene patrones de inyección
1033
+ */
1034
+ declare function containsInjection(value: string): boolean;
1035
+ /**
1036
+ * Valida recursivamente un valor (string, array de strings, objetos con strings)
1037
+ * Retorna true si NO contiene inyección (válido), false si contiene (inválido)
1038
+ */
1039
+ declare function isSafeFromInjection(value: unknown): boolean;
1040
+
1041
+ /**
1042
+ * Utilidad para bloquear formularios después de N intentos fallidos
1043
+ */
1044
+ interface AttemptsLockOptions {
1045
+ maxAttempts: number;
1046
+ blockDurationMinutes?: number;
1047
+ storageKey?: string;
1048
+ onLocked?: (remainingMs: number) => void;
1049
+ onUnlocked?: () => void;
1050
+ }
1051
+ declare class AttemptsLock {
1052
+ private maxAttempts;
1053
+ private blockDurationMs;
1054
+ private storageKey?;
1055
+ private attempts;
1056
+ private lockedUntil;
1057
+ private onLocked?;
1058
+ private onUnlocked?;
1059
+ private unlockCheckInterval;
1060
+ constructor(options: AttemptsLockOptions);
1061
+ private loadFromStorage;
1062
+ private saveToStorage;
1063
+ private checkExpiration;
1064
+ private startUnlockCheck;
1065
+ private stopUnlockCheck;
1066
+ /**
1067
+ * Incrementa el contador de intentos. Si alcanza maxAttempts, bloquea.
1068
+ */
1069
+ incrementAttempts(): void;
1070
+ /**
1071
+ * Retorna true si el lock está activo (aún dentro del período de bloqueo)
1072
+ */
1073
+ isLocked(): boolean;
1074
+ /**
1075
+ * Retorna los milisegundos restantes del bloqueo, o 0 si no está bloqueado
1076
+ */
1077
+ getRemainingBlockTimeMs(): number;
1078
+ /**
1079
+ * Resetea el contador de intentos y el bloqueo
1080
+ */
1081
+ reset(): void;
1082
+ /**
1083
+ * Retorna el número actual de intentos
1084
+ */
1085
+ getAttempts(): number;
1086
+ }
1087
+
945
1088
  /**
946
1089
  * Utilidades generales
947
1090
  */
@@ -1014,4 +1157,4 @@ declare function getAvailableTemplates(): TemplateName[];
1014
1157
  */
1015
1158
  declare function extendTemplate(templateName: string, additionalFields: Field[]): FormSchema;
1016
1159
 
1017
- export { type AccordionSelectField, type ArrayField, type BaseField, type BaseValidation, type ChangeEventDetail, type CheckboxField, type ComponentRegistry, ConditionEngine, type ConditionOperator, type CustomComponent, type CustomField, type CustomMask, type CustomValidation, type DateField, EasyForm, type EmailValidation, type ErrorEventDetail, type Field, type FieldCondition, type FieldDependencies, type FieldType, type FileField, type FormColors, type FormSchema, type FormState, type FormTheme, type GroupField, type ImageGridSelectField, type MaskConfig, MaskEngine, type MaxLengthValidation, type MaxValidation, type MinLengthValidation, type MinValidation, type NumberField, type OTPField, PREDEFINED_MASKS, type PatternValidation, type PredefinedMask, type QuantityField, type RadioField, type RequiredValidation, type RowField, SchemaParser, type SelectField, StateManager, type Step, type StepChangeEventDetail, type SubmitEventDetail, type SwitchField, type TemplateName, type TextField, type TextareaField, type Validation, ValidationEngine, type ValidationType, type WizardState, attributeValue, createInput, extendTemplate, generateId, getAvailableTemplates, getColors, getCustomComponent, getNestedValue, getPredefinedMask, getTemplate, getThemeStyles, isValidEmail, parseAttributeValue, registerComponent, registerComponents, sanitizeId, setNestedValue, templates };
1160
+ export { type AccordionSelectField, type ArrayField, AttemptsLock, type AttemptsLockOptions, type BaseField, type BaseValidation, type ChangeEventDetail, type CheckboxField, type ComponentRegistry, ConditionEngine, type ConditionOperator, type CustomComponent, type CustomField, type CustomMask, type CustomValidation, type DateField, EasyForm, type EmailValidation, type ErrorEventDetail, type Field, type FieldCondition, type FieldDependencies, type FieldType, type FileField, type FormColors, type FormSchema, type FormState, type FormTheme, type GroupField, INJECTION_VALIDATION_MESSAGE, type ImageGridSelectField, type MaskConfig, MaskEngine, type MaxLengthValidation, type MaxValidation, type MinLengthValidation, type MinValidation, type NoInjectionValidation, type NumberField, type OTPField, PREDEFINED_MASKS, type PatternValidation, type PredefinedMask, type QuantityField, type RadioField, type RequiredValidation, type RowField, SchemaParser, type SelectField, StateManager, type Step, type StepChangeEventDetail, type SubmitButtonConfig, type SubmitEventDetail, type SwitchField, type TemplateName, type TextField, type TextareaField, type Validation, ValidationEngine, type ValidationType, type WizardState, attributeValue, containsInjection, createInput, extendTemplate, generateId, getAvailableTemplates, getColors, getCustomComponent, getNestedValue, getPredefinedMask, getTemplate, getThemeStyles, isSafeFromInjection, isValidEmail, parseAttributeValue, registerComponent, registerComponents, sanitizeId, setNestedValue, templates };