reslib 2.2.0 → 2.3.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/build/auth/errors.d.ts +4 -0
- package/build/auth/errors.js +5 -0
- package/build/auth/index.d.ts +65 -1963
- package/build/auth/index.js +2 -2
- package/build/auth/types.d.ts +42 -0
- package/build/exception/index.js +2 -2
- package/build/resources/index.d.ts +5 -5
- package/build/resources/index.js +3 -3
- 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 +1 -1
- package/build/validator/rules/format.js +3 -3
- package/build/validator/rules/ifRule.d.ts +76 -0
- package/build/validator/rules/ifRule.js +5 -0
- package/build/validator/rules/index.d.ts +1 -0
- package/build/validator/rules/index.js +3 -3
- package/build/validator/rules/multiRules.js +2 -2
- package/build/validator/rules/numeric.js +2 -2
- package/build/validator/rules/object.js +2 -2
- package/build/validator/rules/string.js +2 -2
- package/build/validator/rules/target.js +2 -2
- package/build/validator/rulesMarkers.d.ts +1 -0
- package/build/validator/rulesMarkers.js +1 -1
- package/build/validator/types.d.ts +399 -48
- package/build/validator/validator.d.ts +376 -5
- package/build/validator/validator.js +2 -2
- package/package.json +251 -253
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ClassConstructor, MakeOptional } from '../types';
|
|
1
|
+
import { ClassConstructor, MakeOptional, MakeRequired } from '../types';
|
|
2
2
|
import { I18n } from '../i18n';
|
|
3
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';
|
|
4
|
+
import { ValidatorAsyncRuleResult, ValidatorBulkOptions, ValidatorBulkResult, ValidatorClassOptions, ValidatorClassResult, ValidatorDefaultMultiRule, ValidatorIfResolver, ValidatorIfRuleFunction, ValidatorIfRuleOptions, ValidatorMultiRuleFunction, ValidatorMultiRuleNames, ValidatorMultiRuleOptions, ValidatorNestedRuleFunctionOptions, ValidatorObjectOptions, ValidatorObjectResult, ValidatorObjectRules, ValidatorObjectSchema, ValidatorOptions, ValidatorResult, ValidatorRule, ValidatorRuleConfigMessage, ValidatorRuleFunction, ValidatorRuleFunctionsMap, ValidatorRuleName, ValidatorRuleObject, ValidatorRuleParams, ValidatorRuleResult, ValidatorRules, ValidatorSanitizedRuleObject, ValidatorSanitizedRules, ValidatorSuccess } from './types';
|
|
5
5
|
export declare class Validator {
|
|
6
6
|
private static readonly RULES_METADATA_KEY;
|
|
7
7
|
/**
|
|
@@ -290,7 +290,7 @@ export declare class Validator {
|
|
|
290
290
|
* @see {@link ValidatorOptionalOrEmptyRuleNames} - Type constraint for registered rules
|
|
291
291
|
* @public
|
|
292
292
|
*/
|
|
293
|
-
static getRule<Context = unknown>(ruleName: ValidatorRuleName): ValidatorRuleFunction<[options?: import("../utils/index").IsEmailOptions | undefined], Context> | ValidatorRuleFunction<[options?: import("../utils/index").IsUrlOptions | undefined], Context> | ValidatorRuleFunction<[], Context> | ValidatorRuleFunction<[minLength: number], Context> | ValidatorRuleFunction<[maxLength: number], Context> | ValidatorRuleFunction<[length: number], Context> | ValidatorRuleFunction<any[], Context> | ValidatorRuleFunction<[date: string | number | Date], Context> | ValidatorRuleFunction<[date: string | number | Date], Context> | ValidatorRuleFunction<[minDate: string | number | Date, maxDate: string | number | Date], Context> | ValidatorRuleFunction<[date: string | number | Date], Context> | ValidatorRuleFunction<unknown[], Context> | ValidatorRuleFunction<[size: number], Context> | ValidatorRuleFunction<string[], Context> | ValidatorRuleFunction<[minSize: number], Context> | ValidatorRuleFunction<[countryCode?: "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AI" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "
|
|
293
|
+
static getRule<Context = unknown>(ruleName: ValidatorRuleName): ValidatorRuleFunction<[options?: import("../utils/index").IsEmailOptions | undefined], Context> | ValidatorRuleFunction<[options?: import("../utils/index").IsUrlOptions | undefined], Context> | ValidatorRuleFunction<[], Context> | ValidatorRuleFunction<[minLength: number], Context> | ValidatorRuleFunction<[maxLength: number], Context> | ValidatorRuleFunction<[length: number], Context> | ValidatorRuleFunction<any[], Context> | ValidatorRuleFunction<[date: string | number | Date], Context> | ValidatorRuleFunction<[date: string | number | Date], Context> | ValidatorRuleFunction<[minDate: string | number | Date, maxDate: string | number | Date], Context> | ValidatorRuleFunction<[date: string | number | Date], Context> | ValidatorRuleFunction<unknown[], Context> | ValidatorRuleFunction<[size: number], Context> | ValidatorRuleFunction<string[], Context> | ValidatorRuleFunction<[minSize: number], Context> | ValidatorRuleFunction<[countryCode?: "KM" | "BD" | "CF" | "FR" | "SR" | "TL" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AI" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BM" | "BT" | "BO" | "BA" | "BW" | "BR" | "IO" | "VG" | "BN" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "BQ" | "KY" | "TD" | "CL" | "CN" | "CX" | "CC" | "CO" | "CD" | "CG" | "CK" | "CR" | "CI" | "HR" | "CU" | "CW" | "CY" | "CZ" | "DK" | "DJ" | "DM" | "DO" | "EC" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FK" | "FO" | "FJ" | "FI" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GI" | "GR" | "GL" | "GD" | "GP" | "GU" | "GT" | "GG" | "GN" | "GW" | "GY" | "HT" | "HN" | "HK" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IM" | "IL" | "IT" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LY" | "LI" | "LT" | "LU" | "MO" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MH" | "MQ" | "MR" | "MU" | "YT" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "MM" | "NA" | "NR" | "NP" | "NL" | "NC" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "MP" | "NO" | "OM" | "PK" | "PW" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "RE" | "RO" | "RU" | "RW" | "BL" | "SH" | "KN" | "LC" | "MF" | "PM" | "VC" | "WS" | "SM" | "ST" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SB" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SJ" | "SZ" | "SE" | "CH" | "SY" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TK" | "TO" | "TT" | "TN" | "TR" | "TM" | "TC" | "TV" | "VI" | "UG" | "UA" | "AE" | "GB" | "US" | "UY" | "UZ" | "VU" | "VA" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW" | "AX" | undefined], Context> | ValidatorRuleFunction<[options?: {
|
|
294
294
|
email?: import("../utils/index").IsEmailOptions;
|
|
295
295
|
phoneNumber?: {
|
|
296
296
|
countryCode?: import("../countries").CountryCode;
|
|
@@ -752,6 +752,79 @@ export declare class Validator {
|
|
|
752
752
|
* @returns `true` if the value matches the sanitized rule structure, `false` otherwise
|
|
753
753
|
*/
|
|
754
754
|
static isSanitizedRuleObject<TRuleParams extends ValidatorDefaultArray = ValidatorDefaultArray, Context = unknown>(rule: any): rule is ValidatorSanitizedRuleObject<TRuleParams, Context>;
|
|
755
|
+
/**
|
|
756
|
+
* ## Translate Rule Config Message
|
|
757
|
+
*
|
|
758
|
+
* Translates or processes a custom rule message from a `ValidatorRuleConfigMessage`.
|
|
759
|
+
* This method handles both static string messages (with optional i18n translation)
|
|
760
|
+
* and dynamic function-based messages.
|
|
761
|
+
*
|
|
762
|
+
* ### Purpose
|
|
763
|
+
* This method extracts the rule message translation logic into a reusable function
|
|
764
|
+
* that can be called independently of the `validate` method. It's particularly useful
|
|
765
|
+
* when you need to process custom rule messages in custom validation pipelines or
|
|
766
|
+
* when building custom error handling logic.
|
|
767
|
+
*
|
|
768
|
+
* ### Message Types
|
|
769
|
+
* 1. **Static String**: Can be a direct message or an i18n translation key
|
|
770
|
+
* - If the string is a valid i18n key, it will be translated
|
|
771
|
+
* - Otherwise, the string is used as-is
|
|
772
|
+
* 2. **Dynamic Function**: A function that receives validation options and returns a message
|
|
773
|
+
* - If the function throws an error, an empty string is returned
|
|
774
|
+
*
|
|
775
|
+
* ### Examples
|
|
776
|
+
*
|
|
777
|
+
* #### Static String Message
|
|
778
|
+
* ```typescript
|
|
779
|
+
* const message = Validator.translateRuleConfigMessage({
|
|
780
|
+
* message: 'This field is required',
|
|
781
|
+
* i18n: i18nInstance,
|
|
782
|
+
* validateOptions: { value: '', ruleName: 'Required', ruleParams: [] }
|
|
783
|
+
* });
|
|
784
|
+
* // message = 'This field is required'
|
|
785
|
+
* ```
|
|
786
|
+
*
|
|
787
|
+
* #### i18n Translation Key
|
|
788
|
+
* ```typescript
|
|
789
|
+
* const message = Validator.translateRuleConfigMessage({
|
|
790
|
+
* message: 'validation.required',
|
|
791
|
+
* i18n: i18nInstance,
|
|
792
|
+
* validateOptions: { value: '', ruleName: 'Required', ruleParams: [] }
|
|
793
|
+
* });
|
|
794
|
+
* // message = 'Ce champ est obligatoire' (if i18n is set to French)
|
|
795
|
+
* ```
|
|
796
|
+
*
|
|
797
|
+
* #### Dynamic Function Message
|
|
798
|
+
* ```typescript
|
|
799
|
+
* const message = Validator.translateRuleConfigMessage({
|
|
800
|
+
* message: ({ value, ruleName }) => `Value "${value}" failed ${ruleName} rule`,
|
|
801
|
+
* i18n: i18nInstance,
|
|
802
|
+
* validateOptions: { value: 'test', ruleName: 'Email', ruleParams: [] }
|
|
803
|
+
* });
|
|
804
|
+
* // message = 'Value "test" failed Email rule'
|
|
805
|
+
* ```
|
|
806
|
+
*
|
|
807
|
+
* @template Context - The type of the optional validation context
|
|
808
|
+
*
|
|
809
|
+
* @param options - The options for translating the rule message
|
|
810
|
+
* @param options.message - The rule message to translate (string or function)
|
|
811
|
+
* @param options.i18n - The i18n instance for translation
|
|
812
|
+
* @param options.validateOptions - The validation options passed to function messages
|
|
813
|
+
*
|
|
814
|
+
* @returns The translated/processed message string, or empty string if:
|
|
815
|
+
* - The message is undefined/null
|
|
816
|
+
* - The function message throws an error
|
|
817
|
+
* - The message is not a valid string or function
|
|
818
|
+
*
|
|
819
|
+
* @see {@link ValidatorRuleConfigMessage} - Type definition for rule messages
|
|
820
|
+
* @see {@link validate} - Main validation method that uses this internally
|
|
821
|
+
* @public
|
|
822
|
+
*/
|
|
823
|
+
static translateRuleConfigMessage<Context = unknown>({ message, i18n, validateOptions, }: {
|
|
824
|
+
message: ValidatorRuleConfigMessage | undefined;
|
|
825
|
+
i18n: I18n;
|
|
826
|
+
validateOptions: MakeRequired<Omit<ValidatorOptions<ValidatorDefaultArray, Context>, 'sanitizedRules' | 'rules' | 'rule'>, 'i18n' | 'ruleName' | 'ruleParams'>;
|
|
827
|
+
}): string;
|
|
755
828
|
static validate<Context = unknown>({ rules, ...extra }: MakeOptional<ValidatorOptions<ValidatorDefaultArray, Context>, 'i18n' | 'ruleParams'>): Promise<ValidatorResult<Context>>;
|
|
756
829
|
/**
|
|
757
830
|
* ## Should Skip Validation
|
|
@@ -857,6 +930,122 @@ export declare class Validator {
|
|
|
857
930
|
*
|
|
858
931
|
*/
|
|
859
932
|
static validateArrayOfRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(options: ValidatorMultiRuleOptions<Context, RulesFunctions>): ValidatorAsyncRuleResult;
|
|
933
|
+
/**
|
|
934
|
+
* ## Validate If Rule
|
|
935
|
+
*
|
|
936
|
+
* Conditional validation method that applies rules based on a resolver function.
|
|
937
|
+
* The resolver dynamically determines which rules to apply (if any) based on
|
|
938
|
+
* runtime conditions, enabling flexible, context-aware validation.
|
|
939
|
+
*
|
|
940
|
+
* ### Resolver Pattern
|
|
941
|
+
* Unlike traditional condition + then/otherwise approach, this method uses a single
|
|
942
|
+
* resolver function that returns:
|
|
943
|
+
* - **Rules array**: Apply these validation rules
|
|
944
|
+
* - **Object with `rules` and `message`**: Apply rules with custom error message
|
|
945
|
+
* - **Empty array, `undefined`, or `null`**: Skip validation (return success)
|
|
946
|
+
*
|
|
947
|
+
* ### Use Cases
|
|
948
|
+
* - **Optional Validation**: Only validate if a value is present
|
|
949
|
+
* - **Role-Based Rules**: Different validation based on user role
|
|
950
|
+
* - **Context-Aware Validation**: Rules that depend on application state
|
|
951
|
+
* - **Dynamic Messages**: Custom error messages based on context
|
|
952
|
+
* - **Feature Flags**: Enable/disable validation based on configuration
|
|
953
|
+
*
|
|
954
|
+
* ### Examples
|
|
955
|
+
*
|
|
956
|
+
* #### Optional field validation
|
|
957
|
+
* ```typescript
|
|
958
|
+
* const result = await Validator.validateIfRule({
|
|
959
|
+
* value: optionalEmail,
|
|
960
|
+
* resolver: ({ value }) => {
|
|
961
|
+
* if (!value) return []; // Skip validation
|
|
962
|
+
* return ['Email'];
|
|
963
|
+
* },
|
|
964
|
+
* fieldName: 'email'
|
|
965
|
+
* });
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
968
|
+
* #### Role-based validation with custom message
|
|
969
|
+
* ```typescript
|
|
970
|
+
* const result = await Validator.validateIfRule({
|
|
971
|
+
* value: password,
|
|
972
|
+
* data: { role: 'admin' },
|
|
973
|
+
* resolver: ({ data }) => {
|
|
974
|
+
* if (data?.role === 'admin') {
|
|
975
|
+
* return {
|
|
976
|
+
* rules: ['Required', 'StrongPassword'],
|
|
977
|
+
* message: 'Admin passwords must be strong',
|
|
978
|
+
* };
|
|
979
|
+
* }
|
|
980
|
+
* return ['Required', { MinLength: [6] }];
|
|
981
|
+
* },
|
|
982
|
+
* fieldName: 'password'
|
|
983
|
+
* });
|
|
984
|
+
* ```
|
|
985
|
+
*
|
|
986
|
+
* #### Context-aware validation
|
|
987
|
+
* ```typescript
|
|
988
|
+
* const result = await Validator.validateIfRule({
|
|
989
|
+
* value: username,
|
|
990
|
+
* context: { strictMode: true },
|
|
991
|
+
* resolver: ({ context }) => {
|
|
992
|
+
* if (context?.strictMode) {
|
|
993
|
+
* return ['Required', 'Alphanumeric', { MinLength: [5] }];
|
|
994
|
+
* }
|
|
995
|
+
* return ['Required'];
|
|
996
|
+
* },
|
|
997
|
+
* fieldName: 'username'
|
|
998
|
+
* });
|
|
999
|
+
* ```
|
|
1000
|
+
*
|
|
1001
|
+
* #### Async resolver - Load rules from database
|
|
1002
|
+
* ```typescript
|
|
1003
|
+
* const result = await Validator.validateIfRule({
|
|
1004
|
+
* value: password,
|
|
1005
|
+
* context: { tenantId: 'tenant-123' },
|
|
1006
|
+
* resolver: async ({ context }) => {
|
|
1007
|
+
* // Load validation config from database
|
|
1008
|
+
* const config = await loadValidationConfig(context?.tenantId);
|
|
1009
|
+
* return config.passwordRules;
|
|
1010
|
+
* },
|
|
1011
|
+
* fieldName: 'password'
|
|
1012
|
+
* });
|
|
1013
|
+
* ```
|
|
1014
|
+
*
|
|
1015
|
+
* #### Async resolver - Feature flag check
|
|
1016
|
+
* ```typescript
|
|
1017
|
+
* const result = await Validator.validateIfRule({
|
|
1018
|
+
* value: username,
|
|
1019
|
+
* resolver: async () => {
|
|
1020
|
+
* const useStrictValidation = await featureFlags.isEnabled('strict-username');
|
|
1021
|
+
* if (useStrictValidation) {
|
|
1022
|
+
* return ['Required', 'Alphanumeric', { MinLength: [5] }];
|
|
1023
|
+
* }
|
|
1024
|
+
* return ['Required'];
|
|
1025
|
+
* },
|
|
1026
|
+
* fieldName: 'username'
|
|
1027
|
+
* });
|
|
1028
|
+
* ```
|
|
1029
|
+
*
|
|
1030
|
+
* @template Context - Type of the optional validation context
|
|
1031
|
+
*
|
|
1032
|
+
* @param options - The validation options including resolver function
|
|
1033
|
+
* @param options.resolver - Function that returns rules to apply (sync or async)
|
|
1034
|
+
* @param options.value - The value to validate
|
|
1035
|
+
* @param options.data - Optional additional data (other fields)
|
|
1036
|
+
* @param options.context - Optional application-specific context
|
|
1037
|
+
* @param options.message - Optional fallback message (used if resolver doesn't provide one)
|
|
1038
|
+
*
|
|
1039
|
+
* @returns ValidatorAsyncRuleResult - `true` if validation passes, error string otherwise
|
|
1040
|
+
*
|
|
1041
|
+
* @public
|
|
1042
|
+
* @async
|
|
1043
|
+
* @see {@link if} - Factory method to create reusable If rules
|
|
1044
|
+
* @see {@link ValidatorIfRuleOptions} - Options interface
|
|
1045
|
+
* @see {@link ValidatorIfResolver} - Resolver function type (supports sync/async)
|
|
1046
|
+
* @see {@link ValidatorIfResolverResult} - Resolver return type
|
|
1047
|
+
*/
|
|
1048
|
+
static validateIfRule<Context = unknown>(options: ValidatorIfRuleOptions<Context>): ValidatorAsyncRuleResult;
|
|
860
1049
|
static getI18nTranslateOptions<Context = unknown>({ fieldName, propertyName, fieldLabel, translatedPropertyName, context, ...rest }: Partial<ValidatorOptions<ValidatorDefaultArray, Context>>): Partial<ValidatorOptions<ValidatorDefaultArray, Context>>;
|
|
861
1050
|
/**
|
|
862
1051
|
* ## Validate Nested Rule (Core Nested Validation Executor)
|
|
@@ -1043,7 +1232,7 @@ export declare class Validator {
|
|
|
1043
1232
|
* @public
|
|
1044
1233
|
* @async
|
|
1045
1234
|
*/
|
|
1046
|
-
static validateMultiRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(ruleName: ValidatorMultiRuleNames, { value, ruleParams, startTime, ...extra }: ValidatorMultiRuleOptions<Context, RulesFunctions>): Promise<string | true>;
|
|
1235
|
+
static validateMultiRule<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(ruleName: ValidatorMultiRuleNames, { value, ruleParams, startTime, message, ...extra }: ValidatorMultiRuleOptions<Context, RulesFunctions>): Promise<string | true>;
|
|
1047
1236
|
/**
|
|
1048
1237
|
* ## Create OneOf Validation Rule
|
|
1049
1238
|
*
|
|
@@ -1237,6 +1426,129 @@ export declare class Validator {
|
|
|
1237
1426
|
*
|
|
1238
1427
|
*/
|
|
1239
1428
|
static arrayOf<Context = unknown>(ruleParams: ValidatorDefaultMultiRule<Context>): ValidatorRuleFunction<ValidatorDefaultArray, Context>;
|
|
1429
|
+
/**
|
|
1430
|
+
* ## Create If Validation Rule
|
|
1431
|
+
*
|
|
1432
|
+
* Factory method that creates a conditional validation rule function. This method provides
|
|
1433
|
+
* a programmatic way to create validation rules that apply different sub-rules based on
|
|
1434
|
+
* a runtime resolver function.
|
|
1435
|
+
*
|
|
1436
|
+
* ### Resolver Pattern
|
|
1437
|
+
* Unlike traditional condition + then/otherwise approach, this factory accepts a single
|
|
1438
|
+
* resolver function that returns the rules to apply. This enables:
|
|
1439
|
+
* - **Complex conditional logic**: Multi-branch conditions, nested checks
|
|
1440
|
+
* - **Dynamic messages**: Different messages based on context
|
|
1441
|
+
* - **Rule composition**: Build rules dynamically from multiple sources
|
|
1442
|
+
* - **Early exit**: Return empty array to skip validation entirely
|
|
1443
|
+
*
|
|
1444
|
+
* ### Return Value
|
|
1445
|
+
* Returns a `ValidatorRuleFunction` that can be used:
|
|
1446
|
+
* - In `Validator.validate()` calls
|
|
1447
|
+
* - In validation decorators like `@IsProperty()`
|
|
1448
|
+
* - As part of rule arrays in class-based validation
|
|
1449
|
+
*
|
|
1450
|
+
* ### Examples
|
|
1451
|
+
*
|
|
1452
|
+
* #### Optional Field Validation
|
|
1453
|
+
* ```typescript
|
|
1454
|
+
* // Only validate email format if value is present
|
|
1455
|
+
* const optionalEmail = Validator.if(({ value }) => {
|
|
1456
|
+
* if (!value) return []; // Skip validation
|
|
1457
|
+
* return ['Email'];
|
|
1458
|
+
* });
|
|
1459
|
+
*
|
|
1460
|
+
* await optionalEmail({ value: '' }); // true (resolver returns [])
|
|
1461
|
+
* await optionalEmail({ value: 'invalid' }); // error (Email fails)
|
|
1462
|
+
* await optionalEmail({ value: 'user@example.com' }); // true
|
|
1463
|
+
* ```
|
|
1464
|
+
*
|
|
1465
|
+
* #### Role-Based Validation
|
|
1466
|
+
* ```typescript
|
|
1467
|
+
* const passwordRule = Validator.if(({ data }) => {
|
|
1468
|
+
* if (data?.role === 'admin') {
|
|
1469
|
+
* return ['Required', 'StrongPassword'];
|
|
1470
|
+
* }
|
|
1471
|
+
* if (data?.role === 'moderator') {
|
|
1472
|
+
* return ['Required', { MinLength: [8] }];
|
|
1473
|
+
* }
|
|
1474
|
+
* return ['Required', { MinLength: [6] }];
|
|
1475
|
+
* });
|
|
1476
|
+
* ```
|
|
1477
|
+
*
|
|
1478
|
+
* #### With Custom Message
|
|
1479
|
+
* ```typescript
|
|
1480
|
+
* const strictModeRule = Validator.if(({ context, i18n }) => {
|
|
1481
|
+
* if (context?.strictMode) {
|
|
1482
|
+
* return {
|
|
1483
|
+
* rules: ['Required', { MinLength: [10] }],
|
|
1484
|
+
* message: i18n.t('validation.strict_mode_required'),
|
|
1485
|
+
* };
|
|
1486
|
+
* }
|
|
1487
|
+
* return ['Required'];
|
|
1488
|
+
* });
|
|
1489
|
+
* ```
|
|
1490
|
+
*
|
|
1491
|
+
* #### Dependent Field Validation
|
|
1492
|
+
* ```typescript
|
|
1493
|
+
* const confirmPasswordRule = Validator.if(({ value, data }) => {
|
|
1494
|
+
* if (!data?.password) return []; // Skip if no password
|
|
1495
|
+
* return {
|
|
1496
|
+
* rules: ['Required', { Equals: [data.password] }],
|
|
1497
|
+
* message: 'Passwords must match',
|
|
1498
|
+
* };
|
|
1499
|
+
* });
|
|
1500
|
+
* ```
|
|
1501
|
+
*
|
|
1502
|
+
* #### Async Resolver - Load from Database
|
|
1503
|
+
* ```typescript
|
|
1504
|
+
* const dynamicRule = Validator.if(async ({ context }) => {
|
|
1505
|
+
* const config = await loadValidationConfig(context?.tenantId);
|
|
1506
|
+
* return config.rules;
|
|
1507
|
+
* });
|
|
1508
|
+
* ```
|
|
1509
|
+
*
|
|
1510
|
+
* #### Async Resolver - Feature Flag
|
|
1511
|
+
* ```typescript
|
|
1512
|
+
* const featureFlagRule = Validator.if(async () => {
|
|
1513
|
+
* const enabled = await featureFlags.isEnabled('strict-validation');
|
|
1514
|
+
* return enabled ? ['Required', 'StrictFormat'] : ['Required'];
|
|
1515
|
+
* });
|
|
1516
|
+
* ```
|
|
1517
|
+
*
|
|
1518
|
+
* ### Decorator Usage
|
|
1519
|
+
* ```typescript
|
|
1520
|
+
* class UserForm {
|
|
1521
|
+
* @IsProperty([
|
|
1522
|
+
* Validator.if(({ data }) => {
|
|
1523
|
+
* if (data?.userType === 'business') {
|
|
1524
|
+
* return ['Required', { MinLength: [3] }];
|
|
1525
|
+
* }
|
|
1526
|
+
* return []; // No validation for non-business users
|
|
1527
|
+
* })
|
|
1528
|
+
* ])
|
|
1529
|
+
* companyName?: string;
|
|
1530
|
+
* }
|
|
1531
|
+
* ```
|
|
1532
|
+
*
|
|
1533
|
+
* ### Sync vs Async
|
|
1534
|
+
* The resolver supports both synchronous and asynchronous operations:
|
|
1535
|
+
* - **Sync**: Return the result directly for simple, non-blocking logic
|
|
1536
|
+
* - **Async**: Return a Promise for database lookups, API calls, or async configuration
|
|
1537
|
+
*
|
|
1538
|
+
* @template Context - Type of the optional validation context
|
|
1539
|
+
*
|
|
1540
|
+
* @param resolver - Resolver function (sync or async) that returns rules to apply
|
|
1541
|
+
*
|
|
1542
|
+
* @returns A `ValidatorRuleFunction` that performs conditional validation
|
|
1543
|
+
*
|
|
1544
|
+
* @public
|
|
1545
|
+
* @see {@link validateIfRule} - The underlying validation method
|
|
1546
|
+
* @see {@link ValidatorIfResolver} - Resolver function type (supports sync/async)
|
|
1547
|
+
* @see {@link ValidatorIfResolverResult} - Resolver return type
|
|
1548
|
+
* @see {@link oneOf} - Similar factory for OR logic validation
|
|
1549
|
+
* @see {@link allOf} - Similar factory for AND logic validation
|
|
1550
|
+
*/
|
|
1551
|
+
static if<Context = unknown>(resolver: ValidatorIfResolver<Context>): ValidatorRuleFunction<ValidatorDefaultArray, Context>;
|
|
1240
1552
|
/**
|
|
1241
1553
|
* ## Create Nested Validation Rule Factory
|
|
1242
1554
|
*
|
|
@@ -3237,7 +3549,27 @@ export declare class Validator {
|
|
|
3237
3549
|
*/
|
|
3238
3550
|
static isAnyError(result: unknown): result is ValidatorError | ValidatorClassError | ValidatorBulkError;
|
|
3239
3551
|
private static _prepareRuleDecorator;
|
|
3240
|
-
|
|
3552
|
+
/**
|
|
3553
|
+
* ## Create Property Decorator from Rule
|
|
3554
|
+
*
|
|
3555
|
+
* Creates a property decorator for a validation rule with specific parameters.
|
|
3556
|
+
* This method combines rule registration (if a name is provided) with property decorator creation.
|
|
3557
|
+
* Unlike `buildRuleDecorator` which returns a factory, this returns the actual decorator
|
|
3558
|
+
* bound to the provided rule parameters.
|
|
3559
|
+
*
|
|
3560
|
+
* @remarks
|
|
3561
|
+
* **Naming Guide**:
|
|
3562
|
+
* - `buildRuleDecorator`: Creates a **Factory** (e.g. `IsRequired()`) that produces decorators.
|
|
3563
|
+
* - `createPropertyDecoratorFromRule`: Creates the **Decorator** instance directly from parameters.
|
|
3564
|
+
*
|
|
3565
|
+
* @param ruleParameters - The parameters for the validation rule
|
|
3566
|
+
* @param ruleFunction - The validation rule logic
|
|
3567
|
+
* @param ruleName - Optional name to register the rule with
|
|
3568
|
+
* @param symbolMarker - Internal symbol marker
|
|
3569
|
+
* @returns The PropertyDecorator
|
|
3570
|
+
* @public
|
|
3571
|
+
*/
|
|
3572
|
+
static createPropertyDecoratorFromRule<TRuleParams extends ValidatorRuleParams = ValidatorRuleParams, Context = unknown>(ruleParameters: TRuleParams, ruleFunction: ValidatorRuleFunction<TRuleParams, Context>, ruleName?: ValidatorRuleName, symbolMarker?: symbol): PropertyDecorator;
|
|
3241
3573
|
/**
|
|
3242
3574
|
* ## Build TClass Rule Decorator Factory
|
|
3243
3575
|
*
|
|
@@ -3677,6 +4009,45 @@ export declare class Validator {
|
|
|
3677
4009
|
* @public
|
|
3678
4010
|
*/
|
|
3679
4011
|
static buildMultiRuleDecorator<Context = unknown, RulesFunctions extends ValidatorDefaultMultiRule<Context> = ValidatorDefaultMultiRule<Context>>(ruleFunction: ValidatorMultiRuleFunction<Context, RulesFunctions>, symbolMarker?: symbol): (ruleParameters: RulesFunctions) => PropertyDecorator;
|
|
4012
|
+
/**
|
|
4013
|
+
* ## Build If Rule Decorator Factory
|
|
4014
|
+
*
|
|
4015
|
+
* Creates a specialized decorator factory for the conditional `@If` rule.
|
|
4016
|
+
* This method wraps `_buildRuleDecorator` to specifically handle the single
|
|
4017
|
+
* resolver function argument pattern used by `Validator.if`.
|
|
4018
|
+
*
|
|
4019
|
+
* ### Purpose
|
|
4020
|
+
* Standard decorators created by `buildRuleDecorator` typically accept rule parameters
|
|
4021
|
+
* as a spread of arguments (`...args`). However, the `@If` decorator accepts a
|
|
4022
|
+
* single resolver function argument. This factory method adapts the generic decorator
|
|
4023
|
+
* builder to enforce this specific signature, providing better type safety and DX
|
|
4024
|
+
* for conditional validation.
|
|
4025
|
+
*
|
|
4026
|
+
* ### How It Works
|
|
4027
|
+
* 1. Takes the `If` validation function as input
|
|
4028
|
+
* 2. Returns a new decorator factory function
|
|
4029
|
+
* 3. This factory takes a single `ValidatorIfResolver` argument
|
|
4030
|
+
* 4. It passes this resolver as a single-element array to the underlying `_buildRuleDecorator`
|
|
4031
|
+
*
|
|
4032
|
+
* ### Benefits
|
|
4033
|
+
* - **Type Safety**: Enforces that exactly one resolver is passed
|
|
4034
|
+
* - **Simplified API**: Users just pass the function: `@If(({ value }) => ...)`
|
|
4035
|
+
* - **Internal consistency**: Reuses the core decorator infrastructure
|
|
4036
|
+
*
|
|
4037
|
+
* @template Context - Type of the optional validation context
|
|
4038
|
+
*
|
|
4039
|
+
* @param ruleFunction - The core validation logic function (processes the rule)
|
|
4040
|
+
* @param symbolMarker - Optional symbol to tag the decorator for reflection
|
|
4041
|
+
*
|
|
4042
|
+
* @returns A decorator factory that accepts a resolver function
|
|
4043
|
+
*
|
|
4044
|
+
* @public
|
|
4045
|
+
* @see {@link createPropertyDecoratorFromRule} - The internal decorator builder
|
|
4046
|
+
* @see {@link ValidatorIfRuleFunction} - The type of the validation function
|
|
4047
|
+
* @see {@link ValidatorIfResolver} - The resolver type accepted by the decorator
|
|
4048
|
+
* @see {@link ValidatorIfResolver} - The resolver type accepted by the decorator
|
|
4049
|
+
*/
|
|
4050
|
+
static buildIfRuleDecorator<Context = unknown>(ruleFunction: ValidatorIfRuleFunction<Context>, symbolMarker?: symbol): (ifRuleResolver: ValidatorIfResolver<Context>) => PropertyDecorator;
|
|
3680
4051
|
/**
|
|
3681
4052
|
* ## Build Property Decorator Factory
|
|
3682
4053
|
*
|