reslib 1.0.3 → 2.0.0
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/README.md +9 -5
- package/build/auth/index.js +2 -2
- package/build/countries/index.js +2 -2
- package/build/currency/index.js +2 -2
- package/build/currency/session.js +2 -2
- package/build/exception/index.d.ts +1901 -0
- package/build/exception/index.js +5 -0
- package/build/i18n/index.d.ts +12 -4
- package/build/i18n/index.js +2 -2
- package/build/inputFormatter/index.js +2 -2
- package/build/logger/index.js +2 -2
- package/build/resources/ResourcePaginationHelper.js +1 -1
- package/build/resources/decorators/index.js +1 -1
- package/build/resources/fields/index.d.ts +5 -5
- package/build/resources/fields/index.js +1 -1
- package/build/resources/index.d.ts +1 -1
- package/build/resources/index.js +3 -3
- package/build/translations/index.d.ts +40 -4
- package/build/translations/index.js +2 -2
- package/build/translations/validator.en.d.ts +73 -4
- package/build/translations/validator.en.js +2 -2
- package/build/types/index.d.ts +21 -0
- package/build/utils/date/dateHelper.js +2 -2
- package/build/utils/date/index.js +2 -2
- package/build/utils/index.d.ts +2 -2
- package/build/utils/index.js +3 -3
- package/build/utils/interpolate.js +1 -1
- package/build/utils/isTime.js +1 -1
- package/build/utils/numbers.js +2 -2
- package/build/utils/object.js +1 -1
- package/build/validator/errors/index.d.ts +299 -0
- package/build/validator/errors/index.js +1 -0
- package/build/validator/index.d.ts +1 -0
- package/build/validator/index.js +3 -3
- package/build/validator/rules/array.js +2 -2
- package/build/validator/rules/boolean.js +2 -2
- package/build/validator/rules/date.js +2 -2
- package/build/validator/rules/default.js +2 -2
- package/build/validator/rules/enum.js +2 -2
- package/build/validator/rules/file.js +2 -2
- package/build/validator/rules/format.d.ts +182 -13
- package/build/validator/rules/format.js +3 -3
- package/build/validator/rules/index.d.ts +1 -0
- package/build/validator/rules/index.js +3 -3
- package/build/validator/rules/multiRules.d.ts +10 -10
- package/build/validator/rules/multiRules.js +2 -2
- package/build/validator/rules/numeric.d.ts +8 -8
- package/build/validator/rules/numeric.js +2 -2
- package/build/validator/rules/object.d.ts +71 -0
- package/build/validator/rules/object.js +5 -0
- package/build/validator/rules/string.d.ts +6 -6
- package/build/validator/rules/string.js +2 -2
- package/build/validator/rules/target.d.ts +8 -8
- package/build/validator/rules/target.js +2 -2
- package/build/validator/rules.types.d.ts +167 -0
- package/build/validator/rules.types.js +1 -0
- package/build/validator/types.d.ts +832 -1286
- package/build/validator/validator.d.ts +554 -867
- package/build/validator/validator.js +2 -2
- package/lib/cjs/exception.js +1 -0
- package/lib/esm/exception.mjs +2 -0
- package/package.json +254 -244
|
@@ -1,79 +1,7 @@
|
|
|
1
1
|
import { ClassConstructor, MakeOptional } from '../types';
|
|
2
2
|
import { I18n } from '../i18n';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
* # Validator Class
|
|
6
|
-
*
|
|
7
|
-
* A comprehensive validation system that provides flexible and powerful validation capabilities
|
|
8
|
-
* for TypeScript/JavaScript applications. This class supports both synchronous and asynchronous
|
|
9
|
-
* validation, decorator-based validation for classes, and a rich ecosystem of validation rules.
|
|
10
|
-
*
|
|
11
|
-
* ## Key Features
|
|
12
|
-
* - **Type-Safe Validation**: Full TypeScript support with generic types
|
|
13
|
-
* - **Decorator Support**: Class property validation using decorators
|
|
14
|
-
* - **Async Validation**: Support for asynchronous validation rules
|
|
15
|
-
* - **Internationalization**: Built-in i18n support for error messages
|
|
16
|
-
* - **Extensible**: Easy to register custom validation rules
|
|
17
|
-
* - **Rule Composition**: Combine multiple validation rules
|
|
18
|
-
*
|
|
19
|
-
* ## Basic Usage
|
|
20
|
-
* ```typescript
|
|
21
|
-
* // Register a custom validation rule
|
|
22
|
-
* Validator.registerRule('CustomRule', ({ value }) => {
|
|
23
|
-
* return value > 10 || 'Value must be greater than 10';
|
|
24
|
-
* });
|
|
25
|
-
*
|
|
26
|
-
* // Validate a single value
|
|
27
|
-
* const result = await Validator.validate({
|
|
28
|
-
* value: 15,
|
|
29
|
-
* rules: ['Required', 'CustomRule']
|
|
30
|
-
* });
|
|
31
|
-
*
|
|
32
|
-
* // Use with decorators
|
|
33
|
-
* class User {
|
|
34
|
-
* @IsRequired()
|
|
35
|
-
* @IsEmail()
|
|
36
|
-
* email: string;
|
|
37
|
-
*
|
|
38
|
-
* @IsRequired()
|
|
39
|
-
* @MinLength(3)
|
|
40
|
-
* name: string;
|
|
41
|
-
* }
|
|
42
|
-
*
|
|
43
|
-
* const userData = { email: 'user@example.com', name: 'John' };
|
|
44
|
-
* const validated = await Validator.validateTarget(User, userData);
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* ## Advanced Usage
|
|
48
|
-
* ```typescript
|
|
49
|
-
* // Complex validation with context
|
|
50
|
-
* const validationOptions = {
|
|
51
|
-
* value: userData,
|
|
52
|
-
* rules: [
|
|
53
|
-
* 'required',
|
|
54
|
-
* { minLength: [5] },
|
|
55
|
-
* async ({ value, context }) => {
|
|
56
|
-
* const exists = await checkIfUserExists(value);
|
|
57
|
-
* return !exists || 'User already exists';
|
|
58
|
-
* }
|
|
59
|
-
* ],
|
|
60
|
-
* context: { userId: 123 }
|
|
61
|
-
* };
|
|
62
|
-
*
|
|
63
|
-
* try {
|
|
64
|
-
* const result = await Validator.validate(validationOptions);
|
|
65
|
-
* console.log('Validation passed!', result);
|
|
66
|
-
* } catch (error) {
|
|
67
|
-
* console.error('Validation failed:', error.message);
|
|
68
|
-
* }
|
|
69
|
-
* ```
|
|
70
|
-
*
|
|
71
|
-
* @author Resk Framework Team
|
|
72
|
-
*
|
|
73
|
-
* @version 2.1.0
|
|
74
|
-
* @see {@link https://docs.resk.dev/validation | Validation Documentation}
|
|
75
|
-
* @public
|
|
76
|
-
*/
|
|
3
|
+
import { ValidatorBulkError, ValidatorClassError, ValidatorCreateBulkErrorPayload, ValidatorCreateClassErrorPayload, ValidatorCreateErrorPayload, ValidatorError } from './errors';
|
|
4
|
+
import { ValidatorAsyncRuleResult, ValidatorBulkOptions, ValidatorBulkResult, ValidatorClassOptions, ValidatorClassResult, ValidatorDefaultMultiRule, ValidatorMultiRuleFunction, ValidatorMultiRuleNames, ValidatorMultiRuleOptions, ValidatorNestedRuleFunctionOptions, ValidatorObjectOptions, ValidatorObjectResult, ValidatorObjectRules, ValidatorObjectSchema, ValidatorOptions, ValidatorResult, ValidatorRule, ValidatorRuleFunction, ValidatorRuleFunctionsMap, ValidatorRuleName, ValidatorRuleObject, ValidatorRuleParams, ValidatorRuleResult, ValidatorRules, ValidatorSanitizedRuleObject, ValidatorSanitizedRules, ValidatorSuccess } from './types';
|
|
77
5
|
export declare class Validator {
|
|
78
6
|
private static readonly RULES_METADATA_KEY;
|
|
79
7
|
/**
|
|
@@ -95,14 +23,14 @@ export declare class Validator {
|
|
|
95
23
|
* context?: Context;
|
|
96
24
|
* fieldName?: string;
|
|
97
25
|
* translatedPropertyName?: string;
|
|
98
|
-
* }) =>
|
|
26
|
+
* }) => ValidatorRuleResult
|
|
99
27
|
* ```
|
|
100
28
|
*
|
|
101
29
|
* ### Rule Return Values
|
|
102
30
|
* - `true` - Validation passed
|
|
103
31
|
* - `false` - Validation failed (uses default error message)
|
|
104
32
|
* - `string` - Validation failed with custom error message
|
|
105
|
-
* - `
|
|
33
|
+
* - `ValidatorAsyncRuleResult` - Async validation
|
|
106
34
|
*
|
|
107
35
|
* @example
|
|
108
36
|
* ```typescript
|
|
@@ -477,7 +405,7 @@ export declare class Validator {
|
|
|
477
405
|
* console.log(separators); // { multiple: ", ", single: ", " }
|
|
478
406
|
*
|
|
479
407
|
* // Custom error message formatting
|
|
480
|
-
* function
|
|
408
|
+
* function formatValidatorErrors(fieldName: string, errors: string[]) {
|
|
481
409
|
* const seps = Validator.getErrorMessageSeparators();
|
|
482
410
|
* if (errors.length === 0) return null;
|
|
483
411
|
* if (errors.length === 1) return `${fieldName}: ${errors[0]}`;
|
|
@@ -485,7 +413,7 @@ export declare class Validator {
|
|
|
485
413
|
* }
|
|
486
414
|
*
|
|
487
415
|
* const errors = ['Field is required', 'Must be email', 'Too short'];
|
|
488
|
-
* console.log(
|
|
416
|
+
* console.log(formatValidatorErrors('email', errors));
|
|
489
417
|
* // Output: "email: Field is required, Must be email, Too short"
|
|
490
418
|
*
|
|
491
419
|
* // Using separators in validation result processing
|
|
@@ -530,13 +458,15 @@ export declare class Validator {
|
|
|
530
458
|
*
|
|
531
459
|
* @remarks
|
|
532
460
|
* - Separators are loaded from i18n key `validator.separators` with fallback defaults
|
|
533
|
-
* - Method is used internally by `validate()` and `
|
|
461
|
+
* - Method is used internally by `validate()` and `validateClass()` for filtering error formatting
|
|
534
462
|
* - Supports both built-in i18n and custom I18n instances
|
|
535
463
|
* - Thread-safe and stateless - can be called multiple times without side effects
|
|
536
464
|
* - Default separators ensure English-compatible formatting when i18n unavailable
|
|
465
|
+
* - Note: This deals specifically with flat lists of errors (e.g. multiple failed rules on one field).
|
|
466
|
+
* Nested error structure formatting (e.g. nested objects) is handled separately via `translateNestedErrorResult`.
|
|
537
467
|
*
|
|
538
468
|
* @see {@link validate} - Uses these separators for formatting validation error messages
|
|
539
|
-
* @see {@link
|
|
469
|
+
* @see {@link validateClass} - Uses these separators for multi-field validation errors
|
|
540
470
|
* @see {@link validateMultiRule} - Uses separators for OneOf/AllOf error aggregation
|
|
541
471
|
* @see {@link validateArrayOfRule} - Uses separators for array item error formatting
|
|
542
472
|
* @see {@link I18n} - Internationalization system for custom separator configuration
|
|
@@ -549,201 +479,95 @@ export declare class Validator {
|
|
|
549
479
|
/**
|
|
550
480
|
* ## Parse and Validate Rules
|
|
551
481
|
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
* the critical preprocessing step that enables flexible rule input while ensuring type safety
|
|
555
|
-
* and consistent validation behavior across the entire validator system.
|
|
482
|
+
* The primary entry point for rule preprocessing in the validation pipeline.
|
|
483
|
+
* This method bridges the gap between user-friendly rule specification and the internal validation engine.
|
|
556
484
|
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
* and transforms them into a uniform structure that the validation pipeline can process efficiently.
|
|
561
|
-
* Invalid rules are separated out for error reporting rather than causing validation failures.
|
|
485
|
+
* It transforms rules from multiple formats (strings, objects, functions) into a uniform structure
|
|
486
|
+
* that the validation engine can execute. Crucially, it isolates invalid rules (e.g., misspelled names)
|
|
487
|
+
* so they can be reported separately without crashing the validation process.
|
|
562
488
|
*
|
|
563
489
|
* ### Supported Input Formats
|
|
564
490
|
*
|
|
565
|
-
* #### 1. Function Rules (Direct
|
|
491
|
+
* #### 1. Function Rules (Direct Logic)
|
|
492
|
+
* The most flexible format. Functions are preserved as-is.
|
|
566
493
|
* ```typescript
|
|
567
|
-
* // Synchronous
|
|
568
|
-
* const
|
|
569
|
-
*
|
|
570
|
-
* // Asynchronous function rule with context
|
|
571
|
-
* const asyncRule = async ({ value, context }) => {
|
|
572
|
-
* const result = await someAsyncCheck(value, context);
|
|
573
|
-
* return result || 'Async validation failed';
|
|
574
|
-
* };
|
|
494
|
+
* // Synchronous
|
|
495
|
+
* const isEven = ({ value }) => value % 2 === 0 || 'Must be even';
|
|
575
496
|
*
|
|
576
|
-
* //
|
|
577
|
-
* const
|
|
578
|
-
*
|
|
579
|
-
* if (value.length < 3) return 'Must be at least 3 characters';
|
|
580
|
-
* return true; // Valid
|
|
497
|
+
* // Asynchronous
|
|
498
|
+
* const isUnique = async ({ value, context }) => {
|
|
499
|
+
* return await checkDb(value) || 'Already exists';
|
|
581
500
|
* };
|
|
582
501
|
* ```
|
|
583
502
|
*
|
|
584
|
-
* #### 2. String Rules (
|
|
503
|
+
* #### 2. String Rules (Simple Names)
|
|
504
|
+
* Useful for built-in rules that don't require parameters (or where parameters are optional).
|
|
585
505
|
* ```typescript
|
|
586
|
-
*
|
|
587
|
-
* '
|
|
588
|
-
* '
|
|
589
|
-
*
|
|
506
|
+
* 'Required'
|
|
507
|
+
* 'Email'
|
|
508
|
+
* 'IsNumber'
|
|
509
|
+
* ```
|
|
590
510
|
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
* 'MaxLength' // Maximum length validation
|
|
594
|
-
* 'GreaterThan' // Numeric comparison
|
|
511
|
+
* #### 3. Object Rules (Type-Safe & Configurable)
|
|
512
|
+
* The most robust format, supporting parameters and custom messages.
|
|
595
513
|
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
*
|
|
514
|
+
* **Standard Format:**
|
|
515
|
+
* ```typescript
|
|
516
|
+
* { MinLength: [5] } // Rule with parameters
|
|
517
|
+
* { Required: [] } // Rule without parameters
|
|
600
518
|
* ```
|
|
601
519
|
*
|
|
602
|
-
*
|
|
520
|
+
* **Extended Format (with Custom Message):**
|
|
603
521
|
* ```typescript
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
* { MaxLength: [100] } // Array with one element
|
|
611
|
-
*
|
|
612
|
-
* // Rules with multiple parameters
|
|
613
|
-
* { Between: [10, 20] } // Range validation
|
|
614
|
-
* { InArray: ['admin', 'user', 'guest'] } // Multiple allowed values
|
|
615
|
-
* { CustomRule: ['param1', 'param2', 42] } // Mixed parameter types
|
|
522
|
+
* {
|
|
523
|
+
* Required: {
|
|
524
|
+
* params: [],
|
|
525
|
+
* message: "This specific field is mandatory!"
|
|
526
|
+
* }
|
|
527
|
+
* }
|
|
616
528
|
* ```
|
|
617
529
|
*
|
|
618
530
|
* ### Processing Logic
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
* 4. **Object Processing**: Object notation is converted to standardized rule objects
|
|
625
|
-
* 5. **Rule Registry Lookup**: Each parsed rule is validated against the registered rules map
|
|
626
|
-
* 6. **Error Isolation**: Invalid/unregistered rules are collected separately for reporting
|
|
627
|
-
* 7. **Type Safety**: All output maintains TypeScript type safety with proper generics
|
|
531
|
+
* 1. **Normalization**: Iterates through the input array.
|
|
532
|
+
* 2. **Function Preservation**: Function rules are added directly to `sanitizedRules`.
|
|
533
|
+
* 3. **String Parsing**: String rules are looked up in the registry.
|
|
534
|
+
* 4. **Object Parsing**: Object rules are converted to `ValidatorSanitizedRuleObject`s.
|
|
535
|
+
* 5. **Validation**: Rules that are not found in the registry are moved to `invalidRules`.
|
|
628
536
|
*
|
|
629
|
-
* ###
|
|
630
|
-
*
|
|
537
|
+
* ### Return Value Structure
|
|
538
|
+
* Returns an object `{ sanitizedRules, invalidRules }`.
|
|
631
539
|
*
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
* interface SanitizedRule {
|
|
636
|
-
* ruleName: ValidatorRuleName; // Extracted rule name
|
|
637
|
-
* params: any[]; // Parameter array (empty for no params)
|
|
638
|
-
* ruleFunction: ValidatorRuleFunction; // Actual validation function
|
|
639
|
-
* rawRuleName: string; // Original input string/object
|
|
640
|
-
* }
|
|
641
|
-
* ```
|
|
540
|
+
* - **sanitizedRules**: Array of `ValidatorSanitizedRule` (Union of functions and objects).
|
|
541
|
+
* - Functions are untouched.
|
|
542
|
+
* - Objects are normalized to `{ ruleName, params, ruleFunction, message? }`.
|
|
642
543
|
*
|
|
643
|
-
*
|
|
644
|
-
* Array of rules that couldn't be processed (maintains original input types):
|
|
645
|
-
* - Unregistered rule names
|
|
646
|
-
* - Malformed string syntax
|
|
647
|
-
* - Invalid object structures
|
|
648
|
-
* - Rules that failed registry lookup
|
|
649
|
-
*
|
|
650
|
-
* ### Error Handling Strategy
|
|
651
|
-
* - **Graceful Degradation**: Invalid rules don't break the entire validation process
|
|
652
|
-
* - **Error Reporting**: Invalid rules are collected for user feedback
|
|
653
|
-
* - **Type Preservation**: Original rule formats are maintained in invalidRules array
|
|
654
|
-
* - **Validation Continuation**: Valid rules proceed through the validation pipeline
|
|
544
|
+
* - **invalidRules**: Array of rules that failed parsing or lookup. kept in original format for error reporting.
|
|
655
545
|
*
|
|
656
546
|
* @example
|
|
657
547
|
* ```typescript
|
|
658
|
-
* // Mixed rule formats with validation
|
|
659
548
|
* const mixedRules = [
|
|
660
|
-
* 'Required',
|
|
661
|
-
* { MaxLength: [50] },
|
|
662
|
-
*
|
|
663
|
-
* '
|
|
664
|
-
*
|
|
549
|
+
* 'Required', // String rule
|
|
550
|
+
* { MaxLength: [50] }, // Object rule
|
|
551
|
+
* { MinLength: { params: [3], message: "Too short!" } }, // Custom message
|
|
552
|
+
* ({ value }) => value.includes('@'), // Function rule
|
|
553
|
+
* 'InvalidRule' // Will be invalid
|
|
665
554
|
* ];
|
|
666
555
|
*
|
|
667
556
|
* const { sanitizedRules, invalidRules } = Validator.parseAndValidateRules(mixedRules);
|
|
668
557
|
*
|
|
669
|
-
* console.log(
|
|
670
|
-
* console.log(
|
|
671
|
-
* console.log('Invalid rules:', invalidRules);
|
|
672
|
-
* // Output: ['InvalidRule', { NonExistentRule: ['param'] }]
|
|
673
|
-
*
|
|
674
|
-
* // Each sanitized rule has consistent structure
|
|
675
|
-
* sanitizedRules.forEach(rule => {
|
|
676
|
-
* console.log(`Rule: ${rule.ruleName}, Params: ${rule.params.length}, Raw: ${rule.rawRuleName}`);
|
|
677
|
-
* });
|
|
678
|
-
*
|
|
679
|
-
* // Empty or undefined input handling
|
|
680
|
-
* const { sanitizedRules: emptyRules } = Validator.parseAndValidateRules();
|
|
681
|
-
* console.log('Empty input rules:', emptyRules.length); // 0
|
|
682
|
-
*
|
|
683
|
-
* const { sanitizedRules: undefinedRules } = Validator.parseAndValidateRules(undefined);
|
|
684
|
-
* console.log('Undefined input rules:', undefinedRules.length); // 0
|
|
685
|
-
*
|
|
686
|
-
* // Complex validation scenarios
|
|
687
|
-
* const complexRules = [
|
|
688
|
-
* 'Between[1,100]', // Numeric range
|
|
689
|
-
* { InArray: ['admin', 'user'] }, // Value enumeration
|
|
690
|
-
* ({ value, context }) => { // Context-aware function
|
|
691
|
-
* if (context?.userType === 'admin') return true;
|
|
692
|
-
* return value !== 'admin' || 'Admin access required';
|
|
693
|
-
* }
|
|
694
|
-
* ];
|
|
695
|
-
*
|
|
696
|
-
* const result = Validator.parseAndValidateRules(complexRules);
|
|
697
|
-
* console.log('Complex rules processed:', result.sanitizedRules.length); // 3
|
|
698
|
-
* console.log('No invalid rules:', result.invalidRules.length); // 0
|
|
699
|
-
*
|
|
700
|
-
* // Error handling in validation pipeline
|
|
701
|
-
* const validationRules = ['Required', 'Email', 'UnknownRule'];
|
|
702
|
-
* const { sanitizedRules: validRules, invalidRules: errors } = Validator.parseAndValidateRules(validationRules);
|
|
703
|
-
*
|
|
704
|
-
* if (errors.length > 0) {
|
|
705
|
-
* console.warn('Some validation rules are invalid:', errors);
|
|
706
|
-
* // Could log to monitoring system or throw custom error
|
|
707
|
-
* }
|
|
708
|
-
*
|
|
709
|
-
* // Proceed with valid rules only
|
|
710
|
-
* const validationResult = await Validator.validate({
|
|
711
|
-
* value: 'test@example.com',
|
|
712
|
-
* rules: validRules.map(rule => rule.ruleFunction) // Extract functions for validation
|
|
713
|
-
* });
|
|
558
|
+
* console.log(sanitizedRules.length); // 4
|
|
559
|
+
* console.log(invalidRules.length); // 1
|
|
714
560
|
* ```
|
|
715
561
|
*
|
|
716
|
-
* @template Context -
|
|
717
|
-
*
|
|
718
|
-
* @
|
|
719
|
-
* Supports strings, objects, and functions in any combination
|
|
720
|
-
* Undefined or empty arrays are handled gracefully
|
|
721
|
-
*
|
|
722
|
-
* @returns Structured result object containing processed rules and errors
|
|
723
|
-
* @returns returns.sanitizedRules - Array of successfully parsed rule objects with standardized structure
|
|
724
|
-
* @returns returns.invalidRules - Array of rules that couldn't be processed (maintains original format)
|
|
562
|
+
* @template Context - Type of the validation context
|
|
563
|
+
* @param inputRules - Array of rules (or undefined)
|
|
564
|
+
* @returns Object containing valid sanitized rules and a list of invalid rules
|
|
725
565
|
*
|
|
726
|
-
* @remarks
|
|
727
|
-
* - This method is the primary entry point for rule preprocessing in the validation pipeline
|
|
728
|
-
* - Called internally by `validate()` and `validateTarget()` before rule execution
|
|
729
|
-
* - Invalid rules are isolated rather than causing validation failures for better error handling
|
|
730
|
-
* - Supports all rule formats: functions, bracket strings, and parameter objects
|
|
731
|
-
* - Maintains type safety through TypeScript generics for context propagation
|
|
732
|
-
* - Rule registry lookup ensures only registered rules are accepted
|
|
733
|
-
* - Empty input (undefined/null) returns empty arrays without errors
|
|
734
|
-
* - Processing is synchronous and performant for large rule sets
|
|
735
|
-
* - Invalid rules preserve original input format for accurate error reporting
|
|
736
|
-
*
|
|
737
|
-
* @see {@link parseStringRule} - Internal method for parsing bracket notation strings
|
|
738
|
-
* @see {@link parseObjectRule} - Internal method for processing object notation rules
|
|
739
|
-
* @see {@link validate} - Main validation method that uses this preprocessing
|
|
740
|
-
* @see {@link validateTarget} - Class-based validation that uses this preprocessing
|
|
741
|
-
* @see {@link registerRule} - Method for registering custom rules in the system
|
|
742
|
-
* @see {@link getRules} - Method to retrieve all registered rules
|
|
743
|
-
* @see {@link ValidatorSanitizedRules} - Type definition for processed rules
|
|
744
566
|
* @public
|
|
567
|
+
* @see {@link parseStringRule}
|
|
568
|
+
* @see {@link parseObjectRule}
|
|
745
569
|
*/
|
|
746
|
-
static parseAndValidateRules<Context = unknown>(inputRules?:
|
|
570
|
+
static parseAndValidateRules<Context = unknown>(inputRules?: ValidatorOptions<ValidatorDefaultArray, Context>['rules']): {
|
|
747
571
|
sanitizedRules: ValidatorSanitizedRules<Context>;
|
|
748
572
|
invalidRules: ValidatorRules<Context>[];
|
|
749
573
|
};
|
|
@@ -758,11 +582,7 @@ export declare class Validator {
|
|
|
758
582
|
* ### Current Supported String Formats
|
|
759
583
|
* - `"ruleName"` - Simple rule without parameters (e.g., `"Required"`, `"Email"`)
|
|
760
584
|
*
|
|
761
|
-
|
|
762
|
-
* The method includes commented code for bracket notation parameter parsing:
|
|
763
|
-
* - `"ruleName[param]"` - Rule with single parameter (planned)
|
|
764
|
-
* - `"ruleName[param1,param2,param3]"` - Rule with multiple parameters (planned)
|
|
765
|
-
*
|
|
585
|
+
|
|
766
586
|
* ### Processing Logic
|
|
767
587
|
* 1. **Input Validation**: Accepts any value, converts to trimmed string
|
|
768
588
|
* 2. **Rule Lookup**: Searches registered rules map using the string as rule name
|
|
@@ -771,9 +591,8 @@ export declare class Validator {
|
|
|
771
591
|
* 5. **Error Handling**: Returns null if rule is not found in registry
|
|
772
592
|
*
|
|
773
593
|
* ### Parameter Handling
|
|
774
|
-
* -
|
|
775
|
-
-
|
|
776
|
-
- Bracket notation parsing is reserved for future implementation
|
|
594
|
+
* - String rules **do not** support parameters.
|
|
595
|
+
* - Rules needing parameters must use object notation: `{ RuleName: [params] }`
|
|
777
596
|
*
|
|
778
597
|
* ### Return Value Structure
|
|
779
598
|
* When successful, returns a complete rule object:
|
|
@@ -782,7 +601,6 @@ export declare class Validator {
|
|
|
782
601
|
* ruleName: "Required", // The rule identifier
|
|
783
602
|
* params: [], // Empty array (no parsing yet)
|
|
784
603
|
* ruleFunction: Function, // The actual validation function
|
|
785
|
-
* rawRuleName: "Required" // Original input string
|
|
786
604
|
* }
|
|
787
605
|
* ```
|
|
788
606
|
*
|
|
@@ -797,10 +615,10 @@ export declare class Validator {
|
|
|
797
615
|
* ```typescript
|
|
798
616
|
* // Simple rule lookup
|
|
799
617
|
* const rule = Validator.parseStringRule("Required", registeredRules);
|
|
800
|
-
* // Returns: { ruleName: "Required", params: [], ruleFunction: fn
|
|
618
|
+
* // Returns: { ruleName: "Required", params: [], ruleFunction: fn }
|
|
801
619
|
*
|
|
802
620
|
* const emailRule = Validator.parseStringRule("Email", registeredRules);
|
|
803
|
-
* // Returns: { ruleName: "Email", params: [], ruleFunction: fn
|
|
621
|
+
* // Returns: { ruleName: "Email", params: [], ruleFunction: fn }
|
|
804
622
|
* ```
|
|
805
623
|
*
|
|
806
624
|
* #### Unknown Rule Handling
|
|
@@ -828,12 +646,7 @@ export declare class Validator {
|
|
|
828
646
|
* - **Memory Efficient**: Creates minimal rule objects
|
|
829
647
|
* - **Synchronous**: No async operations or I/O
|
|
830
648
|
*
|
|
831
|
-
|
|
832
|
-
* - Implement bracket notation parameter parsing
|
|
833
|
-
* - Support nested parameter structures
|
|
834
|
-
* - Add parameter type validation
|
|
835
|
-
* - Support quoted parameters with spaces
|
|
836
|
-
*
|
|
649
|
+
|
|
837
650
|
* @template Context - Optional validation context type for rule functions
|
|
838
651
|
*
|
|
839
652
|
* @param ruleString - The string representation of the rule to parse
|
|
@@ -845,13 +658,11 @@ export declare class Validator {
|
|
|
845
658
|
* @returns returns.ruleName - The rule identifier (same as input string)
|
|
846
659
|
* @returns returns.params - Empty array (parameter parsing not implemented)
|
|
847
660
|
* @returns returns.ruleFunction - The actual validation function from registry
|
|
848
|
-
* @returns returns.rawRuleName - The original unparsed rule string
|
|
849
661
|
*
|
|
850
662
|
* @throws {Never} This method never throws errors; returns null for invalid rules
|
|
851
663
|
*
|
|
852
664
|
* @remarks
|
|
853
665
|
* - This is an internal method used by `parseAndValidateRules`
|
|
854
|
-
* - Parameter parsing via bracket notation is planned but currently commented out
|
|
855
666
|
* - For rules with parameters, use object notation: `{ RuleName: [param1, param2] }`
|
|
856
667
|
* - Rule registry lookup ensures only registered rules are accepted
|
|
857
668
|
* - Maintains type safety through TypeScript generics for context propagation
|
|
@@ -864,314 +675,84 @@ export declare class Validator {
|
|
|
864
675
|
* @see {@link ValidatorSanitizedRuleObject} - Type definition for parsed rules
|
|
865
676
|
*/
|
|
866
677
|
static parseStringRule<Context = unknown>(ruleString: string, registeredRules: ValidatorRuleFunctionsMap<Context>): any;
|
|
678
|
+
/**
|
|
679
|
+
* ## Parse Function Rule
|
|
680
|
+
*
|
|
681
|
+
* Transforms a raw validation function into a standardized rule object.
|
|
682
|
+
* This is a critical normalization step that ensures even ad-hoc, anonymous functions
|
|
683
|
+
* conform to the system's uniform `ValidatorSanitizedRuleObject` structure.
|
|
684
|
+
*
|
|
685
|
+
* ### Logic
|
|
686
|
+
* 1. **Rule Name resolution**: Attempts to identify the rule name in this order:
|
|
687
|
+
* - Checks for a marked rule name (metadata attached via decorators)
|
|
688
|
+
* - Falls back to the function's innate `.name` property
|
|
689
|
+
* - Defaults to "anonymous" (implicit in most cases if un-named)
|
|
690
|
+
* 2. **Structure Creation**: Wraps the function in a standard object with:
|
|
691
|
+
* - `ruleFunction`: The original function itself
|
|
692
|
+
* - `ruleName`: The resolved identifier
|
|
693
|
+
* - `params`: Empty array `[]` (Function rules carry their logic internally)
|
|
694
|
+
*
|
|
695
|
+
* @template Context - Validation context type
|
|
696
|
+
* @param rule - The raw validation function to process
|
|
697
|
+
* @returns A sanitized rule object containing the function and metadata
|
|
698
|
+
*/
|
|
867
699
|
static parseFunctionRule<Context = unknown>(rule: ValidatorRuleFunction<ValidatorDefaultArray, Context>): ValidatorSanitizedRuleObject<ValidatorDefaultArray, Context>;
|
|
868
700
|
/**
|
|
869
701
|
* ## Parse Object Rule
|
|
870
702
|
*
|
|
871
703
|
* Parses object notation validation rules into standardized rule objects. This method handles
|
|
872
|
-
* rules specified as key-value pairs where the key is the rule name and the value is
|
|
873
|
-
* of parameters
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
*
|
|
704
|
+
* rules specified as key-value pairs where the key is the rule name and the value is either
|
|
705
|
+
* an array of parameters or a structured configuration object.
|
|
706
|
+
*
|
|
707
|
+
* ### Object Rule Formats
|
|
708
|
+
* 1. **Simple Format**: Key is rule name, value is parameter array
|
|
709
|
+
* ```typescript
|
|
710
|
+
* { MinLength: [5] }
|
|
711
|
+
* ```
|
|
712
|
+
* 2. **Detailed Format**: Key is rule name, value is object with `params` and `message`
|
|
713
|
+
* ```typescript
|
|
714
|
+
* {
|
|
715
|
+
* Required: {
|
|
716
|
+
* params: [],
|
|
717
|
+
* message: "This field is mandatory"
|
|
718
|
+
* }
|
|
719
|
+
* }
|
|
720
|
+
* ```
|
|
880
721
|
*
|
|
881
722
|
* ### Processing Logic
|
|
882
|
-
* 1. **Input Validation**: Ensures `rulesObject` is a valid object
|
|
883
|
-
* 2. **
|
|
884
|
-
* 3. **
|
|
885
|
-
* 4. **
|
|
886
|
-
* 5. **
|
|
887
|
-
* 6. **
|
|
888
|
-
*
|
|
889
|
-
*
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
* - Invalid rule names (not registered) are silently skipped
|
|
893
|
-
*
|
|
894
|
-
* ### Examples
|
|
895
|
-
*
|
|
896
|
-
* #### Basic Object Rules
|
|
897
|
-
* ```typescript
|
|
898
|
-
* const rulesObject = {
|
|
899
|
-
* Required: [], // No parameters
|
|
900
|
-
* MinLength: [5], // Single parameter
|
|
901
|
-
* MaxLength: [50], // Single parameter
|
|
902
|
-
* Pattern: ['^[A-Z]+$'], // String parameter
|
|
903
|
-
* };
|
|
904
|
-
*
|
|
905
|
-
* const parsedRules = Validator.parseObjectRule(rulesObject, registeredRules);
|
|
906
|
-
* // Returns array of sanitized rule objects with function references
|
|
907
|
-
* ```
|
|
908
|
-
*
|
|
909
|
-
* #### Complex Parameter Rules
|
|
910
|
-
* ```typescript
|
|
911
|
-
* const complexRules = {
|
|
912
|
-
* Range: [1, 100], // Multiple numeric parameters
|
|
913
|
-
* CustomPattern: ['^[0-9]{3}-[0-9]{3}$'], // Regex pattern
|
|
914
|
-
* Enum: [['active', 'inactive', 'pending']], // Array parameter
|
|
915
|
-
* };
|
|
916
|
-
* ```
|
|
917
|
-
*
|
|
918
|
-
* #### Mixed with String Rules
|
|
919
|
-
* ```typescript
|
|
920
|
-
* // Object rules are typically used alongside string rules
|
|
921
|
-
* const allRules = [
|
|
922
|
-
* "Required", // String rule
|
|
923
|
-
* "Email", // String rule
|
|
924
|
-
* { MinLength: [3] }, // Object rule
|
|
925
|
-
* { MaxLength: [100] }, // Object rule
|
|
926
|
-
* ];
|
|
927
|
-
*
|
|
928
|
-
* const result = Validator.parseAndValidateRules(allRules);
|
|
929
|
-
* ```
|
|
930
|
-
*
|
|
931
|
-
* #### Integration with Validation Pipeline
|
|
932
|
-
* ```typescript
|
|
933
|
-
* // Object rules are processed during rule parsing phase
|
|
934
|
-
* const inputRules = [
|
|
935
|
-
* "Required",
|
|
936
|
-
* { MinLength: [5], MaxLength: [50] },
|
|
937
|
-
* "Email"
|
|
938
|
-
* ];
|
|
939
|
-
*
|
|
940
|
-
* const { sanitizedRules } = Validator.parseAndValidateRules(inputRules);
|
|
941
|
-
* // sanitizedRules contains both string and object rule objects
|
|
942
|
-
* ```
|
|
943
|
-
*
|
|
944
|
-
* ### Error Handling
|
|
945
|
-
* - **Invalid Input**: Returns empty array if `rulesObject` is not an object
|
|
946
|
-
* - **Missing Rules**: Unregistered rule names are ignored (not added to result)
|
|
947
|
-
* - **Invalid Parameters**: Non-array parameters are ignored
|
|
948
|
-
* - **No Errors Thrown**: Method is robust and never throws exceptions
|
|
949
|
-
*
|
|
950
|
-
* ### Performance Characteristics
|
|
951
|
-
* - **Linear Time**: O(n) where n is the number of properties in rules object
|
|
952
|
-
* - **Memory Efficient**: Creates minimal objects with function references
|
|
953
|
-
* - **Registry Lookup**: Fast hash map lookup for rule function existence
|
|
954
|
-
* - **Parameter Validation**: Lightweight array type checking
|
|
955
|
-
*
|
|
956
|
-
* ### Future Enhancements
|
|
957
|
-
* - Support for non-array parameter formats (single values, objects)
|
|
958
|
-
* - Parameter type validation against rule function signatures
|
|
959
|
-
* - Rule dependency resolution and ordering
|
|
960
|
-
* - Enhanced error reporting for invalid configurations
|
|
961
|
-
*
|
|
962
|
-
* @template Context - Optional type for validation context passed to rule functions
|
|
963
|
-
*
|
|
964
|
-
* @param rulesObject - Object containing rule names as keys and parameter arrays as values
|
|
965
|
-
* @param registeredRules - Map of registered validation rule functions for lookup
|
|
966
|
-
*
|
|
967
|
-
* @returns Array of sanitized rule objects with function references and parameters
|
|
968
|
-
* - Empty array if input is invalid or no valid rules found
|
|
969
|
-
* - Each object contains: ruleName, ruleFunction, params, rawRuleName
|
|
970
|
-
*
|
|
971
|
-
* @throws {Never} This method never throws errors; invalid inputs return empty arrays
|
|
972
|
-
*
|
|
973
|
-
* @remarks
|
|
974
|
-
* - This method complements `parseStringRule` for different rule input formats
|
|
975
|
-
* - Object rules enable complex parameter passing not possible with string notation
|
|
976
|
-
* - Rules are validated against the registry to ensure only registered functions are used
|
|
977
|
-
* - Parameter arrays are passed directly to rule functions without modification
|
|
978
|
-
* - The method is part of the rule preprocessing pipeline in `parseAndValidateRules`
|
|
979
|
-
*
|
|
980
|
-
* @see {@link parseStringRule} - Handles string notation rules without parameters
|
|
981
|
-
* @see {@link parseAndValidateRules} - Main rule parsing method that uses this function
|
|
982
|
-
* @see {@link registerRule} - How rules are registered in the rule functions map
|
|
983
|
-
* @see {@link ValidatorRuleObject} - Type definition for object rule format
|
|
984
|
-
* @see {@link ValidatorSanitizedRuleObject} - Type definition for parsed rule objects
|
|
985
|
-
*
|
|
986
|
-
* @public
|
|
987
|
-
* @static
|
|
723
|
+
* 1. **Input Validation**: Ensures `rulesObject` is a valid object
|
|
724
|
+
* 2. **Sanitized Check**: Pass-through if object is already sanitized
|
|
725
|
+
* 3. **Iteration**: Loops through keys in the object
|
|
726
|
+
* 4. **Lookup**: Verifies rule existence in registry
|
|
727
|
+
* 5. **Extraction**: Handles both array and object value formats
|
|
728
|
+
* 6. **Construction**: Creates standardized rule objects with function references
|
|
729
|
+
*
|
|
730
|
+
* @param rulesObject - The rule configuration object
|
|
731
|
+
* @param registeredRules - Map of registered validation functions
|
|
732
|
+
* @returns Array of sanitized rule objects ready for execution
|
|
988
733
|
*/
|
|
989
734
|
static parseObjectRule<Context = unknown>(rulesObject: ValidatorRuleObject, registeredRules: ValidatorRuleFunctionsMap<Context>): ValidatorSanitizedRuleObject<ValidatorDefaultArray, Context>[];
|
|
990
|
-
static isSanitizedRuleObject<TRuleParams extends ValidatorDefaultArray = ValidatorDefaultArray, Context = unknown>(rule: any): rule is ValidatorSanitizedRuleObject<TRuleParams, Context>;
|
|
991
735
|
/**
|
|
992
|
-
* ##
|
|
993
|
-
*
|
|
994
|
-
* Executes comprehensive validation on a single value against an array of validation rules.
|
|
995
|
-
* This method implements the core validation pipeline with sequential rule execution,
|
|
996
|
-
* multi-rule delegation, and sophisticated error handling for complex validation scenarios.
|
|
997
|
-
*
|
|
998
|
-
* ### Validation Pipeline Overview
|
|
999
|
-
* 1. **Rule Parsing**: Validates and sanitizes input rules using `parseAndValidateRules`
|
|
1000
|
-
* 2. **Invalid Rule Handling**: Returns failure result for any invalid rules
|
|
1001
|
-
* 3. **Nullable Skip Check**: Skips validation if value meets nullable rule conditions
|
|
1002
|
-
* 4. **Sequential Execution**: Processes rules one-by-one using Promise-based `next()` function
|
|
1003
|
-
* 5. **Multi-Rule Detection**: Delegates to specialized handlers for OneOf/AllOf/ArrayOf/ValidateNested
|
|
1004
|
-
* 6. **Result Processing**: Handles boolean, string, and Error results with proper error creation
|
|
1005
|
-
* 7. **Error Aggregation**: Returns discriminated union result (success/failure)
|
|
1006
|
-
*
|
|
1007
|
-
* ### Rule Execution Strategy
|
|
1008
|
-
* - **Sequential Processing**: Rules execute one after another, not in parallel
|
|
1009
|
-
* - **Early Exit**: Validation stops on first rule failure (fail-fast behavior)
|
|
1010
|
-
* - **Rule Context**: Each rule receives i18n context, field names, and validation options
|
|
1011
|
-
* - **Parameter Extraction**: Automatically extracts rule names and parameters from various formats
|
|
1012
|
-
*
|
|
1013
|
-
* ### Multi-Rule Support
|
|
1014
|
-
* The method automatically detects and delegates to specialized validators:
|
|
1015
|
-
* - **OneOf/AllOf**: Uses symbol markers to identify logical combination rules
|
|
1016
|
-
* - **ArrayOf**: Validates arrays where each item must satisfy sub-rules
|
|
1017
|
-
* - **ValidateNested**: Delegates to class-based validation for nested objects
|
|
1018
|
-
*
|
|
1019
|
-
* ### Error Handling Architecture
|
|
1020
|
-
* - **Boolean Results**: `false` → creates validation error with i18n message
|
|
1021
|
-
* - **String Results**: Direct error messages (validated for non-null strings)
|
|
1022
|
-
* - **Error Objects**: Stringifies thrown errors and creates validation errors
|
|
1023
|
-
* - **Invalid Messages**: Falls back to i18n for null/undefined string results
|
|
1024
|
-
*
|
|
1025
|
-
* ### Nullable Rule Behavior
|
|
1026
|
-
* Skips remaining validation when nullable conditions are met:
|
|
1027
|
-
* - **Empty**: Skips if value is empty string `""`
|
|
1028
|
-
* - **Nullable**: Skips if value is `null` or `undefined`
|
|
1029
|
-
* - **Optional**: Skips if value is `undefined` only
|
|
1030
|
-
*
|
|
1031
|
-
* ### Rule Format Support
|
|
1032
|
-
* Accepts rules in multiple formats with automatic parameter extraction:
|
|
1033
|
-
* - **String Rules**: `"Email"`, `"Required"`
|
|
1034
|
-
* - **Function Rules**: Direct validator functions with optional parameters
|
|
1035
|
-
* - **Object Rules**: `{ ruleFunction, params, ruleName }` structured objects
|
|
1036
|
-
*
|
|
1037
|
-
* ### Context Propagation
|
|
1038
|
-
* Builds comprehensive context for each rule execution:
|
|
1039
|
-
* - **i18n Options**: Translation keys, field names, rule information
|
|
1040
|
-
* - **Validation Data**: Current value, rule parameters, context object
|
|
1041
|
-
* - **Field Metadata**: Property names, translated names, data references
|
|
1042
|
-
*
|
|
1043
|
-
* #### Basic Usage Examples
|
|
1044
|
-
* ```typescript
|
|
1045
|
-
* // Simple string validation
|
|
1046
|
-
* const result1 = await Validator.validate({
|
|
1047
|
-
* value: "test@example.com",
|
|
1048
|
-
* rules: ["Required", "Email"],
|
|
1049
|
-
* });
|
|
1050
|
-
* // result1.success === true
|
|
1051
|
-
*
|
|
1052
|
-
* // Numeric validation with parameters
|
|
1053
|
-
* const result2 = await Validator.validate({
|
|
1054
|
-
* value: 25,
|
|
1055
|
-
* rules: ["Required", { Min: [18] }, { Max: [65] }],
|
|
1056
|
-
* });
|
|
1057
|
-
* // result2.success === true
|
|
1058
|
-
*
|
|
1059
|
-
* // Function-based validation
|
|
1060
|
-
* const result3 = await Validator.validate({
|
|
1061
|
-
* value: "custom",
|
|
1062
|
-
* rules: [({ value }) => value.startsWith("prefix") || "Must start with prefix"],
|
|
1063
|
-
* });
|
|
1064
|
-
* // result3.success === true
|
|
1065
|
-
* ```
|
|
1066
|
-
*
|
|
1067
|
-
* #### Nullable Rule Examples
|
|
1068
|
-
* ```typescript
|
|
1069
|
-
* // Empty allows skipping other rules
|
|
1070
|
-
* const result1 = await Validator.validate({
|
|
1071
|
-
* value: "",
|
|
1072
|
-
* rules: ["Empty", "Email"],
|
|
1073
|
-
* });
|
|
1074
|
-
* // result1.success === true (skips Email check)
|
|
1075
|
-
*
|
|
1076
|
-
* // Nullable allows null/undefined
|
|
1077
|
-
* const result2 = await Validator.validate({
|
|
1078
|
-
* value: null,
|
|
1079
|
-
* rules: ["Nullable", "IsNumber"],
|
|
1080
|
-
* });
|
|
1081
|
-
* // result2.success === true (skips IsNumber check)
|
|
1082
|
-
*
|
|
1083
|
-
* // Optional allows undefined only
|
|
1084
|
-
* const result3 = await Validator.validate({
|
|
1085
|
-
* value: undefined,
|
|
1086
|
-
* rules: ["Optional"],
|
|
1087
|
-
* });
|
|
1088
|
-
* // result3.success === true (skips MinLength check)
|
|
1089
|
-
* ```
|
|
1090
|
-
*
|
|
1091
|
-
* #### Multi-Rule Examples
|
|
1092
|
-
* ```typescript
|
|
1093
|
-
* // OneOf: email OR phone required
|
|
1094
|
-
* const result1 = await Validator.validate({
|
|
1095
|
-
* value: "user@example.com",
|
|
1096
|
-
* rules: [Validator.oneOf(["Email", "PhoneNumber"])],
|
|
1097
|
-
* });
|
|
1098
|
-
* // result1.success === true
|
|
736
|
+
* ## Check if Object is Sanitized Rule
|
|
1099
737
|
*
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1102
|
-
*
|
|
1103
|
-
* rules: [Validator.arrayOf(["Email"])],
|
|
1104
|
-
* });
|
|
1105
|
-
* // result2.success === true
|
|
1106
|
-
*
|
|
1107
|
-
* // AllOf: must satisfy all conditions
|
|
1108
|
-
* const result3 = await Validator.validate({
|
|
1109
|
-
* value: "hello",
|
|
1110
|
-
* rules: [Validator.allOf(["String", { MinLength: [3] }])],
|
|
1111
|
-
* });
|
|
1112
|
-
* // result3.success === true
|
|
1113
|
-
* ```
|
|
1114
|
-
*
|
|
1115
|
-
* #### Type Guards for Result Narrowing
|
|
1116
|
-
* ```typescript
|
|
1117
|
-
* const result = await Validator.validate({
|
|
1118
|
-
* value: "test",
|
|
1119
|
-
* rules: ["Required"],
|
|
1120
|
-
* });
|
|
738
|
+
* Type guard that determines whether a given value matches the structure of a
|
|
739
|
+
* `ValidatorSanitizedRuleObject`. This ensures that the object has all the necessary
|
|
740
|
+
* properties (ruleName, ruleFunction, params) to be safely used by the validation engine.
|
|
1121
741
|
*
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1124
|
-
*
|
|
1125
|
-
*
|
|
1126
|
-
*
|
|
1127
|
-
* // TypeScript knows result.success === false
|
|
1128
|
-
* console.error("Error:", result.error.message);
|
|
1129
|
-
* }
|
|
1130
|
-
* ```
|
|
1131
|
-
*
|
|
1132
|
-
* ### Technical Implementation Details
|
|
1133
|
-
* - **Promise-Based Execution**: Uses recursive `next()` function for sequential processing
|
|
1134
|
-
* - **Symbol-Based Detection**: Identifies multi-rules using internal symbol markers
|
|
1135
|
-
* - **Context Building**: Constructs i18n and validation context for each rule
|
|
1136
|
-
* - **Error Creation**: Uses `createValidationError` for consistent error objects
|
|
1137
|
-
* - **Duration Tracking**: Measures validation execution time from start to finish
|
|
1138
|
-
*
|
|
1139
|
-
* @template Context - Optional type for the validation context object
|
|
1140
|
-
*
|
|
1141
|
-
* @param options - Validation options (MakeOptional<
|
|
1142
|
-
ValidatorValidateOptions<ValidatorDefaultArray, Context>,
|
|
1143
|
-
"i18n"
|
|
1144
|
-
>)
|
|
1145
|
-
* @param options.value - The value to validate (required)
|
|
1146
|
-
* @param options.rules - Array of validation rules to apply
|
|
1147
|
-
* @param options.context - Optional context object passed to rule functions
|
|
1148
|
-
* @param options.data - Optional data object for rule context
|
|
1149
|
-
* @param options.fieldName - Optional field identifier for error messages
|
|
1150
|
-
* @param options.propertyName - Optional property identifier for error messages
|
|
1151
|
-
* @param options.translatedPropertyName - Optional translated property name
|
|
1152
|
-
* @param options.message - Optional custom error message prefix
|
|
742
|
+
* ### Type Guard Checks
|
|
743
|
+
* 1. **Is Object**: The value must be a non-null object.
|
|
744
|
+
* 2. **Has Function**: `ruleFunction` must be a callable function.
|
|
745
|
+
* 3. **Has Name**: `ruleName` must be a string.
|
|
746
|
+
* 4. **Has Parameters**: `params` must be an array.
|
|
1153
747
|
*
|
|
1154
|
-
* @
|
|
1155
|
-
*
|
|
1156
|
-
* - Failure: object with success=false, error, failedAt, duration
|
|
748
|
+
* @template TRuleParams - Parameter types for the rule
|
|
749
|
+
* @template Context - Validation context type
|
|
1157
750
|
*
|
|
1158
|
-
* @
|
|
1159
|
-
*
|
|
1160
|
-
*
|
|
1161
|
-
* @see {@link validateTarget} - For class-based validation using decorators
|
|
1162
|
-
* @see {@link registerRule} - To register custom validation rules
|
|
1163
|
-
* @see {@link parseAndValidateRules} - Internal rule parsing and validation
|
|
1164
|
-
* @see {@link shouldSkipValidation} - Nullable rule checking logic
|
|
1165
|
-
* @see {@link validateMultiRule} - OneOf/AllOf rule implementation
|
|
1166
|
-
* @see {@link validateArrayOfRule} - ArrayOf rule implementation
|
|
1167
|
-
* @see {@link validateNestedRule} - ValidateNested rule implementation
|
|
1168
|
-
* @see {@link ValidatorValidateResult} - Result type documentation
|
|
1169
|
-
* @see {@link ValidatorValidationError} - Error details type
|
|
1170
|
-
*
|
|
1171
|
-
* @public
|
|
1172
|
-
* @async
|
|
751
|
+
* @param rule - The value to check
|
|
752
|
+
* @returns `true` if the value matches the sanitized rule structure, `false` otherwise
|
|
1173
753
|
*/
|
|
1174
|
-
static
|
|
754
|
+
static isSanitizedRuleObject<TRuleParams extends ValidatorDefaultArray = ValidatorDefaultArray, Context = unknown>(rule: any): rule is ValidatorSanitizedRuleObject<TRuleParams, Context>;
|
|
755
|
+
static validate<Context = unknown>({ rules, ...extra }: MakeOptional<ValidatorOptions<ValidatorDefaultArray, Context>, 'i18n' | 'ruleParams'>): Promise<ValidatorResult<Context>>;
|
|
1175
756
|
/**
|
|
1176
757
|
* ## Should Skip Validation
|
|
1177
758
|
*
|
|
@@ -1200,7 +781,7 @@ export declare class Validator {
|
|
|
1200
781
|
*
|
|
1201
782
|
*
|
|
1202
783
|
* @see {@link validate} - Uses this method to conditionally skip validation
|
|
1203
|
-
* @see {@link
|
|
784
|
+
* @see {@link validateClass} - Also uses this method for class-based validation
|
|
1204
785
|
* @public
|
|
1205
786
|
*/
|
|
1206
787
|
static shouldSkipValidation<Context = unknown>({ value, rules, }: {
|
|
@@ -1218,7 +799,7 @@ export declare class Validator {
|
|
|
1218
799
|
* @template Context - Optional type for validation context
|
|
1219
800
|
* @template RulesFunctions - Array of sub-rules to evaluate
|
|
1220
801
|
* @param options - Multi-rule validation options
|
|
1221
|
-
* @returns `
|
|
802
|
+
* @returns `ValidatorRuleResult` (`ValidatorAsyncRuleResult`)
|
|
1222
803
|
* @example
|
|
1223
804
|
* const res = await Validator.validateOneOfRule({
|
|
1224
805
|
* value: "user@example.com",
|
|
@@ -1228,7 +809,7 @@ export declare class Validator {
|
|
|
1228
809
|
*
|
|
1229
810
|
* @see {@link validateMultiRule}
|
|
1230
811
|
*/
|
|
1231
|
-
static validateOneOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options:
|
|
812
|
+
static validateOneOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options: ValidatorMultiRuleOptions<Context, RulesFunctions>): ValidatorRuleResult;
|
|
1232
813
|
/**
|
|
1233
814
|
* ## Validate AllOf Rule
|
|
1234
815
|
*
|
|
@@ -1240,7 +821,7 @@ export declare class Validator {
|
|
|
1240
821
|
* @template Context - Optional type for validation context
|
|
1241
822
|
* @template RulesFunctions - Array of sub-rules to evaluate
|
|
1242
823
|
* @param options - Multi-rule validation options
|
|
1243
|
-
* @returns `
|
|
824
|
+
* @returns `ValidatorRuleResult` (`ValidatorAsyncRuleResult`)
|
|
1244
825
|
* @example
|
|
1245
826
|
* const res = await Validator.validateAllOfRule({
|
|
1246
827
|
* value: "hello",
|
|
@@ -1250,7 +831,7 @@ export declare class Validator {
|
|
|
1250
831
|
*
|
|
1251
832
|
* @see {@link validateMultiRule}
|
|
1252
833
|
*/
|
|
1253
|
-
static validateAllOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options:
|
|
834
|
+
static validateAllOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options: ValidatorMultiRuleOptions<Context, RulesFunctions>): ValidatorRuleResult;
|
|
1254
835
|
/**
|
|
1255
836
|
* ## Validate ArrayOf Rule
|
|
1256
837
|
*
|
|
@@ -1260,13 +841,13 @@ export declare class Validator {
|
|
|
1260
841
|
* - Ensures `value` is an array; otherwise returns the localized `array` error.
|
|
1261
842
|
* - Applies {@link validateMultiRule} with `"AllOf"` to each item using the provided `ruleParams`.
|
|
1262
843
|
* - Aggregates failing item messages; returns `true` when all items pass.
|
|
1263
|
-
* - When any items fail, returns a localized summary using `
|
|
1264
|
-
* followed by
|
|
844
|
+
* - When any items fail, returns a localized summary using `arrayValidationFailed`
|
|
845
|
+
* with indices of failed items, followed by detailed error messages for each item.
|
|
1265
846
|
*
|
|
1266
847
|
* @template Context - Optional type for validation context
|
|
1267
848
|
* @template RulesFunctions - Array of sub-rules applied to each item
|
|
1268
849
|
* @param options - Multi-rule validation options
|
|
1269
|
-
* @returns `
|
|
850
|
+
* @returns `ValidatorRuleResult` (`ValidatorAsyncRuleResult`) - `true` if all items pass; otherwise an aggregated error string
|
|
1270
851
|
* @example
|
|
1271
852
|
* const res = await Validator.validateArrayOfRule({
|
|
1272
853
|
* value: ["user@example.com", "admin@example.com"],
|
|
@@ -1275,14 +856,14 @@ export declare class Validator {
|
|
|
1275
856
|
* // res === true when every item is a valid email
|
|
1276
857
|
*
|
|
1277
858
|
*/
|
|
1278
|
-
static validateArrayOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options:
|
|
1279
|
-
static getI18nTranslateOptions<Context = unknown>({ fieldName, propertyName, fieldLabel, translatedPropertyName, context, ...rest }: Partial<
|
|
859
|
+
static validateArrayOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options: ValidatorMultiRuleOptions<Context, RulesFunctions>): ValidatorAsyncRuleResult;
|
|
860
|
+
static getI18nTranslateOptions<Context = unknown>({ fieldName, propertyName, fieldLabel, translatedPropertyName, context, ...rest }: Partial<ValidatorOptions<ValidatorDefaultArray, Context>>): Partial<ValidatorOptions<ValidatorDefaultArray, Context>>;
|
|
1280
861
|
/**
|
|
1281
862
|
* ## Validate Nested Rule (Core Nested Validation Executor)
|
|
1282
863
|
*
|
|
1283
864
|
* Internal rule function that validates a nested object against a class constructor with
|
|
1284
865
|
* validation decorators. This method is the workhorse for nested class validation, delegating
|
|
1285
|
-
* to {@link
|
|
866
|
+
* to {@link validateClass} for the actual multi-field validation logic.
|
|
1286
867
|
*
|
|
1287
868
|
* ### Purpose
|
|
1288
869
|
* This method implements the core logic for the `ValidateNested` rule, enabling validation of
|
|
@@ -1292,7 +873,7 @@ export declare class Validator {
|
|
|
1292
873
|
*
|
|
1293
874
|
* ### Validation Flow
|
|
1294
875
|
* 1. **Parameter Extraction**: Extracts the target class constructor from `ruleParams[0]`
|
|
1295
|
-
* 2. **Validation**: Calls `
|
|
876
|
+
* 2. **Validation**: Calls `validateClass()` to validate the nested object against the class
|
|
1296
877
|
* 3. **Error Aggregation**: Collects nested validation errors with property path information
|
|
1297
878
|
* 4. **Result Formatting**: Returns either `true` (success) or error message string (failure)
|
|
1298
879
|
*
|
|
@@ -1304,7 +885,7 @@ export declare class Validator {
|
|
|
1304
885
|
* - **Successful Validation**: Returns `true` without modification
|
|
1305
886
|
*
|
|
1306
887
|
* ### Type Parameters
|
|
1307
|
-
* - `
|
|
888
|
+
* - `TClass` - Class constructor extending ClassConstructor with validation decorators
|
|
1308
889
|
* - `Context` - Optional validation context type passed through nested validations
|
|
1309
890
|
*
|
|
1310
891
|
* ### Return Values
|
|
@@ -1339,7 +920,7 @@ export declare class Validator {
|
|
|
1339
920
|
*
|
|
1340
921
|
* // When validating a User instance with an Address property,
|
|
1341
922
|
* // validateNestedRule is called to validate the address against the Address class
|
|
1342
|
-
* const result = await Validator.
|
|
923
|
+
* const result = await Validator.validateClass(User, {
|
|
1343
924
|
* data : {
|
|
1344
925
|
* name: "John",
|
|
1345
926
|
* address: { street: "123 Main St", postalCode: "12345" }
|
|
@@ -1347,16 +928,16 @@ export declare class Validator {
|
|
|
1347
928
|
* ```
|
|
1348
929
|
*
|
|
1349
930
|
* ### Key Features
|
|
1350
|
-
* - **DRY Principle**: Reuses existing `
|
|
931
|
+
* - **DRY Principle**: Reuses existing `validateClass` logic to avoid code duplication
|
|
1351
932
|
* - **Error Context**: Preserves field hierarchy information in error messages
|
|
1352
933
|
* - **i18n Integration**: Uses translation system for localized error messages
|
|
1353
934
|
* - **Context Propagation**: Passes validation context through to nested validators
|
|
1354
935
|
* - **Timing Tracking**: Maintains duration tracking across nested validations
|
|
1355
936
|
*
|
|
1356
|
-
* @template
|
|
937
|
+
* @template TClass - Class constructor type (must extend ClassConstructor)
|
|
1357
938
|
* @template Context - Optional validation context type
|
|
1358
939
|
*
|
|
1359
|
-
* @param options - Validation rule function options (ValidatorNestedRuleFunctionOptions<
|
|
940
|
+
* @param options - Validation rule function options (ValidatorNestedRuleFunctionOptions<TClass, Context>)
|
|
1360
941
|
* @param options.ruleParams - Array containing the nested class constructor at index [0]
|
|
1361
942
|
* @param options.value - The nested object value to validate (extracted to data property)
|
|
1362
943
|
* @param options.data - The nested object data to validate against the target class
|
|
@@ -1367,7 +948,7 @@ export declare class Validator {
|
|
|
1367
948
|
* @param options.startTime - Optional timestamp for duration tracking
|
|
1368
949
|
* @param options.i18n - Optional i18n instance for error message translation
|
|
1369
950
|
*
|
|
1370
|
-
* @returns {
|
|
951
|
+
* @returns {ValidatorAsyncRuleResult}
|
|
1371
952
|
* - Resolves to `true` if nested object validation succeeds
|
|
1372
953
|
* - Resolves to error message string if validation fails
|
|
1373
954
|
* - Never rejects; all errors are returned as resolution values
|
|
@@ -1377,24 +958,25 @@ export declare class Validator {
|
|
|
1377
958
|
*
|
|
1378
959
|
* @remarks
|
|
1379
960
|
* - This is an internal method primarily used by the `validateNested` factory
|
|
1380
|
-
* - Accepts ValidatorNestedRuleFunctionOptions which omits
|
|
1381
|
-
* - Delegates directly to
|
|
961
|
+
* - Accepts ValidatorNestedRuleFunctionOptions which omits validateClass's i18n parameter
|
|
962
|
+
* - Delegates directly to validateClass(target, options) maintaining all context
|
|
1382
963
|
* - Nested validation errors include property names for clear error tracing
|
|
1383
964
|
* - The method integrates seamlessly with the multi-rule validation system
|
|
1384
965
|
* - Supports recursive nesting of arbitrarily deep object structures
|
|
1385
|
-
* - Performance: Delegates to
|
|
966
|
+
* - Performance: Delegates to validateClass which validates fields in parallel
|
|
1386
967
|
* - Error aggregation uses nested field paths for hierarchical clarity
|
|
1387
968
|
*
|
|
1388
969
|
*
|
|
1389
970
|
* @see {@link validateNested} - Factory function that creates rule functions using this method
|
|
1390
|
-
* @see {@link
|
|
971
|
+
* @see {@link validateClass} - The underlying class-based validation method (accepts options with data)
|
|
1391
972
|
* @see {@link ValidateNested} - Decorator that uses this method via the factory
|
|
1392
973
|
* @see {@link ValidatorNestedRuleFunctionOptions} - Options interface for this method
|
|
1393
974
|
* @see {@link buildMultiRuleDecorator} - Decorator builder for complex multi-rule scenarios
|
|
1394
975
|
* @internal
|
|
1395
976
|
* @async
|
|
1396
977
|
*/
|
|
1397
|
-
static validateNestedRule<
|
|
978
|
+
static validateNestedRule<TClass extends ClassConstructor = ClassConstructor, Context = unknown>({ ruleParams, ...options }: ValidatorNestedRuleFunctionOptions<TClass, Context>): ValidatorAsyncRuleResult;
|
|
979
|
+
static translateNestedErrorResult(nestedErrorResult: ValidatorClassError, customI18n?: I18n): string;
|
|
1398
980
|
/**
|
|
1399
981
|
* ## Validate Multi-Rule (OneOf / AllOf)
|
|
1400
982
|
*
|
|
@@ -1421,7 +1003,7 @@ export declare class Validator {
|
|
|
1421
1003
|
* parameterized rule object, or a rule function
|
|
1422
1004
|
*
|
|
1423
1005
|
* @param ruleName - Multi-rule mode to apply: `"OneOf"` or `"AllOf"`
|
|
1424
|
-
* @param options - Validation options extending {@link
|
|
1006
|
+
* @param options - Validation options extending {@link ValidatorMultiRuleOptions}
|
|
1425
1007
|
* @param options.value - The value to validate against the sub-rules
|
|
1426
1008
|
* @param options.ruleParams - Array of sub-rules to evaluate (functions or named/object rules)
|
|
1427
1009
|
* @param options.context - Optional context passed through to each sub-rule
|
|
@@ -1432,7 +1014,7 @@ export declare class Validator {
|
|
|
1432
1014
|
* @param options.translatedPropertyName - Optional localized property name for error messages
|
|
1433
1015
|
* @param options.i18n - Optional i18n instance used to localize the error label
|
|
1434
1016
|
*
|
|
1435
|
-
* @returns
|
|
1017
|
+
* @returns ValidatorRuleResult
|
|
1436
1018
|
* - `true` when validation succeeds (any sub-rule for `OneOf`, all sub-rules for `AllOf`)
|
|
1437
1019
|
* - `string` containing aggregated error messages when validation fails
|
|
1438
1020
|
*
|
|
@@ -1461,7 +1043,7 @@ export declare class Validator {
|
|
|
1461
1043
|
* @public
|
|
1462
1044
|
* @async
|
|
1463
1045
|
*/
|
|
1464
|
-
static validateMultiRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(ruleName: ValidatorMultiRuleNames, { value, ruleParams, startTime, ...extra }:
|
|
1046
|
+
static validateMultiRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(ruleName: ValidatorMultiRuleNames, { value, ruleParams, startTime, ...extra }: ValidatorMultiRuleOptions<Context, RulesFunctions>): Promise<string | true>;
|
|
1465
1047
|
/**
|
|
1466
1048
|
* ## Create OneOf Validation Rule
|
|
1467
1049
|
*
|
|
@@ -1684,7 +1266,7 @@ export declare class Validator {
|
|
|
1684
1266
|
* ### Key Characteristics
|
|
1685
1267
|
* - **Lazy Evaluation**: Rule parameters are captured at factory creation time
|
|
1686
1268
|
* - **Composability**: Can be combined with other rules using OneOf, AllOf, ArrayOf
|
|
1687
|
-
* - **Type Safety**: Full TypeScript support with generic
|
|
1269
|
+
* - **Type Safety**: Full TypeScript support with generic TClass class type
|
|
1688
1270
|
* - **Contextual Validation**: Supports optional validation context propagation
|
|
1689
1271
|
* - **i18n Support**: Automatically uses i18n system for error messages
|
|
1690
1272
|
*
|
|
@@ -1764,23 +1346,23 @@ export declare class Validator {
|
|
|
1764
1346
|
* }
|
|
1765
1347
|
*
|
|
1766
1348
|
* // When context is provided during validation
|
|
1767
|
-
* const result = await Validator.
|
|
1349
|
+
* const result = await Validator.validateClass(User, {
|
|
1768
1350
|
* data: userData,
|
|
1769
1351
|
* context: { userId: 1, isAdmin: true }
|
|
1770
1352
|
* });
|
|
1771
1353
|
* ```
|
|
1772
1354
|
*
|
|
1773
1355
|
* ### Type Parameters
|
|
1774
|
-
* - `
|
|
1356
|
+
* - `TClass` - Class constructor type (extends ClassConstructor) that the nested object must satisfy
|
|
1775
1357
|
* - `Context` - Optional validation context type passed through nested validations
|
|
1776
1358
|
*
|
|
1777
1359
|
* ### Parameters
|
|
1778
|
-
* @param
|
|
1360
|
+
* @param TClass - The nested class constructor.
|
|
1779
1361
|
* Must be a class decorated with validation rules.
|
|
1780
1362
|
*
|
|
1781
1363
|
* ### Returns
|
|
1782
|
-
* `ValidatorRuleFunction<[target:
|
|
1783
|
-
* - Accepts validation options with nested object data (
|
|
1364
|
+
* `ValidatorRuleFunction<[target: TClass], Context>` - A rule function that:
|
|
1365
|
+
* - Accepts validation options with nested object data (ValidatorOptions)
|
|
1784
1366
|
* - Delegates to `validateNestedRule` for actual validation
|
|
1785
1367
|
* - Returns `true` on successful nested object validation
|
|
1786
1368
|
* - Returns error message string if any nested field validation fails
|
|
@@ -1791,8 +1373,8 @@ export declare class Validator {
|
|
|
1791
1373
|
* 1. Extracts the data property from validation options
|
|
1792
1374
|
* 2. Creates a shallow copy of the data using `Object.assign`
|
|
1793
1375
|
* 3. Calls `validateNestedRule` with the combined parameters
|
|
1794
|
-
* 4. Properly types the data as `
|
|
1795
|
-
* 5. Delegates to
|
|
1376
|
+
* 4. Properly types the data as `ValidatorClassInput<TClass>`
|
|
1377
|
+
* 5. Delegates to validateClass via validateNestedRule which expects options.data
|
|
1796
1378
|
*
|
|
1797
1379
|
* ### Error Message Format
|
|
1798
1380
|
* When nested validation fails, error messages include field-level details:
|
|
@@ -1802,7 +1384,7 @@ export declare class Validator {
|
|
|
1802
1384
|
*
|
|
1803
1385
|
* ### Performance Characteristics
|
|
1804
1386
|
* - **Lazy Evaluation**: Parameters are captured but not executed until rule runs
|
|
1805
|
-
* - **Efficient Nesting**: Reuses
|
|
1387
|
+
* - **Efficient Nesting**: Reuses validateClass's parallel field validation
|
|
1806
1388
|
* - **Memory Efficient**: Shallow copy of data prevents unnecessary object duplication
|
|
1807
1389
|
* - **Async Optimized**: Properly awaits nested async validation rules
|
|
1808
1390
|
*
|
|
@@ -1819,7 +1401,7 @@ export declare class Validator {
|
|
|
1819
1401
|
* });
|
|
1820
1402
|
* ```
|
|
1821
1403
|
*
|
|
1822
|
-
* @template
|
|
1404
|
+
* @template TClass - Class constructor for the nested object schema
|
|
1823
1405
|
* @template Context - Optional context type for validations
|
|
1824
1406
|
*
|
|
1825
1407
|
* @param ruleParams - Tuple `[target]` where target is the class constructor
|
|
@@ -1861,7 +1443,7 @@ export declare class Validator {
|
|
|
1861
1443
|
* }
|
|
1862
1444
|
* };
|
|
1863
1445
|
*
|
|
1864
|
-
* const result = await Validator.
|
|
1446
|
+
* const result = await Validator.validateClass(Person, {data:person});
|
|
1865
1447
|
* if (result.success) {
|
|
1866
1448
|
* console.log("Valid person with contact", result.data);
|
|
1867
1449
|
* } else {
|
|
@@ -1870,292 +1452,308 @@ export declare class Validator {
|
|
|
1870
1452
|
* ```
|
|
1871
1453
|
*
|
|
1872
1454
|
*
|
|
1873
|
-
* @see {@link validateNestedRule} - The underlying validation executor that delegates to
|
|
1455
|
+
* @see {@link validateNestedRule} - The underlying validation executor that delegates to validateClass
|
|
1874
1456
|
* @see {@link ValidateNested} - Decorator using this factory
|
|
1875
|
-
* @see {@link
|
|
1876
|
-
* @see {@link
|
|
1877
|
-
* @see {@link
|
|
1457
|
+
* @see {@link validateClass} - Multi-field class validation (signature: validateClass<T, Context>(target, options))
|
|
1458
|
+
* @see {@link ValidatorOptions} - Validation options interface for rule functions
|
|
1459
|
+
* @see {@link ValidatorClassOptions} - TClass validation options interface
|
|
1878
1460
|
* @see {@link oneOf} - Similar factory for OneOf rule creation
|
|
1879
1461
|
* @see {@link allOf} - Similar factory for AllOf rule creation
|
|
1880
1462
|
* @see {@link arrayOf} - Similar factory for ArrayOf rule creation
|
|
1881
1463
|
* @see {@link buildMultiRuleDecorator} - Decorator builder for complex rules
|
|
1882
1464
|
* @public
|
|
1883
1465
|
*/
|
|
1884
|
-
static validateNested<
|
|
1885
|
-
static
|
|
1886
|
-
|
|
1466
|
+
static validateNested<TClass extends ClassConstructor<unknown> = ClassConstructor<unknown>, Context = unknown>(target: TClass): ValidatorRuleFunction<Array<unknown>, Context>;
|
|
1467
|
+
static validateClass<TClass extends ClassConstructor = ClassConstructor, Context = unknown>(target: TClass, options: Omit<ValidatorClassOptions<TClass, Context>, 'i18n' | 'ruleParams'> & {
|
|
1468
|
+
i18n?: I18n;
|
|
1469
|
+
}): Promise<ValidatorClassResult<TClass, Context>>;
|
|
1887
1470
|
/**
|
|
1888
|
-
* ## Validate
|
|
1471
|
+
* ## Validate Object
|
|
1889
1472
|
*
|
|
1890
|
-
*
|
|
1891
|
-
* This
|
|
1473
|
+
* Validates a plain object against a set of rules without requiring a class definition.
|
|
1474
|
+
* This provides a functional alternative to class-based validation, similar to libraries like Zod.
|
|
1892
1475
|
*
|
|
1893
|
-
*
|
|
1894
|
-
*
|
|
1895
|
-
* - **Multi-FieldMeta Validation**: Validates all decorated properties in parallel
|
|
1896
|
-
* - **Error Accumulation**: Collects all field validation errors into a single result
|
|
1897
|
-
* - **FieldMeta Mapping**: Maps validated data back to original structure with proper types
|
|
1898
|
-
* - **Internationalization**: Supports translated property names and error messages
|
|
1899
|
-
* - **Custom Error Formatting**: Allows custom error message builders per field
|
|
1900
|
-
* - **Async Rules**: Supports both sync and async validation rules for each field
|
|
1901
|
-
* - **Type Safe**: Full TypeScript support with generic typing for class instances
|
|
1902
|
-
*
|
|
1903
|
-
* ### Return Type: ValidatorValidateTargetResult
|
|
1904
|
-
* Returns a discriminated union that can be narrowed:
|
|
1905
|
-
* ```typescript
|
|
1906
|
-
* type ValidatorValidateTargetResult<T> =
|
|
1907
|
-
* | ValidatorValidateTargetSuccess<T> // success: true
|
|
1908
|
-
* | ValidatorValidateTargetFailure<T> // success: false
|
|
1909
|
-
* ```
|
|
1910
|
-
*
|
|
1911
|
-
* #### Success Result (success: true)
|
|
1912
|
-
* - `success`: true
|
|
1913
|
-
* - `data`: Validated object data matching the class structure
|
|
1914
|
-
* - `value`: undefined for target validation
|
|
1915
|
-
* - `validatedAt`: ISO timestamp when validation completed
|
|
1916
|
-
* - `duration`: Milliseconds elapsed during validation
|
|
1917
|
-
* - `status`: "success"
|
|
1918
|
-
* - `context`: Optional validation context of type Context
|
|
1919
|
-
*
|
|
1920
|
-
* #### Failure Result (success: false)
|
|
1921
|
-
* - `success`: false
|
|
1922
|
-
* - `data`: undefined for target failures
|
|
1923
|
-
* - `errors`: Array of ValidatorValidationError objects, one per failed field
|
|
1924
|
-
* - `failureCount`: Number of fields that failed validation
|
|
1925
|
-
* - `message`: Summary message (e.g., "Validation failed for 3 fields")
|
|
1926
|
-
* - `failedAt`: ISO timestamp when validation failed
|
|
1927
|
-
* - `duration`: Milliseconds elapsed before failure
|
|
1928
|
-
* - `status`: "error"
|
|
1929
|
-
*
|
|
1930
|
-
* ### Supported Decorators
|
|
1931
|
-
* - `@IsRequired()` / `@IsNullable` / `@IsEmpty()` / `@IsOptional()` - Conditional rules
|
|
1932
|
-
* - `@IsEmail()` / `@IsUrl` / `@IsPhoneNumber()` - Format validators
|
|
1933
|
-
* - `@MinLength(3)` / `@MaxLength(50)` - Length validators
|
|
1934
|
-
* - `@IsNumber()` / `@IsNonNullString()` - Type validators
|
|
1935
|
-
* - `@ Length[n]` - Exact length validator
|
|
1936
|
-
* - Custom decorators created with `Validator.buildPropertyDecorator()`
|
|
1937
|
-
*
|
|
1938
|
-
* ### Nullable Rule Behavior
|
|
1939
|
-
* - **@IsEmpty()**: Skips remaining rules if value is empty string ""
|
|
1940
|
-
* - **@IsNullable**: Skips remaining rules if value is null or undefined
|
|
1941
|
-
* - **@IsOptional()**: Skips remaining rules if value is undefined only
|
|
1942
|
-
* - **Skip if Absent**: @IsOptional() fields can be omitted from data entirely
|
|
1476
|
+
* @template T - The type of data to validate
|
|
1477
|
+
* @template Context - Optional validation context type
|
|
1943
1478
|
*
|
|
1944
|
-
*
|
|
1479
|
+
* @param data - The data object to validate
|
|
1480
|
+
* @param rules - A map where keys are property names and values are rule definitions
|
|
1481
|
+
* @param options - Optional validation configuration
|
|
1482
|
+
* @returns Promise resolving to a structured validation result
|
|
1945
1483
|
*
|
|
1946
|
-
*
|
|
1484
|
+
* @example
|
|
1947
1485
|
* ```typescript
|
|
1948
|
-
*
|
|
1486
|
+
* const result = await Validator.validateObject(
|
|
1487
|
+
* { name: 'John', age: 25 },
|
|
1488
|
+
* { name: ['Required'], age: ['Required', 'Number'] }
|
|
1489
|
+
* );
|
|
1490
|
+
* ```
|
|
1491
|
+
*
|
|
1492
|
+
* @public
|
|
1493
|
+
*/
|
|
1494
|
+
static validateObject<T extends object, Context = unknown>(data: T, rules: ValidatorObjectRules<T>, options?: Omit<ValidatorObjectOptions<ClassConstructor, Context>, 'data'>): Promise<ValidatorObjectResult<T, Context>>;
|
|
1495
|
+
/**
|
|
1496
|
+
* ## Create Object Schema
|
|
1497
|
+
*
|
|
1498
|
+
* Factory method that creates a reusable object schema for validation.
|
|
1499
|
+
* This enables a Zod-like validation pattern: `const schema = Validator.object({...}); schema.validate(data);`
|
|
1500
|
+
*
|
|
1501
|
+
* @template T - The type of data to validate
|
|
1502
|
+
* @template Context - Optional validation context type
|
|
1503
|
+
*
|
|
1504
|
+
* @param rules - A map where keys are property names and values are rule definitions
|
|
1505
|
+
* @returns A `ValidatorObjectSchema` instance
|
|
1506
|
+
*
|
|
1507
|
+
* @example
|
|
1508
|
+
* ```typescript
|
|
1509
|
+
* const UserSchema = Validator.object({
|
|
1510
|
+
* email: ['Required', 'Email'],
|
|
1511
|
+
* age: ['NumberGTE[18]']
|
|
1512
|
+
* });
|
|
1513
|
+
*
|
|
1514
|
+
* const result = await UserSchema.validate({ email: 'test@example.com', age: 20 });
|
|
1515
|
+
* ```
|
|
1516
|
+
*
|
|
1517
|
+
* @public
|
|
1518
|
+
*/
|
|
1519
|
+
static object<T extends object, Context = unknown>(rules: Record<keyof T | string, ValidatorRules>): ValidatorObjectSchema<T, Context>;
|
|
1520
|
+
/**
|
|
1521
|
+
* ## Validate Bulk
|
|
1522
|
+
*
|
|
1523
|
+
* Validates an array of class instances in a single batch operation, providing detailed
|
|
1524
|
+
* feedback on which items passed or failed validation. This method is optimized for
|
|
1525
|
+
* bulk data processing scenarios like CSV imports, batch API requests, or mass data migrations.
|
|
1526
|
+
*
|
|
1527
|
+
* ### Purpose
|
|
1528
|
+
* Enables efficient validation of multiple data items against a class schema, with:
|
|
1529
|
+
* - **Parallel validation**: All items are validated concurrently for performance
|
|
1530
|
+
* - **Detailed failure tracking**: Each failed item includes its index and specific errors
|
|
1531
|
+
* - **Contextual error messages**: Different messages for partial vs complete failures
|
|
1532
|
+
* - **Type-safe results**: Discriminated union for success/failure handling
|
|
1533
|
+
*
|
|
1534
|
+
* ### Validation Behavior
|
|
1535
|
+
* - **All items pass**: Returns {@link ValidatorBulkSuccess} with validated data array
|
|
1536
|
+
* - **Some items fail**: Returns {@link ValidatorBulkError} with failure details
|
|
1537
|
+
* - **All items fail**: Returns {@link ValidatorBulkError} with specialized message
|
|
1538
|
+
* - **Invalid input**: Returns {@link ValidatorBulkError} if data is not an array
|
|
1539
|
+
*
|
|
1540
|
+
* ### Performance Characteristics
|
|
1541
|
+
* - **Concurrent validation**: Uses `Promise.all()` for parallel processing
|
|
1542
|
+
* - **Memory efficient**: Collects only failures, not all results
|
|
1543
|
+
* - **Early validation**: Input type checking before processing
|
|
1544
|
+
* - **Optimized for large datasets**: Suitable for thousands of items
|
|
1545
|
+
*
|
|
1546
|
+
* @template TClass - The class constructor type to validate against
|
|
1547
|
+
* @template Context - Optional context type for validation rules
|
|
1548
|
+
*
|
|
1549
|
+
* @param target - The class constructor containing validation decorators
|
|
1550
|
+
* @param options - Bulk validation options
|
|
1551
|
+
* @param options.data - Array of data objects to validate
|
|
1552
|
+
* @param options.startTime - Optional start timestamp (defaults to Date.now())
|
|
1553
|
+
* @param options.context - Optional context passed to validation rules
|
|
1554
|
+
* @param options.i18n - Optional i18n instance for custom translations
|
|
1555
|
+
*
|
|
1556
|
+
* @returns Promise resolving to {@link ValidatorBulkResult}
|
|
1557
|
+
*
|
|
1558
|
+
* @throws Never throws - Always returns a result object (success or error)
|
|
1559
|
+
*
|
|
1560
|
+
* @example
|
|
1561
|
+
* ```typescript
|
|
1562
|
+
* // Basic usage - User registration batch
|
|
1563
|
+
* class User {
|
|
1949
1564
|
* @IsRequired()
|
|
1950
1565
|
* @IsEmail()
|
|
1951
1566
|
* email: string;
|
|
1952
1567
|
*
|
|
1953
1568
|
* @IsRequired()
|
|
1954
1569
|
* @MinLength(3)
|
|
1955
|
-
* @MaxLength(50)
|
|
1956
1570
|
* name: string;
|
|
1957
1571
|
*
|
|
1958
|
-
* @
|
|
1959
|
-
* @
|
|
1572
|
+
* @IsOptional()
|
|
1573
|
+
* @NumberGTE(18)
|
|
1960
1574
|
* age?: number;
|
|
1961
1575
|
* }
|
|
1962
1576
|
*
|
|
1963
|
-
* const
|
|
1964
|
-
* email:
|
|
1965
|
-
* name:
|
|
1966
|
-
* age:
|
|
1967
|
-
*
|
|
1577
|
+
* const users = [
|
|
1578
|
+
* { email: 'alice@example.com', name: 'Alice', age: 25 },
|
|
1579
|
+
* { email: 'invalid-email', name: 'Bob', age: 30 },
|
|
1580
|
+
* { email: 'charlie@example.com', name: 'C', age: 17 }, // Too short, too young
|
|
1581
|
+
* ];
|
|
1582
|
+
*
|
|
1583
|
+
* const result = await Validator.validateBulk(User, { data: users });
|
|
1968
1584
|
*
|
|
1969
1585
|
* if (result.success) {
|
|
1970
|
-
* console.log(
|
|
1586
|
+
* console.log(`All ${result.data.length} users are valid`);
|
|
1587
|
+
* // Process valid users
|
|
1588
|
+
* await db.users.insertMany(result.data);
|
|
1971
1589
|
* } else {
|
|
1972
|
-
* result.
|
|
1973
|
-
*
|
|
1590
|
+
* console.error(result.message);
|
|
1591
|
+
* // "Bulk validation failed: 2 of 3 items failed"
|
|
1592
|
+
*
|
|
1593
|
+
* result.failures.forEach(failure => {
|
|
1594
|
+
* console.log(`Item ${failure.index}:`, failure.errors);
|
|
1595
|
+
* // Item 2: [{ field: 'email', message: '...' }]
|
|
1596
|
+
* // Item 3: [{ field: 'name', message: '...' }, { field: 'age', message: '...' }]
|
|
1974
1597
|
* });
|
|
1975
1598
|
* }
|
|
1976
1599
|
* ```
|
|
1977
1600
|
*
|
|
1978
|
-
*
|
|
1601
|
+
* @example
|
|
1979
1602
|
* ```typescript
|
|
1980
|
-
*
|
|
1603
|
+
* // CSV Import with context
|
|
1604
|
+
* class Product {
|
|
1981
1605
|
* @IsRequired()
|
|
1982
|
-
*
|
|
1983
|
-
* title: string;
|
|
1606
|
+
* name: string;
|
|
1984
1607
|
*
|
|
1985
|
-
* @IsRequired()
|
|
1986
1608
|
* @IsNumber()
|
|
1987
|
-
* @
|
|
1609
|
+
* @NumberGTE(0)
|
|
1988
1610
|
* price: number;
|
|
1989
1611
|
*
|
|
1990
|
-
* @
|
|
1991
|
-
* @
|
|
1992
|
-
*
|
|
1993
|
-
*
|
|
1994
|
-
*
|
|
1995
|
-
*
|
|
1996
|
-
* imageUrl?: string;
|
|
1612
|
+
* @IsRequired()
|
|
1613
|
+
* @CustomRule((value, { context }) => {
|
|
1614
|
+
* // Validate against organization's catalog
|
|
1615
|
+
* return context.catalog.includes(value) || 'Invalid category';
|
|
1616
|
+
* })
|
|
1617
|
+
* category: string;
|
|
1997
1618
|
* }
|
|
1998
1619
|
*
|
|
1999
|
-
*
|
|
2000
|
-
*
|
|
2001
|
-
*
|
|
2002
|
-
* price: 29.99,
|
|
2003
|
-
* description: "",
|
|
2004
|
-
* // imageUrl omitted (valid with @IsOptional())
|
|
2005
|
-
* }
|
|
2006
|
-
* });
|
|
2007
|
-
* ```
|
|
2008
|
-
*
|
|
2009
|
-
* #### Custom Error Message Building
|
|
2010
|
-
* ```typescript
|
|
2011
|
-
* const result = await Validator.validateTarget(UserForm, data, {
|
|
2012
|
-
* errorMessageBuilder: (translatedPropertyName, error, options) => {
|
|
2013
|
-
* // Custom format: "FieldMeta Name (validation rule): error message"
|
|
2014
|
-
* return `${translatedPropertyName} (${options.ruleName}): ${error}`;
|
|
2015
|
-
* }
|
|
2016
|
-
* });
|
|
2017
|
-
* ```
|
|
2018
|
-
*
|
|
2019
|
-
* #### Validation with Context
|
|
2020
|
-
* ```typescript
|
|
2021
|
-
* interface AuthContext {
|
|
2022
|
-
* userId: number;
|
|
2023
|
-
* isAdmin: boolean;
|
|
1620
|
+
* interface ValidationContext {
|
|
1621
|
+
* catalog: string[];
|
|
1622
|
+
* organizationId: string;
|
|
2024
1623
|
* }
|
|
2025
1624
|
*
|
|
2026
|
-
*
|
|
2027
|
-
*
|
|
2028
|
-
*
|
|
2029
|
-
*
|
|
2030
|
-
* @IsRequired()
|
|
2031
|
-
* targetId: number;
|
|
2032
|
-
* }
|
|
1625
|
+
* const csvData = [
|
|
1626
|
+
* { name: 'Widget', price: 10, category: 'Tools' },
|
|
1627
|
+
* { name: 'Gadget', price: -5, category: 'Electronics' }, // Invalid price
|
|
1628
|
+
* ];
|
|
2033
1629
|
*
|
|
2034
|
-
* const result = await Validator.
|
|
2035
|
-
*
|
|
2036
|
-
* {
|
|
2037
|
-
*
|
|
1630
|
+
* const result = await Validator.validateBulk<typeof Product, ValidationContext>(
|
|
1631
|
+
* Product,
|
|
1632
|
+
* {
|
|
1633
|
+
* data: csvData,
|
|
1634
|
+
* context: {
|
|
1635
|
+
* catalog: ['Tools', 'Electronics', 'Home'],
|
|
1636
|
+
* organizationId: 'org-123'
|
|
1637
|
+
* }
|
|
1638
|
+
* }
|
|
2038
1639
|
* );
|
|
2039
1640
|
* ```
|
|
2040
1641
|
*
|
|
2041
|
-
*
|
|
1642
|
+
* @example
|
|
2042
1643
|
* ```typescript
|
|
2043
|
-
*
|
|
1644
|
+
* // API endpoint - Batch user creation
|
|
1645
|
+
* app.post('/api/users/batch', async (req, res) => {
|
|
1646
|
+
* const result = await Validator.validateBulk(User, {
|
|
1647
|
+
* data: req.body.users
|
|
1648
|
+
* });
|
|
2044
1649
|
*
|
|
2045
|
-
*
|
|
2046
|
-
*
|
|
2047
|
-
*
|
|
2048
|
-
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2051
|
-
* console.error({
|
|
2052
|
-
* field: error.propertyName,
|
|
2053
|
-
* message: error.message,
|
|
2054
|
-
* rule: error.ruleName,
|
|
2055
|
-
* value: error.value,
|
|
1650
|
+
* if (result.success) {
|
|
1651
|
+
* const created = await db.users.insertMany(result.data);
|
|
1652
|
+
* res.json({
|
|
1653
|
+
* success: true,
|
|
1654
|
+
* count: created.length,
|
|
1655
|
+
* message: `Successfully created ${created.length} users`
|
|
2056
1656
|
* });
|
|
2057
|
-
* }
|
|
2058
|
-
*
|
|
1657
|
+
* } else {
|
|
1658
|
+
* res.status(400).json({
|
|
1659
|
+
* success: false,
|
|
1660
|
+
* message: result.message,
|
|
1661
|
+
* failureCount: result.failureCount,
|
|
1662
|
+
* totalCount: result.totalCount,
|
|
1663
|
+
* failures: result.failures.map(f => ({
|
|
1664
|
+
* index: f.index,
|
|
1665
|
+
* errors: f.errors.map(e => ({
|
|
1666
|
+
* field: e.field,
|
|
1667
|
+
* message: e.message
|
|
1668
|
+
* }))
|
|
1669
|
+
* }))
|
|
1670
|
+
* });
|
|
1671
|
+
* }
|
|
1672
|
+
* });
|
|
2059
1673
|
* ```
|
|
2060
1674
|
*
|
|
2061
|
-
*
|
|
1675
|
+
* @example
|
|
2062
1676
|
* ```typescript
|
|
2063
|
-
*
|
|
1677
|
+
* // Error handling patterns
|
|
1678
|
+
* const result = await Validator.validateBulk(User, { data: users });
|
|
2064
1679
|
*
|
|
1680
|
+
* // Pattern 1: Type narrowing with if/else
|
|
2065
1681
|
* if (result.success) {
|
|
2066
|
-
* // result
|
|
2067
|
-
*
|
|
1682
|
+
* // TypeScript knows: result is ValidatorBulkSuccess
|
|
1683
|
+
* result.data.forEach(user => processUser(user));
|
|
2068
1684
|
* } else {
|
|
2069
|
-
* // result
|
|
2070
|
-
*
|
|
1685
|
+
* // TypeScript knows: result is ValidatorBulkError
|
|
1686
|
+
* logErrors(result.failures);
|
|
2071
1687
|
* }
|
|
2072
|
-
* ```
|
|
2073
|
-
*
|
|
2074
|
-
* ### Signature
|
|
2075
|
-
* ```typescript
|
|
2076
|
-
* static async validateTarget<
|
|
2077
|
-
* Target extends ClassConstructor = ClassConstructor,
|
|
2078
|
-
* Context = unknown,
|
|
2079
|
-
* >(
|
|
2080
|
-
* target: Target,
|
|
2081
|
-
* options: Omit<ValidatorValidateTargetOptions<Target, Context>, "i18n"> & {
|
|
2082
|
-
* i18n?: I18n;
|
|
2083
|
-
* }
|
|
2084
|
-
* ): Promise<ValidatorValidateTargetResult<Context>>
|
|
2085
|
-
* ```
|
|
2086
1688
|
*
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2089
|
-
*
|
|
2090
|
-
*
|
|
1689
|
+
* // Pattern 2: Using type guards
|
|
1690
|
+
* if (Validator.isSuccess(result)) {
|
|
1691
|
+
* return result.data;
|
|
1692
|
+
* }
|
|
2091
1693
|
*
|
|
2092
|
-
*
|
|
2093
|
-
*
|
|
2094
|
-
*
|
|
2095
|
-
*
|
|
2096
|
-
*
|
|
2097
|
-
*
|
|
2098
|
-
*
|
|
2099
|
-
*
|
|
2100
|
-
*
|
|
1694
|
+
* // Pattern 3: Extracting valid items
|
|
1695
|
+
* const validIndices = new Set(
|
|
1696
|
+
* result.success ?
|
|
1697
|
+
* result.data.map((_, i) => i) :
|
|
1698
|
+
* users.map((_, i) => i).filter(i =>
|
|
1699
|
+
* !result.failures.some(f => f.index === i + 1)
|
|
1700
|
+
* )
|
|
1701
|
+
* );
|
|
1702
|
+
* ```
|
|
2101
1703
|
*
|
|
2102
|
-
*
|
|
1704
|
+
* @example
|
|
2103
1705
|
* ```typescript
|
|
2104
|
-
* //
|
|
2105
|
-
* const result = await Validator.
|
|
2106
|
-
* data: { email: \"test@example.com\", name: \"John\" },
|
|
2107
|
-
* context: { userId: 123 }
|
|
2108
|
-
* });
|
|
1706
|
+
* // Handling different failure scenarios
|
|
1707
|
+
* const result = await Validator.validateBulk(User, { data: users });
|
|
2109
1708
|
*
|
|
2110
|
-
*
|
|
2111
|
-
*
|
|
2112
|
-
*
|
|
2113
|
-
*
|
|
2114
|
-
*
|
|
1709
|
+
* if (!result.success) {
|
|
1710
|
+
* const { failureCount, totalCount } = result;
|
|
1711
|
+
*
|
|
1712
|
+
* if (failureCount === totalCount) {
|
|
1713
|
+
* // All items failed
|
|
1714
|
+
* console.error('Complete validation failure');
|
|
1715
|
+
* // Message: "All 10 items failed validation"
|
|
1716
|
+
* } else if (failureCount === 1) {
|
|
1717
|
+
* // Single item failed
|
|
1718
|
+
* console.warn('One item failed validation');
|
|
1719
|
+
* // Message: "Bulk validation failed: 1 of 10 items failed"
|
|
1720
|
+
* } else {
|
|
1721
|
+
* // Partial failure
|
|
1722
|
+
* const successRate = ((totalCount - failureCount) / totalCount * 100).toFixed(1);
|
|
1723
|
+
* console.warn(`${successRate}% success rate`);
|
|
1724
|
+
* // Message: "Bulk validation failed: 3 of 10 items failed"
|
|
1725
|
+
* }
|
|
1726
|
+
* }
|
|
2115
1727
|
* ```
|
|
2116
1728
|
*
|
|
2117
|
-
*
|
|
2118
|
-
*
|
|
2119
|
-
*
|
|
2120
|
-
*
|
|
2121
|
-
*
|
|
2122
|
-
*
|
|
2123
|
-
* @param options.errorMessageBuilder - Optional custom error message formatter function
|
|
2124
|
-
* @param options.i18n - Optional i18n instance for localization
|
|
1729
|
+
* ### Common Use Cases
|
|
1730
|
+
* - **CSV/Excel imports**: Validate uploaded file data before insertion
|
|
1731
|
+
* - **Batch API endpoints**: Validate multiple items in a single request
|
|
1732
|
+
* - **Data migrations**: Validate data before moving between systems
|
|
1733
|
+
* - **Form arrays**: Validate dynamic form fields (e.g., multiple addresses)
|
|
1734
|
+
* - **Bulk updates**: Validate changes before applying to database
|
|
2125
1735
|
*
|
|
2126
|
-
*
|
|
2127
|
-
*
|
|
2128
|
-
* -
|
|
2129
|
-
* -
|
|
1736
|
+
* ### Error Message Localization
|
|
1737
|
+
* The method uses contextual i18n keys for different scenarios:
|
|
1738
|
+
* - `validator.invalidBulkData`: When input is not an array
|
|
1739
|
+
* - `validator.bulkValidationFailed`: When some items fail (with pluralization)
|
|
1740
|
+
* - `validator.bulkValidationAllFailed`: When all items fail (with pluralization)
|
|
2130
1741
|
*
|
|
2131
|
-
*
|
|
2132
|
-
*
|
|
2133
|
-
*
|
|
2134
|
-
* -
|
|
2135
|
-
* -
|
|
2136
|
-
* - Property names are translated using i18n if available (via i18n.translateTarget method)
|
|
2137
|
-
* - Errors include field-specific information: propertyName, translatedPropertyName, message, ruleName, value
|
|
2138
|
-
* - Custom errorMessageBuilder allows field-level error message customization
|
|
2139
|
-
* - Context is propagated through to all field validation rules
|
|
2140
|
-
* - Supports nested validation through @ValidateNested rule and validateNested factory
|
|
2141
|
-
* - Error messages use default format: \"[translatedPropertyName] : error\" unless custom builder provided
|
|
2142
|
-
* - Integrates with the multi-rule system (OneOf, AllOf, ArrayOf) for field validation
|
|
2143
|
-
*
|
|
2144
|
-
*
|
|
2145
|
-
* @see {@link validate} - For single-value validation without class schema
|
|
2146
|
-
* @see {@link validateNestedRule} - Internal rule handler that delegates to validateTarget
|
|
2147
|
-
* @see {@link validateNested} - Factory creating nested validation rule functions
|
|
2148
|
-
* @see {@link buildPropertyDecorator} - To create custom validation decorators
|
|
2149
|
-
* @see {@link registerRule} - To register custom validation rules\n * @see {@link ValidatorValidateTargetResult} - Result type documentation
|
|
2150
|
-
* @see {@link ValidatorValidationError} - Error details type
|
|
2151
|
-
* @see {@link ValidatorValidateTargetOptions} - Full options interface
|
|
1742
|
+
* ### Performance Tips
|
|
1743
|
+
* - **Large datasets**: Consider chunking (e.g., 1000 items per batch)
|
|
1744
|
+
* - **Complex validations**: Use context to cache expensive lookups
|
|
1745
|
+
* - **Memory constraints**: Process results incrementally, don't accumulate all
|
|
1746
|
+
* - **Progress tracking**: Wrap in a progress indicator for user feedback
|
|
2152
1747
|
*
|
|
1748
|
+
* @see {@link ValidatorBulkResult} - Return type documentation
|
|
1749
|
+
* @see {@link ValidatorBulkSuccess} - Success result structure
|
|
1750
|
+
* @see {@link ValidatorBulkError} - Error result structure
|
|
1751
|
+
* @see {@link ValidatorBulkOptions} - Options interface
|
|
1752
|
+
* @see {@link validateClass} - Single-item validation method
|
|
2153
1753
|
* @public
|
|
2154
|
-
* @
|
|
1754
|
+
* @since 1.2.0
|
|
2155
1755
|
*/
|
|
2156
|
-
static
|
|
2157
|
-
i18n?: I18n;
|
|
2158
|
-
}): Promise<ValidatorValidateTargetResult<Context>>;
|
|
1756
|
+
static validateBulk<TClass extends ClassConstructor = ClassConstructor, Context = unknown>(target: TClass, { data, startTime, ...options }: ValidatorBulkOptions<TClass, Context>): Promise<ValidatorBulkResult<TClass, Context>>;
|
|
2159
1757
|
/**
|
|
2160
1758
|
* ## Extract Validation Rules from Class
|
|
2161
1759
|
*
|
|
@@ -2192,7 +1790,7 @@ export declare class Validator {
|
|
|
2192
1790
|
* }
|
|
2193
1791
|
*
|
|
2194
1792
|
* // Extract validation rules
|
|
2195
|
-
* const rules = Validator.
|
|
1793
|
+
* const rules = Validator.getClassRules(User);
|
|
2196
1794
|
* console.log(rules);
|
|
2197
1795
|
* // Output:
|
|
2198
1796
|
* // {
|
|
@@ -2207,7 +1805,7 @@ export declare class Validator {
|
|
|
2207
1805
|
*
|
|
2208
1806
|
* // Programmatic rule inspection
|
|
2209
1807
|
* function analyzeClass(targetClass: any) {
|
|
2210
|
-
* const rules = Validator.
|
|
1808
|
+
* const rules = Validator.getClassRules(targetClass);
|
|
2211
1809
|
* const analysis = {
|
|
2212
1810
|
* totalProperties: Object.keys(rules).length,
|
|
2213
1811
|
* requiredProperties: [],
|
|
@@ -2233,17 +1831,17 @@ export declare class Validator {
|
|
|
2233
1831
|
* @returns Record mapping property names to their validation rules
|
|
2234
1832
|
*
|
|
2235
1833
|
*
|
|
2236
|
-
* @see {@link
|
|
1834
|
+
* @see {@link validateClass} - Uses this method to get validation rules
|
|
2237
1835
|
* @see {@link buildPropertyDecorator} - How rules are attached to properties
|
|
2238
1836
|
* @public
|
|
2239
1837
|
*/
|
|
2240
|
-
static
|
|
1838
|
+
static getClassRules<T = unknown>(target: T): Record<string, ValidatorRule[]>;
|
|
2241
1839
|
/**
|
|
2242
|
-
* ## Get
|
|
1840
|
+
* ## Get TClass Validation Options
|
|
2243
1841
|
*
|
|
2244
1842
|
* Retrieves validation options that have been configured for a specific class
|
|
2245
|
-
* through the `@
|
|
2246
|
-
* validation behaves when `
|
|
1843
|
+
* through the `@ValidationClassOptions` decorator. These options control how
|
|
1844
|
+
* validation behaves when `validateClass` is called on the class.
|
|
2247
1845
|
*
|
|
2248
1846
|
* ### Configuration Options
|
|
2249
1847
|
* Options can include custom error message builders, validation contexts,
|
|
@@ -2253,7 +1851,7 @@ export declare class Validator {
|
|
|
2253
1851
|
* @example
|
|
2254
1852
|
* ```typescript
|
|
2255
1853
|
* // Class with custom validation options
|
|
2256
|
-
* @
|
|
1854
|
+
* @ValidationClassOptions({
|
|
2257
1855
|
* errorMessageBuilder: (translatedName, error) => {
|
|
2258
1856
|
* return `❌ ${translatedName}: ${error}`;
|
|
2259
1857
|
* }
|
|
@@ -2265,11 +1863,11 @@ export declare class Validator {
|
|
|
2265
1863
|
* }
|
|
2266
1864
|
*
|
|
2267
1865
|
* // Get the configured options
|
|
2268
|
-
* const options = Validator.
|
|
1866
|
+
* const options = Validator.getValidatorClassOptions(CustomUser);
|
|
2269
1867
|
* console.log(typeof options.errorMessageBuilder); // 'function'
|
|
2270
1868
|
*
|
|
2271
1869
|
* // These options will be automatically used when validating
|
|
2272
|
-
* const result = await Validator.
|
|
1870
|
+
* const result = await Validator.validateClass(CustomUser, userData);
|
|
2273
1871
|
* // Error messages will use the custom format
|
|
2274
1872
|
* ```
|
|
2275
1873
|
*
|
|
@@ -2280,11 +1878,11 @@ export declare class Validator {
|
|
|
2280
1878
|
* @returns Validation options object, or empty object if none configured
|
|
2281
1879
|
*
|
|
2282
1880
|
*
|
|
2283
|
-
* @see {@link
|
|
2284
|
-
* @see {@link
|
|
1881
|
+
* @see {@link validateClass} - Uses these options during validation
|
|
1882
|
+
* @see {@link ValidationClassOptions} - Decorator to set these options
|
|
2285
1883
|
* @public
|
|
2286
1884
|
*/
|
|
2287
|
-
static
|
|
1885
|
+
static getValidatorClassOptions<T = any>(target: T): ValidatorClassOptions<any, any>;
|
|
2288
1886
|
/**
|
|
2289
1887
|
* ## Build Rule Decorator Factory
|
|
2290
1888
|
*
|
|
@@ -2577,7 +2175,7 @@ export declare class Validator {
|
|
|
2577
2175
|
* - Rule functions are reused across multiple property applications
|
|
2578
2176
|
*
|
|
2579
2177
|
* #### Runtime Performance
|
|
2580
|
-
* - Validation execution is deferred until `
|
|
2178
|
+
* - Validation execution is deferred until `validateClass()` is called
|
|
2581
2179
|
* - Parameter binding happens during decoration, not validation
|
|
2582
2180
|
* - No reflection overhead during actual validation
|
|
2583
2181
|
*
|
|
@@ -2631,7 +2229,7 @@ export declare class Validator {
|
|
|
2631
2229
|
*
|
|
2632
2230
|
* #### Context Propagation
|
|
2633
2231
|
* ```typescript
|
|
2634
|
-
* const result = await Validator.
|
|
2232
|
+
* const result = await Validator.validateClass(UserClass, {
|
|
2635
2233
|
* data: userData,
|
|
2636
2234
|
* context: { userId: 123, permissions: ['read'] },
|
|
2637
2235
|
* errorMessageBuilder: (field, error) => `${field}: ${error}`
|
|
@@ -2719,13 +2317,13 @@ export declare class Validator {
|
|
|
2719
2317
|
* - Wrap single parameters: `[value]` instead of `value`
|
|
2720
2318
|
*
|
|
2721
2319
|
* #### Async rule not working
|
|
2722
|
-
* - Ensure `
|
|
2320
|
+
* - Ensure `validateClass()` is called with `await`
|
|
2723
2321
|
* - Check that validation context includes required services
|
|
2724
2322
|
* - Verify async rule returns Promise<string | false | undefined>
|
|
2725
2323
|
*
|
|
2726
2324
|
* ### Related Methods
|
|
2727
2325
|
*
|
|
2728
|
-
* - {@link
|
|
2326
|
+
* - {@link buildClassRuleDecorator} - Specialized for nested class validation
|
|
2729
2327
|
* - {@link buildPropertyDecorator} - Low-level decorator creation
|
|
2730
2328
|
* - {@link buildMultiRuleDecorator} - For rules with multiple validation functions
|
|
2731
2329
|
*
|
|
@@ -2733,7 +2331,7 @@ export declare class Validator {
|
|
|
2733
2331
|
*
|
|
2734
2332
|
* - {@link ValidatorTupleAllowsEmpty} - Type for conditional parameter optionality
|
|
2735
2333
|
* - {@link ValidatorRuleFunction} - Rule function interface
|
|
2736
|
-
* - {@link
|
|
2334
|
+
* - {@link validateClass} - Main validation execution method
|
|
2737
2335
|
* - {@link ValidationOptions} - Complete validation context interface
|
|
2738
2336
|
*
|
|
2739
2337
|
* @template TRuleParams - Tuple type defining the exact parameter structure for the rule.
|
|
@@ -2821,34 +2419,123 @@ export declare class Validator {
|
|
|
2821
2419
|
* @since 1.0.0
|
|
2822
2420
|
* @public
|
|
2823
2421
|
* @category Decorator Factories
|
|
2824
|
-
* @see {@link
|
|
2422
|
+
* @see {@link buildClassRuleDecorator}
|
|
2825
2423
|
* @see {@link ValidatorRuleFunction}
|
|
2826
2424
|
* @see {@link ValidatorTupleAllowsEmpty}
|
|
2827
2425
|
*/
|
|
2828
2426
|
static buildRuleDecorator<TRuleParams extends ValidatorRuleParams = ValidatorRuleParams, Context = unknown>(ruleFunction: ValidatorRuleFunction<TRuleParams, Context>, ruleName?: ValidatorRuleName, symbolMarker?: symbol): (...ruleParameters: TRuleParams) => PropertyDecorator;
|
|
2427
|
+
static isSuccess<Context = unknown>(result: ValidatorResult<Context>): result is ValidatorSuccess<Context>;
|
|
2428
|
+
/**
|
|
2429
|
+
* ## Get Base Error Properties
|
|
2430
|
+
*
|
|
2431
|
+
* Helper method that constructs the foundational properties shared by all validation errors.
|
|
2432
|
+
* This ensures consistency across different error types (single, target, bulk) by centralizing
|
|
2433
|
+
* the creation of timestamp, duration, status code, and error identification fields.
|
|
2434
|
+
*
|
|
2435
|
+
* @param options.startTime - The timestamp when validation started (for duration calculation)
|
|
2436
|
+
* @returns An object containing common error fields (success status, error codes, timings)
|
|
2437
|
+
* @private
|
|
2438
|
+
*/
|
|
2439
|
+
private static getBaseError;
|
|
2440
|
+
/**
|
|
2441
|
+
* ## Check Base Error Structure
|
|
2442
|
+
*
|
|
2443
|
+
* Type guard that verifies if an unknown value matches the structure of a `ValidatorBaseError`.
|
|
2444
|
+
* Checks for specific marker properties and error codes that all validation errors inherit.
|
|
2445
|
+
*
|
|
2446
|
+
* @param value - The value to check
|
|
2447
|
+
* @returns `true` if it's a validation error base structure
|
|
2448
|
+
* @private
|
|
2449
|
+
*/
|
|
2450
|
+
private static isBaseError;
|
|
2451
|
+
/**
|
|
2452
|
+
* ## Create Single Validation Error
|
|
2453
|
+
*
|
|
2454
|
+
* Factory method for creating a `ValidatorError`.
|
|
2455
|
+
* Represents a failure in a simple, single-value validation context.
|
|
2456
|
+
*
|
|
2457
|
+
* @param message - Human-readable error message
|
|
2458
|
+
* @param details - Contextual details (value, startTime, etc.)
|
|
2459
|
+
* @returns A structured `ValidatorError` object
|
|
2460
|
+
*/
|
|
2461
|
+
static createError(message: string, details: ValidatorCreateErrorPayload): ValidatorError;
|
|
2462
|
+
/**
|
|
2463
|
+
* ## Create TClass Validation Error
|
|
2464
|
+
*
|
|
2465
|
+
* Factory method for creating a `ValidatorClassError`.
|
|
2466
|
+
* Represents a failure when validating a class instance or complex object target,
|
|
2467
|
+
* containing a map of field-specific errors.
|
|
2468
|
+
*
|
|
2469
|
+
* @param message - General summary message
|
|
2470
|
+
* @param details - Context including the `errors` map for specific fields
|
|
2471
|
+
* @returns A structured `ValidatorClassError` object
|
|
2472
|
+
*/
|
|
2473
|
+
static createClassError(message: string, details: ValidatorCreateClassErrorPayload): ValidatorClassError;
|
|
2474
|
+
/**
|
|
2475
|
+
* ## Create Bulk Validation Error
|
|
2476
|
+
*
|
|
2477
|
+
* Factory method for creating a `ValidatorBulkError`.
|
|
2478
|
+
* Represents a failure when validating an array of items, mapping indices to specific errors.
|
|
2479
|
+
*
|
|
2480
|
+
* @template TClass - The Target class type
|
|
2481
|
+
* @param message - General summary message
|
|
2482
|
+
* @param details - Context including the `errors` map (index -> error)
|
|
2483
|
+
* @returns A structured `ValidatorBulkError` object
|
|
2484
|
+
*/
|
|
2485
|
+
static createBulkError<TClass extends ClassConstructor = ClassConstructor>(message: string, details: ValidatorCreateBulkErrorPayload): ValidatorBulkError<TClass>;
|
|
2486
|
+
/**
|
|
2487
|
+
* ## Check for Single Validation Error
|
|
2488
|
+
*
|
|
2489
|
+
* Type guard to determine if a result is specifically a `ValidatorError`.
|
|
2490
|
+
* Useful for distinguishing between simple value errors and complex target/bulk errors.
|
|
2491
|
+
*
|
|
2492
|
+
* @param result - The value to check
|
|
2493
|
+
* @returns `true` if it's a single value validation error
|
|
2494
|
+
*/
|
|
2495
|
+
static isError(result: unknown): result is ValidatorError;
|
|
2496
|
+
/**
|
|
2497
|
+
* ## Check for TClass Validation Error
|
|
2498
|
+
*
|
|
2499
|
+
* Type guard to determine if a result is a `ValidatorClassError`.
|
|
2500
|
+
* Identifies errors resulting from class/object validation (e.g., `validateClass`).
|
|
2501
|
+
*
|
|
2502
|
+
* @param result - The value to check
|
|
2503
|
+
* @returns `true` if it's a target object validation error
|
|
2504
|
+
*/
|
|
2505
|
+
static isClassError(result: unknown): result is ValidatorClassError;
|
|
2506
|
+
/**
|
|
2507
|
+
* ## Check for Bulk Validation Error
|
|
2508
|
+
*
|
|
2509
|
+
* Type guard to determine if a result is a `ValidatorBulkError`.
|
|
2510
|
+
* Identifies errors resulting from array bulk validation.
|
|
2511
|
+
*
|
|
2512
|
+
* @param result - The value to check
|
|
2513
|
+
* @returns `true` if it's a bulk validation error
|
|
2514
|
+
*/
|
|
2515
|
+
static isBulkError(result: unknown): result is ValidatorBulkError;
|
|
2829
2516
|
private static _prepareRuleDecorator;
|
|
2830
2517
|
private static _buildRuleDecorator;
|
|
2831
2518
|
/**
|
|
2832
|
-
* ## Build
|
|
2519
|
+
* ## Build TClass Rule Decorator Factory
|
|
2833
2520
|
*
|
|
2834
2521
|
* Creates a specialized decorator factory for validation rules that target nested class
|
|
2835
2522
|
* objects. This method wraps buildRuleDecorator with type specialization for target-based
|
|
2836
2523
|
* rules like @ValidateNested.
|
|
2837
2524
|
*
|
|
2838
2525
|
* ### Purpose
|
|
2839
|
-
*
|
|
2526
|
+
* TClass rule decorators validate properties by delegating to another class's validation
|
|
2840
2527
|
* schema. The most common example is @ValidateNested, which validates nested objects
|
|
2841
2528
|
* against a separate decorated class.
|
|
2842
2529
|
*
|
|
2843
2530
|
* ### How It Works
|
|
2844
|
-
* 1. Takes a rule function specialized for target parameters: [
|
|
2531
|
+
* 1. Takes a rule function specialized for target parameters: [targetClass]
|
|
2845
2532
|
* 2. Wraps it using buildRuleDecorator to create a decorator factory
|
|
2846
2533
|
* 3. Returns a decorator factory that accepts the target class constructor
|
|
2847
2534
|
* 4. When the decorator is applied to a property, it triggers target-based validation
|
|
2848
2535
|
* 5. The rule function receives the target class constructor in ruleParams[0]
|
|
2849
2536
|
*
|
|
2850
2537
|
* ### Type Parameters
|
|
2851
|
-
* -
|
|
2538
|
+
* - TClass: The nested class constructor type (defaults to ClassConstructor)
|
|
2852
2539
|
* - Must be a valid TypeScript class constructor
|
|
2853
2540
|
* - Can have any validation decorators
|
|
2854
2541
|
* - Example: Address, Contact, Location
|
|
@@ -2863,7 +2550,7 @@ export declare class Validator {
|
|
|
2863
2550
|
* ```typescript
|
|
2864
2551
|
* {
|
|
2865
2552
|
* value: any; // The property value being validated
|
|
2866
|
-
* ruleParams: [
|
|
2553
|
+
* ruleParams: [targetClass]; // Single-element array with target constructor
|
|
2867
2554
|
* context?: Context; // Validation context (if provided)
|
|
2868
2555
|
* fieldName: string; // Property name
|
|
2869
2556
|
* translatedPropertyName: string; // Localized property name
|
|
@@ -2875,16 +2562,16 @@ export declare class Validator {
|
|
|
2875
2562
|
* ```typescript
|
|
2876
2563
|
* // Create a target-based validation rule
|
|
2877
2564
|
* const validateNestedRule = ({ value, ruleParams, context }) => {
|
|
2878
|
-
* const [
|
|
2879
|
-
* // Validate value against
|
|
2880
|
-
* return Validator.
|
|
2565
|
+
* const [targetClass] = ruleParams;
|
|
2566
|
+
* // Validate value against targetClass schema
|
|
2567
|
+
* return Validator.validateClass(targetClass, {
|
|
2881
2568
|
* data: value,
|
|
2882
2569
|
* context: context
|
|
2883
2570
|
* });
|
|
2884
2571
|
* };
|
|
2885
2572
|
*
|
|
2886
2573
|
* // Create a target rule decorator
|
|
2887
|
-
* const ValidateNested = Validator.
|
|
2574
|
+
* const ValidateNested = Validator.buildClassRuleDecorator(validateNestedRule);
|
|
2888
2575
|
*
|
|
2889
2576
|
* // Use the decorator with a target class
|
|
2890
2577
|
* class Address {
|
|
@@ -2933,7 +2620,7 @@ export declare class Validator {
|
|
|
2933
2620
|
* }
|
|
2934
2621
|
*
|
|
2935
2622
|
* // Validate with context
|
|
2936
|
-
* const result = await Validator.
|
|
2623
|
+
* const result = await Validator.validateClass(Event, {
|
|
2937
2624
|
* data: eventData,
|
|
2938
2625
|
* context: { userId: 123, permissions: ['edit'] },
|
|
2939
2626
|
* errorMessageBuilder: (fieldName, error) => `${fieldName}: ${error}`
|
|
@@ -2949,15 +2636,15 @@ export declare class Validator {
|
|
|
2949
2636
|
* - Examples: @MinLength([5]), @IsEmail()([]), @Pattern([/regex/])
|
|
2950
2637
|
* - Rule params can be any values
|
|
2951
2638
|
*
|
|
2952
|
-
* **
|
|
2953
|
-
* - Accepts specifically [
|
|
2639
|
+
* **buildClassRuleDecorator (Specialized):**
|
|
2640
|
+
* - Accepts specifically [targetClass] as ruleParams
|
|
2954
2641
|
* - Used for class-level nested validation
|
|
2955
2642
|
* - Examples: @ValidateNested(Address), custom target validators
|
|
2956
2643
|
* - Rule params must contain a class constructor
|
|
2957
2644
|
*
|
|
2958
2645
|
* ### Implementation Details
|
|
2959
2646
|
* This method is a thin wrapper around buildRuleDecorator that:
|
|
2960
|
-
* - Specializes the TRuleParams to [target:
|
|
2647
|
+
* - Specializes the TRuleParams to [target: TClass]
|
|
2961
2648
|
* - Maintains type safety for target-based rules
|
|
2962
2649
|
* - Delegates all decorator factory logic to buildRuleDecorator
|
|
2963
2650
|
* - Reduces code duplication while providing specialized typing
|
|
@@ -2965,7 +2652,7 @@ export declare class Validator {
|
|
|
2965
2652
|
* ### Performance Characteristics
|
|
2966
2653
|
* - No additional overhead vs buildRuleDecorator
|
|
2967
2654
|
* - Wrapper instantiation happens at decoration time, not at import
|
|
2968
|
-
* - Actual validation is performed lazily during
|
|
2655
|
+
* - Actual validation is performed lazily during validateClass() calls
|
|
2969
2656
|
* - Multiple properties with same target class share no cached state
|
|
2970
2657
|
*
|
|
2971
2658
|
* ### Error Handling
|
|
@@ -2982,7 +2669,7 @@ export declare class Validator {
|
|
|
2982
2669
|
* - Context is propagated through nested validation layers
|
|
2983
2670
|
* - I18n support for error messages
|
|
2984
2671
|
*
|
|
2985
|
-
* @template
|
|
2672
|
+
* @template TClass - Class constructor type for the target/nested class
|
|
2986
2673
|
* - Extends ClassConstructor (default generic class constructor)
|
|
2987
2674
|
* - Must be a class decorated with validation rules
|
|
2988
2675
|
* - Example types: typeof Address, typeof Contact, typeof Location
|
|
@@ -2993,7 +2680,7 @@ export declare class Validator {
|
|
|
2993
2680
|
* - Can include permissions, user info, environmental data, etc.
|
|
2994
2681
|
*
|
|
2995
2682
|
* @param ruleFunction - The target validation rule function to wrap
|
|
2996
|
-
* - Must accept ruleParams in format [
|
|
2683
|
+
* - Must accept ruleParams in format [targetClass]
|
|
2997
2684
|
* - Called by the decorator with target class as first param element
|
|
2998
2685
|
* - Should return validation result or error message
|
|
2999
2686
|
* - Can be synchronous or asynchronous
|
|
@@ -3004,17 +2691,17 @@ export declare class Validator {
|
|
|
3004
2691
|
* - Accepts the target class constructor
|
|
3005
2692
|
* - Returns a property decorator
|
|
3006
2693
|
* - Attaches target-based validation to class properties
|
|
3007
|
-
* - Works with class validation via
|
|
2694
|
+
* - Works with class validation via validateClass()
|
|
3008
2695
|
*
|
|
3009
2696
|
*
|
|
3010
2697
|
* @see {@link buildRuleDecorator} - General-purpose decorator factory
|
|
3011
2698
|
* @see {@link buildPropertyDecorator} - Low-level decorator creation
|
|
3012
2699
|
* @see {@link ValidateNested} - Example target rule decorator
|
|
3013
2700
|
* @see {@link validateNestedRule} - Example target validation rule
|
|
3014
|
-
* @see {@link
|
|
2701
|
+
* @see {@link validateClass} - Parent validation method using target rules
|
|
3015
2702
|
* @public
|
|
3016
2703
|
*/
|
|
3017
|
-
static
|
|
2704
|
+
static buildClassRuleDecorator<TClass extends ClassConstructor = ClassConstructor, Context = unknown>(ruleFunction: ValidatorRuleFunction<[target: TClass], Context>, symbolMarker?: symbol): (target: TClass) => PropertyDecorator;
|
|
3018
2705
|
/**
|
|
3019
2706
|
* ## Build Multi-Rule Decorator Factory
|
|
3020
2707
|
*
|
|
@@ -3221,7 +2908,7 @@ export declare class Validator {
|
|
|
3221
2908
|
* - Accepts an array of validation rules as parameters
|
|
3222
2909
|
* - Returns a property decorator when called
|
|
3223
2910
|
* - Attaches multi-rule validation to class properties
|
|
3224
|
-
* - Works with class validation via `
|
|
2911
|
+
* - Works with class validation via `validateClass()`
|
|
3225
2912
|
* - Enables complex validation logic through rule composition
|
|
3226
2913
|
*
|
|
3227
2914
|
* @example
|
|
@@ -3249,14 +2936,14 @@ export declare class Validator {
|
|
|
3249
2936
|
* }
|
|
3250
2937
|
*
|
|
3251
2938
|
* // Validate with context
|
|
3252
|
-
* const result = await Validator.
|
|
2939
|
+
* const result = await Validator.validateClass(Contact, {
|
|
3253
2940
|
* data: { primaryContact: "user@example.com", secondaryContact: "" },
|
|
3254
2941
|
* context: { allowEmptySecondary: true }
|
|
3255
2942
|
* });
|
|
3256
2943
|
* ```
|
|
3257
2944
|
*
|
|
3258
2945
|
* @see {@link buildRuleDecorator} - General-purpose decorator factory
|
|
3259
|
-
* @see {@link
|
|
2946
|
+
* @see {@link buildClassRuleDecorator} - For nested class validation
|
|
3260
2947
|
* @see {@link buildPropertyDecorator} - Low-level decorator creation
|
|
3261
2948
|
* @see {@link OneOf} - Example OneOf multi-rule decorator
|
|
3262
2949
|
* @see {@link AllOf} - Example AllOf multi-rule decorator
|
|
@@ -3277,7 +2964,7 @@ export declare class Validator {
|
|
|
3277
2964
|
* ### Purpose
|
|
3278
2965
|
* This is the most fundamental decorator factory in the validation system. It creates property
|
|
3279
2966
|
* decorators that store validation rules as metadata on class properties, enabling the
|
|
3280
|
-
* {@link
|
|
2967
|
+
* {@link validateClass} method to discover and execute validation rules during class-based
|
|
3281
2968
|
* validation. Unlike higher-level factories, this method works directly with rule objects
|
|
3282
2969
|
* and metadata storage.
|
|
3283
2970
|
*
|
|
@@ -3286,7 +2973,7 @@ export declare class Validator {
|
|
|
3286
2973
|
* 2. Uses the imported `buildPropertyDecorator` helper to create a property decorator
|
|
3287
2974
|
* 3. Stores rules under the `VALIDATOR_TARGET_RULES_METADATA_KEY` symbol
|
|
3288
2975
|
* 4. When applied to a property, accumulates rules with existing rules on the same property
|
|
3289
|
-
* 5. Enables rule discovery during `
|
|
2976
|
+
* 5. Enables rule discovery during `validateClass()` execution
|
|
3290
2977
|
*
|
|
3291
2978
|
* ### Rule Accumulation Logic
|
|
3292
2979
|
* The decorator accumulates rules rather than replacing them:
|
|
@@ -3455,14 +3142,14 @@ export declare class Validator {
|
|
|
3455
3142
|
* - **Accumulation**: Efficient array concatenation for multiple decorators
|
|
3456
3143
|
*
|
|
3457
3144
|
* ### Error Handling
|
|
3458
|
-
* - **Invalid rules**: Stored as-is (validation errors occur during `
|
|
3145
|
+
* - **Invalid rules**: Stored as-is (validation errors occur during `validateClass`)
|
|
3459
3146
|
* - **Metadata failures**: Falls back gracefully if Reflect Metadata unavailable
|
|
3460
3147
|
* - **Type mismatches**: TypeScript prevents invalid rule types at compile time
|
|
3461
3148
|
* - **Runtime errors**: Handled during validation, not decoration
|
|
3462
3149
|
*
|
|
3463
3150
|
* ### Integration with Validation System
|
|
3464
3151
|
* - **Metadata discovery**: Rules found by `getDecoratedProperties()` during validation
|
|
3465
|
-
* - **Parallel execution**: All property rules validated simultaneously in `
|
|
3152
|
+
* - **Parallel execution**: All property rules validated simultaneously in `validateClass()`
|
|
3466
3153
|
* - **Error aggregation**: Property-level errors collected with field names
|
|
3467
3154
|
* - **Context propagation**: Validation context passed to all rule functions
|
|
3468
3155
|
* - **i18n support**: Error messages localized through validation system
|
|
@@ -3488,7 +3175,7 @@ export declare class Validator {
|
|
|
3488
3175
|
* - Attaches the specified rule(s) to class properties
|
|
3489
3176
|
* - Accumulates rules when multiple decorators applied
|
|
3490
3177
|
* - Stores rules as metadata for validation discovery
|
|
3491
|
-
* - Works with `
|
|
3178
|
+
* - Works with `validateClass()` for class validation
|
|
3492
3179
|
* - Enables type-safe property-level validation
|
|
3493
3180
|
*
|
|
3494
3181
|
* @example
|
|
@@ -3516,7 +3203,7 @@ export declare class Validator {
|
|
|
3516
3203
|
* }
|
|
3517
3204
|
*
|
|
3518
3205
|
* // Validate the class
|
|
3519
|
-
* const result = await Validator.
|
|
3206
|
+
* const result = await Validator.validateClass(User, {
|
|
3520
3207
|
* data: {
|
|
3521
3208
|
* name: "John",
|
|
3522
3209
|
* email: "john@example.com",
|
|
@@ -3529,8 +3216,8 @@ export declare class Validator {
|
|
|
3529
3216
|
*
|
|
3530
3217
|
* @see {@link buildRuleDecorator} - Higher-level decorator factory with parameter handling
|
|
3531
3218
|
* @see {@link buildMultiRuleDecorator} - For multi-rule validation patterns
|
|
3532
|
-
* @see {@link
|
|
3533
|
-
* @see {@link
|
|
3219
|
+
* @see {@link buildClassRuleDecorator} - For nested class validation
|
|
3220
|
+
* @see {@link validateClass} - Class validation method that uses these decorators
|
|
3534
3221
|
* @see {@link getDecoratedProperties} - Metadata discovery for validation
|
|
3535
3222
|
* @see {@link ValidatorRule} - Rule type attached by this decorator
|
|
3536
3223
|
* @see {@link VALIDATOR_TARGET_RULES_METADATA_KEY} - Metadata key for rule storage
|
|
@@ -3539,11 +3226,11 @@ export declare class Validator {
|
|
|
3539
3226
|
static buildPropertyDecorator<TRuleParams extends ValidatorRuleParams = ValidatorRuleParams, Context = unknown>(rule: BuildPropertyDecorator<TRuleParams, Context> | BuildPropertyDecorator<TRuleParams, Context>[]): PropertyDecorator;
|
|
3540
3227
|
}
|
|
3541
3228
|
/**
|
|
3542
|
-
* ##
|
|
3229
|
+
* ## ValidationClassOptions Class Decorator
|
|
3543
3230
|
*
|
|
3544
3231
|
* Class decorator that configures validation behavior for a target class.
|
|
3545
3232
|
* This decorator allows you to set class-level validation options that will
|
|
3546
|
-
* be automatically applied whenever `
|
|
3233
|
+
* be automatically applied whenever `validateClass` is called on the class.
|
|
3547
3234
|
*
|
|
3548
3235
|
* ### Configuration Options
|
|
3549
3236
|
* - **errorMessageBuilder**: Custom function to format validation error messages
|
|
@@ -3559,7 +3246,7 @@ export declare class Validator {
|
|
|
3559
3246
|
* @example
|
|
3560
3247
|
* ```typescript
|
|
3561
3248
|
* // Basic usage with custom error formatting
|
|
3562
|
-
* @
|
|
3249
|
+
* @ValidationClassOptions({
|
|
3563
3250
|
* errorMessageBuilder: (fieldName, error) => {
|
|
3564
3251
|
* return `🚫 ${fieldName.toUpperCase()}: ${error}`;
|
|
3565
3252
|
* // {
|
|
@@ -3579,7 +3266,7 @@ export declare class Validator {
|
|
|
3579
3266
|
* // "🚫 NAME: Must be at least 3 characters"
|
|
3580
3267
|
*
|
|
3581
3268
|
* // Advanced usage with context and detailed formatting
|
|
3582
|
-
* @
|
|
3269
|
+
* @ValidationClassOptions({
|
|
3583
3270
|
* errorMessageBuilder: (translatedName, error, builderOptions) => {
|
|
3584
3271
|
* const { propertyName, ruleName, separators } = builderOptions;
|
|
3585
3272
|
*
|
|
@@ -3613,7 +3300,7 @@ export declare class Validator {
|
|
|
3613
3300
|
* organizationId: string;
|
|
3614
3301
|
* }
|
|
3615
3302
|
*
|
|
3616
|
-
* @
|
|
3303
|
+
* @ValidationClassOptions({
|
|
3617
3304
|
* errorMessageBuilder: (fieldName, error, { context }) => {
|
|
3618
3305
|
* const userContext = context as UserValidationContext;
|
|
3619
3306
|
* if (userContext?.isAdmin) {
|
|
@@ -3640,7 +3327,7 @@ export declare class Validator {
|
|
|
3640
3327
|
*
|
|
3641
3328
|
* ### Internationalization Support
|
|
3642
3329
|
* ```typescript
|
|
3643
|
-
* @
|
|
3330
|
+
* @ValidationClassOptions({
|
|
3644
3331
|
* errorMessageBuilder: (translatedName, error, { data }) => {
|
|
3645
3332
|
* // Use translated property names and localized error formatting
|
|
3646
3333
|
* const locale = data.preferredLocale || 'en';
|
|
@@ -3670,12 +3357,12 @@ export declare class Validator {
|
|
|
3670
3357
|
* @returns Class decorator function that applies the validation configuration
|
|
3671
3358
|
*
|
|
3672
3359
|
*
|
|
3673
|
-
* @see {@link
|
|
3674
|
-
* @see {@link
|
|
3360
|
+
* @see {@link validateClass} - Method that uses these options
|
|
3361
|
+
* @see {@link getValidatorClassOptions} - Retrieves configured options
|
|
3675
3362
|
* @decorator
|
|
3676
3363
|
* @public
|
|
3677
3364
|
*/
|
|
3678
|
-
export declare function
|
|
3365
|
+
export declare function ValidationClassOptions(validationOptions: ValidatorClassOptions<any, any>): ClassDecorator;
|
|
3679
3366
|
type ValidatorDefaultArray = Array<unknown>;
|
|
3680
3367
|
type BuildPropertyDecorator<TRuleParams extends ValidatorRuleParams = ValidatorRuleParams, Context = unknown> = ValidatorRule<TRuleParams, Context> | ValidatorSanitizedRuleObject<TRuleParams, Context>;
|
|
3681
3368
|
export {};
|