quantique-field-validator 1.0.2-Beta → 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.
@@ -12,6 +12,8 @@ const defaultErrorMessages = (rules, type) => {
12
12
  noValidation: `No validation exist for ${type}`,
13
13
  custom: "Validation failed",
14
14
  Alphanumeric: "value must be alphanumecric",
15
+ chassisNumber: "valid chassis number",
16
+ engineNumber: "valid engine number",
15
17
  customValidation:
16
18
  rules.errorMessages?.customValidation || "Custom validation failed",
17
19
  };
@@ -0,0 +1,36 @@
1
+ // ChassisNumber validation
2
+ const validateChassisNumber = (value, rules, defaultErrorMessages, type) => {
3
+ if (rules?.minLength && value?.length < rules?.minLength) {
4
+ return {
5
+ isValid: false,
6
+ error:
7
+ rules?.errorMessages?.minLength ||
8
+ defaultErrorMessages(rules, type).minLength,
9
+ };
10
+ }
11
+
12
+ if (rules?.maxLength && value?.length > rules?.maxLength) {
13
+ return {
14
+ isValid: false,
15
+ error:
16
+ rules?.errorMessages?.maxLength ||
17
+ defaultErrorMessages(rules, type).maxLength,
18
+ };
19
+ }
20
+
21
+ const defaultRegex = /^[A-HJ-NPR-Z0-9]{17}$/;
22
+ const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultRegex;
23
+
24
+ if (!regexToUse.test(value)) {
25
+ return {
26
+ isValid: false,
27
+ error:
28
+ defaultErrorMessages(rules, type).chassisNumber ||
29
+ defaultErrorMessages(rules, type).invalid,
30
+ };
31
+ }
32
+
33
+ return { isValid: true, error: "" };
34
+ };
35
+
36
+ module.exports = validateChassisNumber;
@@ -1,24 +1,13 @@
1
- const validateAadhaar = (
2
- value,
3
- rules,
4
- defaultErrorMessages,
5
- type
6
-
7
- ) => {
1
+ const validateAadhaar = (value, rules, defaultErrorMessages, type) => {
8
2
  const defaultRules = {
9
- regex: /^[2-9]{1}[0-9]{11}$/,
3
+ regex: /^[2-9]{1}[0-9]{11}$/,
10
4
  };
11
5
  const effectiveRules = {
12
6
  ...defaultRules,
13
7
  ...rules,
14
8
  };
15
9
 
16
-
17
-
18
- if (
19
- effectiveRules?.regex &&
20
- !new RegExp(effectiveRules?.regex).test(value)
21
- ) {
10
+ if (effectiveRules?.regex && !new RegExp(effectiveRules?.regex).test(value)) {
22
11
  return {
23
12
  isValid: false,
24
13
  error:
@@ -1,4 +1,18 @@
1
1
  // Date validation
2
+
3
+ // {
4
+ // minAge: 18,
5
+ // maxAge: 65,
6
+ // minPlus: 2,
7
+ // maxPlus: 30,
8
+ // minMinus: 5,
9
+ // maxMinus: 365,
10
+ // unit: "month", // or "day" or "year"
11
+ // errorMessages: {
12
+ // minPlus: "Date must be at least 2 months ahead!",
13
+ // }
14
+ // }
15
+
2
16
  const validateDate = (
3
17
  value,
4
18
  rules = { format: "DD/MM/YYYY" },
@@ -26,6 +40,27 @@ const validateDate = (
26
40
  return new Date(year, month, day);
27
41
  };
28
42
 
43
+ const applyOffset = (baseDate, value, unit, operation = "add") => {
44
+ const date = new Date(baseDate);
45
+ const multiplier = operation === "subtract" ? -1 : 1;
46
+
47
+ switch (unit) {
48
+ case "month":
49
+ case "months":
50
+ date.setMonth(date.getMonth() + value * multiplier);
51
+ break;
52
+ case "year":
53
+ case "years":
54
+ date.setFullYear(date.getFullYear() + value * multiplier);
55
+ break;
56
+ default:
57
+ date.setDate(date.getDate() + value * multiplier);
58
+ break;
59
+ }
60
+
61
+ return date;
62
+ };
63
+
29
64
  const parsedDate = parseDateByFormat(value, rules?.format);
30
65
  const today = new Date();
31
66
  today.setHours(0, 0, 0, 0); // Normalize for accurate comparisons
@@ -40,11 +75,11 @@ const validateDate = (
40
75
  };
41
76
  }
42
77
 
43
- // Age check (e.g., user must be 18+)
78
+ // Age check (minAge)
44
79
  if (rules?.minAge) {
45
- const ageDate = new Date();
46
- ageDate.setFullYear(ageDate.getFullYear() - rules.minAge);
47
- if (parsedDate > ageDate) {
80
+ const minAgeDate = new Date();
81
+ minAgeDate.setFullYear(minAgeDate.getFullYear() - rules.minAge);
82
+ if (parsedDate > minAgeDate) {
48
83
  return {
49
84
  isValid: false,
50
85
  error:
@@ -55,59 +90,72 @@ const validateDate = (
55
90
  }
56
91
  }
57
92
 
58
- // Relative date checks
93
+ // Age check (maxAge)
94
+ if (rules?.maxAge) {
95
+ const maxAgeDate = new Date();
96
+ maxAgeDate.setFullYear(maxAgeDate.getFullYear() - rules.maxAge);
97
+ if (parsedDate < maxAgeDate) {
98
+ return {
99
+ isValid: false,
100
+ error:
101
+ rules?.errorMessages?.maxAge ||
102
+ defaultErrorMessages(rules, type)?.maxAge ||
103
+ `You must be at most ${rules.maxAge} years old`,
104
+ };
105
+ }
106
+ }
107
+
108
+ // Handle relative rules with units (default to "day")
109
+ const unit = rules?.unit || "day";
110
+
59
111
  if (rules?.minMinus) {
60
- const minPast = new Date(today);
61
- minPast.setDate(minPast.getDate() - rules.minMinus);
112
+ const minPast = applyOffset(today, rules.minMinus, unit, "subtract");
62
113
  if (parsedDate < minPast) {
63
114
  return {
64
115
  isValid: false,
65
116
  error:
66
117
  rules?.errorMessages?.minMinus ||
67
118
  defaultErrorMessages(rules, type)?.minMinus ||
68
- `Date should not be earlier than ${rules.minMinus} days ago`,
119
+ `Date should not be earlier than ${rules.minMinus} ${unit}(s) ago`,
69
120
  };
70
121
  }
71
122
  }
72
123
 
73
124
  if (rules?.maxPlus) {
74
- const maxFuture = new Date(today);
75
- maxFuture.setDate(maxFuture.getDate() + rules.maxPlus);
125
+ const maxFuture = applyOffset(today, rules.maxPlus, unit, "add");
76
126
  if (parsedDate > maxFuture) {
77
127
  return {
78
128
  isValid: false,
79
129
  error:
80
130
  rules?.errorMessages?.maxPlus ||
81
131
  defaultErrorMessages(rules, type)?.maxPlus ||
82
- `Date should not be more than ${rules.maxPlus} days in the future`,
132
+ `Date should not be more than ${rules.maxPlus} ${unit}(s) in the future`,
83
133
  };
84
134
  }
85
135
  }
86
136
 
87
137
  if (rules?.minPlus) {
88
- const minFuture = new Date(today);
89
- minFuture.setDate(minFuture.getDate() + rules.minPlus);
138
+ const minFuture = applyOffset(today, rules.minPlus, unit, "add");
90
139
  if (parsedDate < minFuture) {
91
140
  return {
92
141
  isValid: false,
93
142
  error:
94
143
  rules?.errorMessages?.minPlus ||
95
144
  defaultErrorMessages(rules, type)?.minPlus ||
96
- `Date should be at least ${rules.minPlus} days in the future`,
145
+ `Date should be at least ${rules.minPlus} ${unit}(s) in the future`,
97
146
  };
98
147
  }
99
148
  }
100
149
 
101
150
  if (rules?.maxMinus) {
102
- const maxPast = new Date(today);
103
- maxPast.setDate(maxPast.getDate() - rules.maxMinus);
151
+ const maxPast = applyOffset(today, rules.maxMinus, unit, "subtract");
104
152
  if (parsedDate > maxPast) {
105
153
  return {
106
154
  isValid: false,
107
155
  error:
108
156
  rules?.errorMessages?.maxMinus ||
109
157
  defaultErrorMessages(rules, type)?.maxMinus ||
110
- `Date should not be later than ${rules.maxMinus} days ago`,
158
+ `Date should not be later than ${rules.maxMinus} ${unit}(s) ago`,
111
159
  };
112
160
  }
113
161
  }
@@ -20,7 +20,8 @@ const validateEmail = (value, rules, defaultErrorMessages, type) => {
20
20
  }
21
21
 
22
22
  // Check against custom regex if provided
23
- const defaultRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
23
+ const defaultRegex =
24
+ /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}))$/;
24
25
  const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultRegex;
25
26
 
26
27
  if (!regexToUse.test(value)) {
@@ -0,0 +1,36 @@
1
+ // ChassisNumber validation
2
+ const validateEngineNumber = (value, rules, defaultErrorMessages, type) => {
3
+ if (rules?.minLength && value?.length < rules?.minLength) {
4
+ return {
5
+ isValid: false,
6
+ error:
7
+ rules?.errorMessages?.minLength ||
8
+ defaultErrorMessages(rules, type).minLength,
9
+ };
10
+ }
11
+
12
+ if (rules?.maxLength && value?.length > rules?.maxLength) {
13
+ return {
14
+ isValid: false,
15
+ error:
16
+ rules?.errorMessages?.maxLength ||
17
+ defaultErrorMessages(rules, type).maxLength,
18
+ };
19
+ }
20
+
21
+ const defaultRegex = /^[A-Za-z0-9.]{5,25}$/;
22
+ const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultRegex;
23
+
24
+ if (!regexToUse.test(value)) {
25
+ return {
26
+ isValid: false,
27
+ error:
28
+ defaultErrorMessages(rules, type).engineNumber ||
29
+ defaultErrorMessages(rules, type).invalid,
30
+ };
31
+ }
32
+
33
+ return { isValid: true, error: "" };
34
+ };
35
+
36
+ module.exports = validateEngineNumber;
@@ -0,0 +1,108 @@
1
+ // Float Number Validation with Precision Check
2
+
3
+ // const rules = {
4
+ // decimalPrecision: 2, // allow only 2 digits after decimal
5
+ // maxWholeDigits: 6, // allow up to 6 digits before decimal
6
+ // minValue: 0.01,
7
+ // maxValue: 999999.99,
8
+ // };
9
+
10
+ const validateFloatNumber = (value, rules, defaultErrorMessages, type) => {
11
+ // Reject if value contains spaces
12
+ if (/\s/.test(value)) {
13
+ return {
14
+ isValid: false,
15
+ error:
16
+ rules?.errorMessages?.invalid ||
17
+ defaultErrorMessages(rules, type).noSpace ||
18
+ defaultErrorMessages(rules, type).invalid,
19
+ };
20
+ }
21
+
22
+ // Default float regex (supports optional decimal)
23
+ const defaultFloatRegex = /^\d+(\.\d+)?$/;
24
+ const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultFloatRegex;
25
+
26
+ if (!regexToUse.test(value)) {
27
+ return {
28
+ isValid: false,
29
+ error:
30
+ rules?.errorMessages?.invalid ||
31
+ defaultErrorMessages(rules, type).invalid ||
32
+ "Please enter a valid amount (e.g., 123.45)",
33
+ };
34
+ }
35
+
36
+ const numberValue = Number(value);
37
+
38
+ // Decimal precision validation
39
+ if (rules?.decimalPrecision !== undefined) {
40
+ const decimalPart = value.split(".")[1];
41
+ const actualPrecision = decimalPart ? decimalPart.length : 0;
42
+ if (actualPrecision > rules.decimalPrecision) {
43
+ return {
44
+ isValid: false,
45
+ error:
46
+ rules?.errorMessages?.decimalPrecision ||
47
+ `Only up to ${rules.decimalPrecision} digits allowed after decimal.`,
48
+ };
49
+ }
50
+ }
51
+
52
+ // Whole number digit validation
53
+ if (rules?.maxWholeDigits !== undefined) {
54
+ const wholePart = value.split(".")[0];
55
+ if (wholePart.length > rules.maxWholeDigits) {
56
+ return {
57
+ isValid: false,
58
+ error:
59
+ rules?.errorMessages?.maxWholeDigits ||
60
+ `Only up to ${rules.maxWholeDigits} digits allowed before decimal.`,
61
+ };
62
+ }
63
+ }
64
+
65
+ // Length checks (on the full string)
66
+ if (rules?.minLength && value.length < rules.minLength) {
67
+ return {
68
+ isValid: false,
69
+ error:
70
+ rules?.errorMessages?.minLength ||
71
+ defaultErrorMessages(rules, type).minLength,
72
+ };
73
+ }
74
+
75
+ if (rules?.maxLength && value.length > rules.maxLength) {
76
+ return {
77
+ isValid: false,
78
+ error:
79
+ rules?.errorMessages?.maxLength ||
80
+ defaultErrorMessages(rules, type).maxLength,
81
+ };
82
+ }
83
+
84
+ // Value range checks
85
+ if (rules?.minValue !== undefined && numberValue < rules.minValue) {
86
+ return {
87
+ isValid: false,
88
+ error:
89
+ rules?.errorMessages?.minValue ||
90
+ defaultErrorMessages(rules, type).minValue ||
91
+ `Amount must be at least ${rules.minValue}`,
92
+ };
93
+ }
94
+
95
+ if (rules?.maxValue !== undefined && numberValue > rules.maxValue) {
96
+ return {
97
+ isValid: false,
98
+ error:
99
+ rules?.errorMessages?.maxValue ||
100
+ defaultErrorMessages(rules, type).maxValue ||
101
+ `Amount must not exceed ${rules.maxValue}`,
102
+ };
103
+ }
104
+
105
+ return { isValid: true, error: "" };
106
+ };
107
+
108
+ module.exports = validateFloatNumber;
@@ -11,8 +11,8 @@ const validateNumber = (value, rules, defaultErrorMessages, type) => {
11
11
  };
12
12
  }
13
13
 
14
- // Default numeric regex (supports optional decimal and negative)
15
- const defaultNumberRegex = /^-?\d+(\.\d+)?$/;
14
+ // Whole number only regex
15
+ const defaultNumberRegex = /^\d+$/;
16
16
  const regexToUse = rules?.regex
17
17
  ? new RegExp(rules.regex)
18
18
  : defaultNumberRegex;
@@ -23,7 +23,7 @@ const validateNumber = (value, rules, defaultErrorMessages, type) => {
23
23
  error:
24
24
  rules?.errorMessages?.invalid ||
25
25
  defaultErrorMessages(rules, type).invalid ||
26
- "Please enter a valid number",
26
+ "Please enter a valid whole number",
27
27
  };
28
28
  }
29
29
 
package/index.js CHANGED
@@ -11,6 +11,7 @@ const defaultErrorMessages = require("./Messages/defaultErrorMessages");
11
11
  const validateString = require("./Validators/validateString");
12
12
  const validateAlphanumeric = require("./Validators/validateAlphanumeric");
13
13
  const validateNumber = require("./Validators/validateNumber");
14
+ const validateFloatNumber = require("./Validators/validateFloatNumber");
14
15
  const validateDate = require("./Validators/validateDate");
15
16
  const validateName = require("./Validators/validateName");
16
17
  const validateEmail = require("./Validators/validateEmail");
@@ -20,15 +21,16 @@ const validatePassword = require("./Validators/validatePassword");
20
21
  const validateCustom = require("./Validators/validateCustom");
21
22
  const validateAadhaar = require("./Validators/validateAadhaar");
22
23
  const validatePanCard = require("./Validators/validatePanCard");
24
+ const validateChassisNumber = require("./Validators/ValidateChassisNumber");
23
25
 
24
26
  const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
25
27
  // Trim the value if it's a string
26
- // const trimmedValue = typeof value === "string" ? value.trim() : value;
28
+ // const selectedValue = typeof value === "string" ? value.trim() : value;
27
29
 
28
- const trimmedValue = value;
30
+ const selectedValue = value;
29
31
 
30
32
  // Check if field is required and empty
31
- if (rules.required && (!trimmedValue || trimmedValue === "")) {
33
+ if (rules.required && (!selectedValue || selectedValue === "")) {
32
34
  return {
33
35
  isValid: false,
34
36
  error:
@@ -38,13 +40,13 @@ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
38
40
  }
39
41
 
40
42
  // Skip further validation if the field is empty and not required
41
- if (!rules.required && (!trimmedValue || trimmedValue === "")) {
43
+ if (!rules.required && (!selectedValue || selectedValue === "")) {
42
44
  return { isValid: true, error: "" };
43
45
  }
44
46
 
45
47
  // First run custom validator if provided (highest priority)
46
48
  if (customValidator && typeof customValidator === "function") {
47
- const customValidation = customValidator(trimmedValue);
49
+ const customValidation = customValidator(selectedValue);
48
50
 
49
51
  if (
50
52
  typeof customValidation === "object" &&
@@ -67,7 +69,7 @@ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
67
69
 
68
70
  // Then run any custom validator in rules
69
71
  if (rules.customValidator && typeof rules.customValidator === "function") {
70
- const rulesCustomValidation = rules.customValidator(trimmedValue);
72
+ const rulesCustomValidation = rules.customValidator(selectedValue);
71
73
 
72
74
  if (
73
75
  typeof rulesCustomValidation === "object" &&
@@ -90,35 +92,49 @@ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
90
92
  // Then validate based on type
91
93
  switch (type) {
92
94
  case "string":
93
- return validateString(trimmedValue, rules, defaultErrorMessages, type);
95
+ return validateString(selectedValue, rules, defaultErrorMessages, type);
94
96
  case "alphanumeric":
95
97
  return validateAlphanumeric(
96
- trimmedValue,
98
+ selectedValue,
97
99
  rules,
98
100
  defaultErrorMessages,
99
101
  type
100
102
  );
101
103
  case "number":
102
- return validateNumber(trimmedValue, rules, defaultErrorMessages, type);
104
+ return validateNumber(selectedValue, rules, defaultErrorMessages, type);
105
+ case "float":
106
+ return validateFloatNumber(
107
+ selectedValue,
108
+ rules,
109
+ defaultErrorMessages,
110
+ type
111
+ );
103
112
  case "date":
104
- return validateDate(trimmedValue, rules, defaultErrorMessages, type);
113
+ return validateDate(selectedValue, rules, defaultErrorMessages, type);
105
114
  case "name":
106
115
  return validateName(trimmedValue, rules, defaultErrorMessages, type);
107
- case "aadhaar":
108
- return validateAadhaar(trimmedValue, rules, defaultErrorMessages, type);
109
- case "pan":
110
- return validatePanCard(trimmedValue, rules, defaultErrorMessages, type);
111
-
112
116
  case "email":
113
- return validateEmail(trimmedValue, rules, defaultErrorMessages, type);
117
+ return validateEmail(selectedValue, rules, defaultErrorMessages, type);
114
118
  case "mobile":
115
- return validateMobile(trimmedValue, rules, defaultErrorMessages, type);
119
+ return validateMobile(selectedValue, rules, defaultErrorMessages, type);
116
120
  case "address":
117
- return validateAddress(trimmedValue, rules, defaultErrorMessages, type);
121
+ return validateAddress(selectedValue, rules, defaultErrorMessages, type);
118
122
  case "password":
119
123
  return validatePassword(trimmedValue, rules, defaultErrorMessages, type);
124
+ case "chassis":
125
+ return validateChassisNumber(
126
+ trimmedValue,
127
+ rules,
128
+ defaultErrorMessages,
129
+ type
130
+ );
131
+ return validatePassword(selectedValue, rules, defaultErrorMessages, type);
132
+ case "aadhaar":
133
+ return validateAadhaar(selectedValue, rules, defaultErrorMessages, type);
134
+ case "pan":
135
+ return validatePanCard(selectedValue, rules, defaultErrorMessages, type);
120
136
  case "custom":
121
- return validateCustom(trimmedValue, rules, defaultErrorMessages, type);
137
+ return validateCustom(selectedValue, rules, defaultErrorMessages, type);
122
138
  default:
123
139
  return {
124
140
  isValid: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quantique-field-validator",
3
- "version": "1.0.2Beta",
3
+ "version": "1.0.2",
4
4
  "description": "Validator to verify all form fields.",
5
5
  "main": "index.js",
6
6
  "scripts": {