@umituz/react-native-validation 1.0.1 → 1.0.2
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/package.json +4 -6
- package/lib/domain/entities/ValidationResult.d.ts +0 -8
- package/lib/domain/entities/ValidationResult.js +0 -6
- package/lib/index.d.ts +0 -11
- package/lib/index.js +0 -37
- package/lib/infrastructure/utils/sanitization.d.ts +0 -54
- package/lib/infrastructure/utils/sanitization.js +0 -95
- package/lib/infrastructure/utils/validators.d.ts +0 -78
- package/lib/infrastructure/utils/validators.js +0 -227
package/package.json
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-validation",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Comprehensive validation and sanitization utilities for React Native forms",
|
|
5
|
-
"main": "./
|
|
6
|
-
"types": "./
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"typecheck": "tsc --noEmit",
|
|
10
10
|
"lint": "tsc --noEmit",
|
|
11
11
|
"clean": "rm -rf lib",
|
|
12
12
|
"prebuild": "npm run clean",
|
|
13
|
-
"prepublishOnly": "npm run build",
|
|
14
13
|
"version:patch": "npm version patch -m 'chore: release v%s'",
|
|
15
14
|
"version:minor": "npm version minor -m 'chore: release v%s'",
|
|
16
15
|
"version:major": "npm version major -m 'chore: release v%s'"
|
|
@@ -22,7 +21,7 @@
|
|
|
22
21
|
"validators",
|
|
23
22
|
"form-validation"
|
|
24
23
|
],
|
|
25
|
-
"author": "
|
|
24
|
+
"author": "\u00dcmit UZ <umit@umituz.com>",
|
|
26
25
|
"license": "MIT",
|
|
27
26
|
"repository": {
|
|
28
27
|
"type": "git",
|
|
@@ -43,7 +42,6 @@
|
|
|
43
42
|
"access": "public"
|
|
44
43
|
},
|
|
45
44
|
"files": [
|
|
46
|
-
"lib",
|
|
47
45
|
"src",
|
|
48
46
|
"README.md",
|
|
49
47
|
"LICENSE"
|
package/lib/index.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @umituz/react-native-validation
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive validation utilities for React Native forms.
|
|
5
|
-
* Provides reusable validation functions for common input types.
|
|
6
|
-
*
|
|
7
|
-
* @package react-native-validation
|
|
8
|
-
*/
|
|
9
|
-
export type { ValidationResult } from './domain/entities/ValidationResult';
|
|
10
|
-
export { validateEmail, validatePassword, validatePasswordConfirmation, validateRequired, validateName, validatePhone, validateNumberRange, validatePositiveNumber, validateMinLength, validateMaxLength, validatePattern, validateDateOfBirth, validateAge, batchValidate, } from './infrastructure/utils/validators';
|
|
11
|
-
export { SECURITY_LIMITS, sanitizeWhitespace, sanitizeEmail, sanitizePassword, sanitizeName, sanitizeText, containsDangerousChars, isWithinLengthLimit, } from './infrastructure/utils/sanitization';
|
package/lib/index.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @umituz/react-native-validation
|
|
4
|
-
*
|
|
5
|
-
* Comprehensive validation utilities for React Native forms.
|
|
6
|
-
* Provides reusable validation functions for common input types.
|
|
7
|
-
*
|
|
8
|
-
* @package react-native-validation
|
|
9
|
-
*/
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.isWithinLengthLimit = exports.containsDangerousChars = exports.sanitizeText = exports.sanitizeName = exports.sanitizePassword = exports.sanitizeEmail = exports.sanitizeWhitespace = exports.SECURITY_LIMITS = exports.batchValidate = exports.validateAge = exports.validateDateOfBirth = exports.validatePattern = exports.validateMaxLength = exports.validateMinLength = exports.validatePositiveNumber = exports.validateNumberRange = exports.validatePhone = exports.validateName = exports.validateRequired = exports.validatePasswordConfirmation = exports.validatePassword = exports.validateEmail = void 0;
|
|
12
|
-
// Infrastructure Layer - Validators
|
|
13
|
-
var validators_1 = require("./infrastructure/utils/validators");
|
|
14
|
-
Object.defineProperty(exports, "validateEmail", { enumerable: true, get: function () { return validators_1.validateEmail; } });
|
|
15
|
-
Object.defineProperty(exports, "validatePassword", { enumerable: true, get: function () { return validators_1.validatePassword; } });
|
|
16
|
-
Object.defineProperty(exports, "validatePasswordConfirmation", { enumerable: true, get: function () { return validators_1.validatePasswordConfirmation; } });
|
|
17
|
-
Object.defineProperty(exports, "validateRequired", { enumerable: true, get: function () { return validators_1.validateRequired; } });
|
|
18
|
-
Object.defineProperty(exports, "validateName", { enumerable: true, get: function () { return validators_1.validateName; } });
|
|
19
|
-
Object.defineProperty(exports, "validatePhone", { enumerable: true, get: function () { return validators_1.validatePhone; } });
|
|
20
|
-
Object.defineProperty(exports, "validateNumberRange", { enumerable: true, get: function () { return validators_1.validateNumberRange; } });
|
|
21
|
-
Object.defineProperty(exports, "validatePositiveNumber", { enumerable: true, get: function () { return validators_1.validatePositiveNumber; } });
|
|
22
|
-
Object.defineProperty(exports, "validateMinLength", { enumerable: true, get: function () { return validators_1.validateMinLength; } });
|
|
23
|
-
Object.defineProperty(exports, "validateMaxLength", { enumerable: true, get: function () { return validators_1.validateMaxLength; } });
|
|
24
|
-
Object.defineProperty(exports, "validatePattern", { enumerable: true, get: function () { return validators_1.validatePattern; } });
|
|
25
|
-
Object.defineProperty(exports, "validateDateOfBirth", { enumerable: true, get: function () { return validators_1.validateDateOfBirth; } });
|
|
26
|
-
Object.defineProperty(exports, "validateAge", { enumerable: true, get: function () { return validators_1.validateAge; } });
|
|
27
|
-
Object.defineProperty(exports, "batchValidate", { enumerable: true, get: function () { return validators_1.batchValidate; } });
|
|
28
|
-
// Infrastructure Layer - Sanitization
|
|
29
|
-
var sanitization_1 = require("./infrastructure/utils/sanitization");
|
|
30
|
-
Object.defineProperty(exports, "SECURITY_LIMITS", { enumerable: true, get: function () { return sanitization_1.SECURITY_LIMITS; } });
|
|
31
|
-
Object.defineProperty(exports, "sanitizeWhitespace", { enumerable: true, get: function () { return sanitization_1.sanitizeWhitespace; } });
|
|
32
|
-
Object.defineProperty(exports, "sanitizeEmail", { enumerable: true, get: function () { return sanitization_1.sanitizeEmail; } });
|
|
33
|
-
Object.defineProperty(exports, "sanitizePassword", { enumerable: true, get: function () { return sanitization_1.sanitizePassword; } });
|
|
34
|
-
Object.defineProperty(exports, "sanitizeName", { enumerable: true, get: function () { return sanitization_1.sanitizeName; } });
|
|
35
|
-
Object.defineProperty(exports, "sanitizeText", { enumerable: true, get: function () { return sanitization_1.sanitizeText; } });
|
|
36
|
-
Object.defineProperty(exports, "containsDangerousChars", { enumerable: true, get: function () { return sanitization_1.containsDangerousChars; } });
|
|
37
|
-
Object.defineProperty(exports, "isWithinLengthLimit", { enumerable: true, get: function () { return sanitization_1.isWithinLengthLimit; } });
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sanitization Utilities
|
|
3
|
-
* Secure input cleaning for user data
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Security constants for input validation
|
|
7
|
-
*/
|
|
8
|
-
export declare const SECURITY_LIMITS: {
|
|
9
|
-
readonly EMAIL_MAX_LENGTH: 254;
|
|
10
|
-
readonly PASSWORD_MIN_LENGTH: 6;
|
|
11
|
-
readonly PASSWORD_MAX_LENGTH: 128;
|
|
12
|
-
readonly NAME_MAX_LENGTH: 100;
|
|
13
|
-
readonly GENERAL_TEXT_MAX_LENGTH: 500;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Trim and normalize whitespace
|
|
17
|
-
*/
|
|
18
|
-
export declare const sanitizeWhitespace: (input: string) => string;
|
|
19
|
-
/**
|
|
20
|
-
* Sanitize email address
|
|
21
|
-
* - Trim whitespace
|
|
22
|
-
* - Convert to lowercase
|
|
23
|
-
* - Limit length
|
|
24
|
-
*/
|
|
25
|
-
export declare const sanitizeEmail: (email: string) => string;
|
|
26
|
-
/**
|
|
27
|
-
* Sanitize password
|
|
28
|
-
* - Only trim (preserve case and special chars)
|
|
29
|
-
* - Limit length to prevent DoS
|
|
30
|
-
*/
|
|
31
|
-
export declare const sanitizePassword: (password: string) => string;
|
|
32
|
-
/**
|
|
33
|
-
* Sanitize display name
|
|
34
|
-
* - Trim whitespace
|
|
35
|
-
* - Normalize multiple spaces
|
|
36
|
-
* - Remove potential XSS characters
|
|
37
|
-
* - Limit length
|
|
38
|
-
*/
|
|
39
|
-
export declare const sanitizeName: (name: string) => string;
|
|
40
|
-
/**
|
|
41
|
-
* Sanitize general text input
|
|
42
|
-
* - Trim whitespace
|
|
43
|
-
* - Remove HTML/script tags
|
|
44
|
-
* - Limit length
|
|
45
|
-
*/
|
|
46
|
-
export declare const sanitizeText: (text: string) => string;
|
|
47
|
-
/**
|
|
48
|
-
* Check if string contains potentially dangerous characters
|
|
49
|
-
*/
|
|
50
|
-
export declare const containsDangerousChars: (input: string) => boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Validate string length is within bounds
|
|
53
|
-
*/
|
|
54
|
-
export declare const isWithinLengthLimit: (input: string, maxLength: number, minLength?: number) => boolean;
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Sanitization Utilities
|
|
4
|
-
* Secure input cleaning for user data
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.isWithinLengthLimit = exports.containsDangerousChars = exports.sanitizeText = exports.sanitizeName = exports.sanitizePassword = exports.sanitizeEmail = exports.sanitizeWhitespace = exports.SECURITY_LIMITS = void 0;
|
|
8
|
-
/**
|
|
9
|
-
* Security constants for input validation
|
|
10
|
-
*/
|
|
11
|
-
exports.SECURITY_LIMITS = {
|
|
12
|
-
EMAIL_MAX_LENGTH: 254, // RFC 5321
|
|
13
|
-
PASSWORD_MIN_LENGTH: 6,
|
|
14
|
-
PASSWORD_MAX_LENGTH: 128,
|
|
15
|
-
NAME_MAX_LENGTH: 100,
|
|
16
|
-
GENERAL_TEXT_MAX_LENGTH: 500,
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Trim and normalize whitespace
|
|
20
|
-
*/
|
|
21
|
-
const sanitizeWhitespace = (input) => {
|
|
22
|
-
return input.trim().replace(/\s+/g, ' ');
|
|
23
|
-
};
|
|
24
|
-
exports.sanitizeWhitespace = sanitizeWhitespace;
|
|
25
|
-
/**
|
|
26
|
-
* Sanitize email address
|
|
27
|
-
* - Trim whitespace
|
|
28
|
-
* - Convert to lowercase
|
|
29
|
-
* - Limit length
|
|
30
|
-
*/
|
|
31
|
-
const sanitizeEmail = (email) => {
|
|
32
|
-
const trimmed = email.trim().toLowerCase();
|
|
33
|
-
return trimmed.substring(0, exports.SECURITY_LIMITS.EMAIL_MAX_LENGTH);
|
|
34
|
-
};
|
|
35
|
-
exports.sanitizeEmail = sanitizeEmail;
|
|
36
|
-
/**
|
|
37
|
-
* Sanitize password
|
|
38
|
-
* - Only trim (preserve case and special chars)
|
|
39
|
-
* - Limit length to prevent DoS
|
|
40
|
-
*/
|
|
41
|
-
const sanitizePassword = (password) => {
|
|
42
|
-
// Don't trim password to preserve intentional spaces
|
|
43
|
-
// Only limit length
|
|
44
|
-
return password.substring(0, exports.SECURITY_LIMITS.PASSWORD_MAX_LENGTH);
|
|
45
|
-
};
|
|
46
|
-
exports.sanitizePassword = sanitizePassword;
|
|
47
|
-
/**
|
|
48
|
-
* Sanitize display name
|
|
49
|
-
* - Trim whitespace
|
|
50
|
-
* - Normalize multiple spaces
|
|
51
|
-
* - Remove potential XSS characters
|
|
52
|
-
* - Limit length
|
|
53
|
-
*/
|
|
54
|
-
const sanitizeName = (name) => {
|
|
55
|
-
const trimmed = (0, exports.sanitizeWhitespace)(name);
|
|
56
|
-
// Remove HTML tags and script content
|
|
57
|
-
const noTags = trimmed.replace(/<[^>]*>/g, '');
|
|
58
|
-
return noTags.substring(0, exports.SECURITY_LIMITS.NAME_MAX_LENGTH);
|
|
59
|
-
};
|
|
60
|
-
exports.sanitizeName = sanitizeName;
|
|
61
|
-
/**
|
|
62
|
-
* Sanitize general text input
|
|
63
|
-
* - Trim whitespace
|
|
64
|
-
* - Remove HTML/script tags
|
|
65
|
-
* - Limit length
|
|
66
|
-
*/
|
|
67
|
-
const sanitizeText = (text) => {
|
|
68
|
-
const trimmed = (0, exports.sanitizeWhitespace)(text);
|
|
69
|
-
const noTags = trimmed.replace(/<[^>]*>/g, '');
|
|
70
|
-
return noTags.substring(0, exports.SECURITY_LIMITS.GENERAL_TEXT_MAX_LENGTH);
|
|
71
|
-
};
|
|
72
|
-
exports.sanitizeText = sanitizeText;
|
|
73
|
-
/**
|
|
74
|
-
* Check if string contains potentially dangerous characters
|
|
75
|
-
*/
|
|
76
|
-
const containsDangerousChars = (input) => {
|
|
77
|
-
// Check for common XSS patterns
|
|
78
|
-
const dangerousPatterns = [
|
|
79
|
-
/<script/i,
|
|
80
|
-
/javascript:/i,
|
|
81
|
-
/on\w+\s*=/i, // onclick, onload, etc.
|
|
82
|
-
/<iframe/i,
|
|
83
|
-
/eval\(/i,
|
|
84
|
-
];
|
|
85
|
-
return dangerousPatterns.some(pattern => pattern.test(input));
|
|
86
|
-
};
|
|
87
|
-
exports.containsDangerousChars = containsDangerousChars;
|
|
88
|
-
/**
|
|
89
|
-
* Validate string length is within bounds
|
|
90
|
-
*/
|
|
91
|
-
const isWithinLengthLimit = (input, maxLength, minLength = 0) => {
|
|
92
|
-
const length = input.trim().length;
|
|
93
|
-
return length >= minLength && length <= maxLength;
|
|
94
|
-
};
|
|
95
|
-
exports.isWithinLengthLimit = isWithinLengthLimit;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validation Utilities
|
|
3
|
-
* Comprehensive validation functions for React Native forms
|
|
4
|
-
*/
|
|
5
|
-
import type { ValidationResult } from '../../domain/entities/ValidationResult';
|
|
6
|
-
/**
|
|
7
|
-
* Validate email format
|
|
8
|
-
*/
|
|
9
|
-
export declare const validateEmail: (email: string) => ValidationResult;
|
|
10
|
-
/**
|
|
11
|
-
* Validate password strength
|
|
12
|
-
* @param password - Password to validate
|
|
13
|
-
* @param minLength - Minimum password length (default: 8)
|
|
14
|
-
* @param requireUppercase - Require uppercase letter (default: true)
|
|
15
|
-
* @param requireLowercase - Require lowercase letter (default: true)
|
|
16
|
-
* @param requireNumber - Require number (default: true)
|
|
17
|
-
*/
|
|
18
|
-
export declare const validatePassword: (password: string, options?: {
|
|
19
|
-
minLength?: number;
|
|
20
|
-
requireUppercase?: boolean;
|
|
21
|
-
requireLowercase?: boolean;
|
|
22
|
-
requireNumber?: boolean;
|
|
23
|
-
}) => ValidationResult;
|
|
24
|
-
/**
|
|
25
|
-
* Validate password confirmation
|
|
26
|
-
*/
|
|
27
|
-
export declare const validatePasswordConfirmation: (password: string, confirmPassword: string) => ValidationResult;
|
|
28
|
-
/**
|
|
29
|
-
* Validate required field
|
|
30
|
-
*/
|
|
31
|
-
export declare const validateRequired: (value: string, fieldName?: string) => ValidationResult;
|
|
32
|
-
/**
|
|
33
|
-
* Validate name
|
|
34
|
-
*/
|
|
35
|
-
export declare const validateName: (name: string, fieldName?: string, minLength?: number) => ValidationResult;
|
|
36
|
-
/**
|
|
37
|
-
* Validate phone number (E.164 format)
|
|
38
|
-
*/
|
|
39
|
-
export declare const validatePhone: (phone: string) => ValidationResult;
|
|
40
|
-
/**
|
|
41
|
-
* Validate number range
|
|
42
|
-
*/
|
|
43
|
-
export declare const validateNumberRange: (value: number, min: number, max: number, fieldName?: string) => ValidationResult;
|
|
44
|
-
/**
|
|
45
|
-
* Validate positive number
|
|
46
|
-
*/
|
|
47
|
-
export declare const validatePositiveNumber: (value: number, fieldName?: string) => ValidationResult;
|
|
48
|
-
/**
|
|
49
|
-
* Validate min length
|
|
50
|
-
*/
|
|
51
|
-
export declare const validateMinLength: (value: string, minLength: number, fieldName?: string) => ValidationResult;
|
|
52
|
-
/**
|
|
53
|
-
* Validate max length
|
|
54
|
-
*/
|
|
55
|
-
export declare const validateMaxLength: (value: string, maxLength: number, fieldName?: string) => ValidationResult;
|
|
56
|
-
/**
|
|
57
|
-
* Validate pattern (regex)
|
|
58
|
-
*/
|
|
59
|
-
export declare const validatePattern: (value: string, pattern: RegExp, fieldName?: string, errorMessage?: string) => ValidationResult;
|
|
60
|
-
/**
|
|
61
|
-
* Validate date of birth
|
|
62
|
-
*/
|
|
63
|
-
export declare const validateDateOfBirth: (date: Date) => ValidationResult;
|
|
64
|
-
/**
|
|
65
|
-
* Validate age
|
|
66
|
-
*/
|
|
67
|
-
export declare const validateAge: (age: number) => ValidationResult;
|
|
68
|
-
/**
|
|
69
|
-
* Batch validation
|
|
70
|
-
* Validates multiple fields and returns all errors
|
|
71
|
-
*/
|
|
72
|
-
export declare const batchValidate: (validations: Array<{
|
|
73
|
-
field: string;
|
|
74
|
-
validator: () => ValidationResult;
|
|
75
|
-
}>) => {
|
|
76
|
-
isValid: boolean;
|
|
77
|
-
errors: Record<string, string>;
|
|
78
|
-
};
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Validation Utilities
|
|
4
|
-
* Comprehensive validation functions for React Native forms
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.batchValidate = exports.validateAge = exports.validateDateOfBirth = exports.validatePattern = exports.validateMaxLength = exports.validateMinLength = exports.validatePositiveNumber = exports.validateNumberRange = exports.validatePhone = exports.validateName = exports.validateRequired = exports.validatePasswordConfirmation = exports.validatePassword = exports.validateEmail = void 0;
|
|
8
|
-
/**
|
|
9
|
-
* Validate email format
|
|
10
|
-
*/
|
|
11
|
-
const validateEmail = (email) => {
|
|
12
|
-
if (!email || email.trim() === '') {
|
|
13
|
-
return { isValid: false, error: 'Email is required' };
|
|
14
|
-
}
|
|
15
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
16
|
-
if (!emailRegex.test(email)) {
|
|
17
|
-
return { isValid: false, error: 'Please enter a valid email address' };
|
|
18
|
-
}
|
|
19
|
-
return { isValid: true };
|
|
20
|
-
};
|
|
21
|
-
exports.validateEmail = validateEmail;
|
|
22
|
-
/**
|
|
23
|
-
* Validate password strength
|
|
24
|
-
* @param password - Password to validate
|
|
25
|
-
* @param minLength - Minimum password length (default: 8)
|
|
26
|
-
* @param requireUppercase - Require uppercase letter (default: true)
|
|
27
|
-
* @param requireLowercase - Require lowercase letter (default: true)
|
|
28
|
-
* @param requireNumber - Require number (default: true)
|
|
29
|
-
*/
|
|
30
|
-
const validatePassword = (password, options) => {
|
|
31
|
-
const { minLength = 8, requireUppercase = true, requireLowercase = true, requireNumber = true, } = options || {};
|
|
32
|
-
if (!password || password.trim() === '') {
|
|
33
|
-
return { isValid: false, error: 'Password is required' };
|
|
34
|
-
}
|
|
35
|
-
if (password.length < minLength) {
|
|
36
|
-
return {
|
|
37
|
-
isValid: false,
|
|
38
|
-
error: `Password must be at least ${minLength} characters`,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
if (requireUppercase && !/[A-Z]/.test(password)) {
|
|
42
|
-
return {
|
|
43
|
-
isValid: false,
|
|
44
|
-
error: 'Password must contain at least one uppercase letter',
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
if (requireLowercase && !/[a-z]/.test(password)) {
|
|
48
|
-
return {
|
|
49
|
-
isValid: false,
|
|
50
|
-
error: 'Password must contain at least one lowercase letter',
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
if (requireNumber && !/[0-9]/.test(password)) {
|
|
54
|
-
return {
|
|
55
|
-
isValid: false,
|
|
56
|
-
error: 'Password must contain at least one number',
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
return { isValid: true };
|
|
60
|
-
};
|
|
61
|
-
exports.validatePassword = validatePassword;
|
|
62
|
-
/**
|
|
63
|
-
* Validate password confirmation
|
|
64
|
-
*/
|
|
65
|
-
const validatePasswordConfirmation = (password, confirmPassword) => {
|
|
66
|
-
if (!confirmPassword) {
|
|
67
|
-
return { isValid: false, error: 'Please confirm your password' };
|
|
68
|
-
}
|
|
69
|
-
if (password !== confirmPassword) {
|
|
70
|
-
return { isValid: false, error: 'Passwords do not match' };
|
|
71
|
-
}
|
|
72
|
-
return { isValid: true };
|
|
73
|
-
};
|
|
74
|
-
exports.validatePasswordConfirmation = validatePasswordConfirmation;
|
|
75
|
-
/**
|
|
76
|
-
* Validate required field
|
|
77
|
-
*/
|
|
78
|
-
const validateRequired = (value, fieldName = 'This field') => {
|
|
79
|
-
if (!value || value.trim() === '') {
|
|
80
|
-
return { isValid: false, error: `${fieldName} is required` };
|
|
81
|
-
}
|
|
82
|
-
return { isValid: true };
|
|
83
|
-
};
|
|
84
|
-
exports.validateRequired = validateRequired;
|
|
85
|
-
/**
|
|
86
|
-
* Validate name
|
|
87
|
-
*/
|
|
88
|
-
const validateName = (name, fieldName = 'Name', minLength = 2) => {
|
|
89
|
-
if (!name || name.trim() === '') {
|
|
90
|
-
return { isValid: false, error: `${fieldName} is required` };
|
|
91
|
-
}
|
|
92
|
-
if (name.trim().length < minLength) {
|
|
93
|
-
return {
|
|
94
|
-
isValid: false,
|
|
95
|
-
error: `${fieldName} must be at least ${minLength} characters`,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
return { isValid: true };
|
|
99
|
-
};
|
|
100
|
-
exports.validateName = validateName;
|
|
101
|
-
/**
|
|
102
|
-
* Validate phone number (E.164 format)
|
|
103
|
-
*/
|
|
104
|
-
const validatePhone = (phone) => {
|
|
105
|
-
if (!phone || phone.trim() === '') {
|
|
106
|
-
return { isValid: false, error: 'Phone number is required' };
|
|
107
|
-
}
|
|
108
|
-
const phoneRegex = /^\+[1-9]\d{1,14}$/;
|
|
109
|
-
if (!phoneRegex.test(phone)) {
|
|
110
|
-
return { isValid: false, error: 'Please enter a valid phone number' };
|
|
111
|
-
}
|
|
112
|
-
return { isValid: true };
|
|
113
|
-
};
|
|
114
|
-
exports.validatePhone = validatePhone;
|
|
115
|
-
/**
|
|
116
|
-
* Validate number range
|
|
117
|
-
*/
|
|
118
|
-
const validateNumberRange = (value, min, max, fieldName = 'Value') => {
|
|
119
|
-
if (isNaN(value)) {
|
|
120
|
-
return { isValid: false, error: `${fieldName} must be a number` };
|
|
121
|
-
}
|
|
122
|
-
if (value < min || value > max) {
|
|
123
|
-
return {
|
|
124
|
-
isValid: false,
|
|
125
|
-
error: `${fieldName} must be between ${min} and ${max}`,
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
return { isValid: true };
|
|
129
|
-
};
|
|
130
|
-
exports.validateNumberRange = validateNumberRange;
|
|
131
|
-
/**
|
|
132
|
-
* Validate positive number
|
|
133
|
-
*/
|
|
134
|
-
const validatePositiveNumber = (value, fieldName = 'Value') => {
|
|
135
|
-
if (isNaN(value)) {
|
|
136
|
-
return { isValid: false, error: `${fieldName} must be a number` };
|
|
137
|
-
}
|
|
138
|
-
if (value <= 0) {
|
|
139
|
-
return { isValid: false, error: `${fieldName} must be greater than 0` };
|
|
140
|
-
}
|
|
141
|
-
return { isValid: true };
|
|
142
|
-
};
|
|
143
|
-
exports.validatePositiveNumber = validatePositiveNumber;
|
|
144
|
-
/**
|
|
145
|
-
* Validate min length
|
|
146
|
-
*/
|
|
147
|
-
const validateMinLength = (value, minLength, fieldName = 'Field') => {
|
|
148
|
-
if (!value || value.trim().length < minLength) {
|
|
149
|
-
return {
|
|
150
|
-
isValid: false,
|
|
151
|
-
error: `${fieldName} must be at least ${minLength} characters`,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
return { isValid: true };
|
|
155
|
-
};
|
|
156
|
-
exports.validateMinLength = validateMinLength;
|
|
157
|
-
/**
|
|
158
|
-
* Validate max length
|
|
159
|
-
*/
|
|
160
|
-
const validateMaxLength = (value, maxLength, fieldName = 'Field') => {
|
|
161
|
-
if (value && value.trim().length > maxLength) {
|
|
162
|
-
return {
|
|
163
|
-
isValid: false,
|
|
164
|
-
error: `${fieldName} must be at most ${maxLength} characters`,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
return { isValid: true };
|
|
168
|
-
};
|
|
169
|
-
exports.validateMaxLength = validateMaxLength;
|
|
170
|
-
/**
|
|
171
|
-
* Validate pattern (regex)
|
|
172
|
-
*/
|
|
173
|
-
const validatePattern = (value, pattern, fieldName = 'Field', errorMessage) => {
|
|
174
|
-
if (!value) {
|
|
175
|
-
return { isValid: false, error: `${fieldName} is required` };
|
|
176
|
-
}
|
|
177
|
-
if (!pattern.test(value)) {
|
|
178
|
-
return {
|
|
179
|
-
isValid: false,
|
|
180
|
-
error: errorMessage || `${fieldName} format is invalid`,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
return { isValid: true };
|
|
184
|
-
};
|
|
185
|
-
exports.validatePattern = validatePattern;
|
|
186
|
-
/**
|
|
187
|
-
* Validate date of birth
|
|
188
|
-
*/
|
|
189
|
-
const validateDateOfBirth = (date) => {
|
|
190
|
-
if (!date || !(date instanceof Date) || isNaN(date.getTime())) {
|
|
191
|
-
return { isValid: false, error: 'Please enter a valid date' };
|
|
192
|
-
}
|
|
193
|
-
const today = new Date();
|
|
194
|
-
const age = today.getFullYear() - date.getFullYear();
|
|
195
|
-
if (age < 13) {
|
|
196
|
-
return { isValid: false, error: 'You must be at least 13 years old' };
|
|
197
|
-
}
|
|
198
|
-
if (age > 120) {
|
|
199
|
-
return { isValid: false, error: 'Please enter a valid date of birth' };
|
|
200
|
-
}
|
|
201
|
-
return { isValid: true };
|
|
202
|
-
};
|
|
203
|
-
exports.validateDateOfBirth = validateDateOfBirth;
|
|
204
|
-
/**
|
|
205
|
-
* Validate age
|
|
206
|
-
*/
|
|
207
|
-
const validateAge = (age) => {
|
|
208
|
-
return (0, exports.validateNumberRange)(age, 13, 120, 'Age');
|
|
209
|
-
};
|
|
210
|
-
exports.validateAge = validateAge;
|
|
211
|
-
/**
|
|
212
|
-
* Batch validation
|
|
213
|
-
* Validates multiple fields and returns all errors
|
|
214
|
-
*/
|
|
215
|
-
const batchValidate = (validations) => {
|
|
216
|
-
const errors = {};
|
|
217
|
-
let isValid = true;
|
|
218
|
-
validations.forEach(({ field, validator }) => {
|
|
219
|
-
const result = validator();
|
|
220
|
-
if (!result.isValid && result.error) {
|
|
221
|
-
errors[field] = result.error;
|
|
222
|
-
isValid = false;
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
return { isValid, errors };
|
|
226
|
-
};
|
|
227
|
-
exports.batchValidate = batchValidate;
|