quantique-field-validator 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.
@@ -0,0 +1,59 @@
1
+ // Name validation
2
+ const validateName = (
3
+ value,
4
+ rules = { type: "user" },
5
+ defaultErrorMessages,
6
+ type
7
+ ) => {
8
+ // Check length constraints
9
+ if (rules?.minLength && value?.length < rules?.minLength) {
10
+ return {
11
+ isValid: false,
12
+ error:
13
+ rules?.errorMessages?.minLength ||
14
+ defaultErrorMessages(rules, type).minLength,
15
+ };
16
+ }
17
+
18
+ if (rules?.maxLength && value?.length > rules?.maxLength) {
19
+ return {
20
+ isValid: false,
21
+ error:
22
+ rules?.errorMessages?.maxLength ||
23
+ defaultErrorMessages(rules, type).maxLength,
24
+ };
25
+ }
26
+
27
+ // Default name validation (only letters, spaces, and basic punctuation)
28
+ // Check against custom regex if provided
29
+ if (rules?.type === "user") {
30
+ const defaultRegex = /^[a-zA-ZÀ-ÿ\s'-.]*$/;
31
+ const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultRegex;
32
+
33
+ if (!regexToUse.test(value)) {
34
+ return {
35
+ isValid: false,
36
+ error:
37
+ rules?.errorMessages?.invalid || "Name contains invalid characters",
38
+ };
39
+ }
40
+ }
41
+
42
+ if (rules?.type === "corporate") {
43
+ const defaultRegex = /^[A-Za-z0-9&.,'()\- ]*$/;
44
+ const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultRegex;
45
+
46
+ if (!regexToUse.test(value)) {
47
+ return {
48
+ isValid: false,
49
+ error:
50
+ rules?.errorMessages?.invalid ||
51
+ "Corporate Name contains invalid characters",
52
+ };
53
+ }
54
+ }
55
+
56
+ return { isValid: true, error: "" };
57
+ };
58
+
59
+ module.exports = validateName;
@@ -0,0 +1,75 @@
1
+ // Number validation
2
+ const validateNumber = (value, rules, defaultErrorMessages, type) => {
3
+ // Reject if value contains spaces
4
+ if (/\s/.test(value)) {
5
+ return {
6
+ isValid: false,
7
+ error:
8
+ rules?.errorMessages?.invalid ||
9
+ defaultErrorMessages(rules, type).noSpace ||
10
+ defaultErrorMessages(rules, type).invalid,
11
+ };
12
+ }
13
+
14
+ // Whole number only regex
15
+ const defaultNumberRegex = /^\d+$/;
16
+ const regexToUse = rules?.regex
17
+ ? new RegExp(rules.regex)
18
+ : defaultNumberRegex;
19
+
20
+ if (!regexToUse.test(value)) {
21
+ return {
22
+ isValid: false,
23
+ error:
24
+ rules?.errorMessages?.invalid ||
25
+ defaultErrorMessages(rules, type).invalid ||
26
+ "Please enter a valid whole number",
27
+ };
28
+ }
29
+
30
+ const numberValue = Number(value);
31
+
32
+ // Length checks (on the string)
33
+ if (rules?.minLength && value.length < rules.minLength) {
34
+ return {
35
+ isValid: false,
36
+ error:
37
+ rules?.errorMessages?.minLength ||
38
+ defaultErrorMessages(rules, type).minLength,
39
+ };
40
+ }
41
+
42
+ if (rules?.maxLength && value.length > rules.maxLength) {
43
+ return {
44
+ isValid: false,
45
+ error:
46
+ rules?.errorMessages?.maxLength ||
47
+ defaultErrorMessages(rules, type).maxLength,
48
+ };
49
+ }
50
+
51
+ // Value range checks
52
+ if (rules?.minValue !== undefined && numberValue < rules.minValue) {
53
+ return {
54
+ isValid: false,
55
+ error:
56
+ rules?.errorMessages?.minValue ||
57
+ defaultErrorMessages(rules, type).minValue ||
58
+ `Value must be at least ${rules.minValue}`,
59
+ };
60
+ }
61
+
62
+ if (rules?.maxValue !== undefined && numberValue > rules.maxValue) {
63
+ return {
64
+ isValid: false,
65
+ error:
66
+ rules?.errorMessages?.maxValue ||
67
+ defaultErrorMessages(rules, type).maxValue ||
68
+ `Value must not exceed ${rules.maxValue}`,
69
+ };
70
+ }
71
+
72
+ return { isValid: true, error: "" };
73
+ };
74
+
75
+ module.exports = validateNumber;
@@ -0,0 +1,34 @@
1
+ const validatePanCard = (
2
+ value,
3
+ rules,
4
+ defaultErrorMessages,
5
+ type
6
+ ) => {
7
+ const defaultRules = {
8
+ regex: /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/,
9
+ };
10
+
11
+
12
+ const effectiveRules = {
13
+ ...defaultRules,
14
+ ...rules,
15
+ };
16
+
17
+
18
+
19
+ if (
20
+ effectiveRules?.regex &&
21
+ !new RegExp(effectiveRules?.regex).test(value)
22
+ ) {
23
+ return {
24
+ isValid: false,
25
+ error:
26
+ effectiveRules?.errorMessages?.invalid ||
27
+ defaultErrorMessages(effectiveRules, type).invalid,
28
+ };
29
+ }
30
+
31
+ return { isValid: true, error: "" };
32
+ };
33
+
34
+ module.exports = validatePanCard;
@@ -0,0 +1,38 @@
1
+ // Add password validation
2
+ const validatePassword = (value, rules, defaultErrorMessages, type) => {
3
+ // Check length constraints
4
+ if (rules?.minLength && value.length < rules?.minLength) {
5
+ return {
6
+ isValid: false,
7
+ error:
8
+ rules?.errorMessages?.minLength ||
9
+ defaultErrorMessages(rules, type).minLength,
10
+ };
11
+ }
12
+
13
+ if (rules?.maxLength && value.length > rules?.maxLength) {
14
+ return {
15
+ isValid: false,
16
+ error:
17
+ rules?.errorMessages?.maxLength ||
18
+ defaultErrorMessages(rules, type).maxLength,
19
+ };
20
+ }
21
+
22
+ // Check against custom regex if provided
23
+ const defaultRegex = /^(?=.*[A-Za-z])(?=.*\d).+$/;
24
+ const regexToUse = rules?.regex ? new RegExp(rules.regex) : defaultRegex;
25
+
26
+ if (!regexToUse.test(value)) {
27
+ return {
28
+ isValid: false,
29
+ error:
30
+ rules?.errorMessages?.invalid ||
31
+ "Password must contain at least one letter and one number",
32
+ };
33
+ }
34
+
35
+ return { isValid: true, error: "" };
36
+ };
37
+
38
+ module.exports = validatePassword;
@@ -0,0 +1,41 @@
1
+ // String validation
2
+ const validateString = (value, rules, defaultErrorMessages, type) => {
3
+ if (typeof value !== "string") {
4
+ return {
5
+ isValid: false,
6
+ error:
7
+ rules?.errorMessages?.invalid ||
8
+ defaultErrorMessages(rules, type).invalid,
9
+ };
10
+ }
11
+ if (rules?.minLength && value.length < rules?.minLength) {
12
+ return {
13
+ isValid: false,
14
+ error:
15
+ rules?.errorMessages?.minLength ||
16
+ defaultErrorMessages(rules, type).minLength,
17
+ };
18
+ }
19
+
20
+ if (rules?.maxLength && value.length > rules?.maxLength) {
21
+ return {
22
+ isValid: false,
23
+ error:
24
+ rules?.errorMessages?.maxLength ||
25
+ defaultErrorMessages(rules, type).maxLength,
26
+ };
27
+ }
28
+
29
+ if (rules?.regex && !new RegExp(rules?.regex).test(value)) {
30
+ return {
31
+ isValid: false,
32
+ error:
33
+ rules?.errorMessages?.invalid ||
34
+ defaultErrorMessages(rules, type).invalid,
35
+ };
36
+ }
37
+
38
+ return { isValid: true, error: "" };
39
+ };
40
+
41
+ module.exports = validateString;
package/index.js CHANGED
@@ -1,5 +1,3 @@
1
- const { parsePhoneNumberFromString } = require("libphonenumber-js/max");
2
-
3
1
  /**
4
2
  * Enhanced dynamic validator with custom function support
5
3
  * @param {string} value - The value to validate
@@ -8,38 +6,47 @@ const { parsePhoneNumberFromString } = require("libphonenumber-js/max");
8
6
  * @param {function} [customValidator] - Optional custom validation function
9
7
  * @returns {object} - Returns { isValid: boolean, error: string }
10
8
  */
11
- const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
12
- // Default error messages
13
- const defaultErrorMessages = {
14
- required: "This field is required",
15
- minLength: `Minimum length should be ${rules.minLength}`,
16
- maxLength: `Maximum length should be ${rules.maxLength}`,
17
- invalid: `Invalid ${type}`,
18
- noValidation: `No validation exist for ${type}`,
19
- custom: "Validation failed",
20
- customValidation:
21
- rules.errorMessages?.customValidation || "Custom validation failed",
22
- };
23
9
 
10
+ const defaultErrorMessages = require("./Messages/defaultErrorMessages");
11
+ const validateString = require("./Validators/validateString");
12
+ const validateAlphanumeric = require("./Validators/validateAlphanumeric");
13
+ const validateNumber = require("./Validators/validateNumber");
14
+ const validateFloatNumber = require("./Validators/validateFloatNumber");
15
+ const validateDate = require("./Validators/validateDate");
16
+ const validateName = require("./Validators/validateName");
17
+ const validateEmail = require("./Validators/validateEmail");
18
+ const validateMobile = require("./Validators/validateMobile");
19
+ const validateAddress = require("./Validators/validateAddress");
20
+ const validatePassword = require("./Validators/validatePassword");
21
+ const validateCustom = require("./Validators/validateCustom");
22
+ const validateAadhaar = require("./Validators/validateAadhaar");
23
+ const validatePanCard = require("./Validators/validatePanCard");
24
+ const validateChassisNumber = require("./Validators/ValidateChassisNumber");
25
+
26
+ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
24
27
  // Trim the value if it's a string
25
- const trimmedValue = typeof value === "string" ? value.trim() : value;
28
+ // const selectedValue = typeof value === "string" ? value.trim() : value;
29
+
30
+ const selectedValue = value;
26
31
 
27
32
  // Check if field is required and empty
28
- if (rules.required && (!trimmedValue || trimmedValue === "")) {
33
+ if (rules.required && (!selectedValue || selectedValue === "")) {
29
34
  return {
30
35
  isValid: false,
31
- error: rules.errorMessages?.required || defaultErrorMessages.required,
36
+ error:
37
+ rules.errorMessages?.required ||
38
+ defaultErrorMessages(rules, type).required,
32
39
  };
33
40
  }
34
41
 
35
42
  // Skip further validation if the field is empty and not required
36
- if (!rules.required && (!trimmedValue || trimmedValue === "")) {
43
+ if (!rules.required && (!selectedValue || selectedValue === "")) {
37
44
  return { isValid: true, error: "" };
38
45
  }
39
46
 
40
47
  // First run custom validator if provided (highest priority)
41
48
  if (customValidator && typeof customValidator === "function") {
42
- const customValidation = customValidator(trimmedValue);
49
+ const customValidation = customValidator(selectedValue);
43
50
 
44
51
  if (
45
52
  typeof customValidation === "object" &&
@@ -47,12 +54,14 @@ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
47
54
  ) {
48
55
  return {
49
56
  isValid: false,
50
- error: customValidation.error || defaultErrorMessages.customValidation,
57
+ error:
58
+ customValidation.error ||
59
+ defaultErrorMessages(rules, type).customValidation,
51
60
  };
52
61
  } else if (customValidation === false) {
53
62
  return {
54
63
  isValid: false,
55
- error: defaultErrorMessages.customValidation,
64
+ error: defaultErrorMessages(rules, type).customValidation,
56
65
  };
57
66
  }
58
67
  // If custom validator returns true or { isValid: true }, continue with other validations
@@ -60,7 +69,7 @@ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
60
69
 
61
70
  // Then run any custom validator in rules
62
71
  if (rules.customValidator && typeof rules.customValidator === "function") {
63
- const rulesCustomValidation = rules.customValidator(trimmedValue);
72
+ const rulesCustomValidation = rules.customValidator(selectedValue);
64
73
 
65
74
  if (
66
75
  typeof rulesCustomValidation === "object" &&
@@ -68,292 +77,69 @@ const dynamicValidator = (value, type, rules = {}, customValidator = null) => {
68
77
  ) {
69
78
  return {
70
79
  isValid: false,
71
- error: rulesCustomValidation.error || defaultErrorMessages.custom,
80
+ error:
81
+ rulesCustomValidation.error ||
82
+ defaultErrorMessages(rules, type).custom,
72
83
  };
73
84
  } else if (rulesCustomValidation === false) {
74
85
  return {
75
86
  isValid: false,
76
- error: defaultErrorMessages.custom,
87
+ error: defaultErrorMessages(rules, type).custom,
77
88
  };
78
89
  }
79
90
  }
80
91
 
81
92
  // Then validate based on type
82
93
  switch (type) {
94
+ case "string":
95
+ return validateString(selectedValue, rules, defaultErrorMessages, type);
96
+ case "alphanumeric":
97
+ return validateAlphanumeric(
98
+ selectedValue,
99
+ rules,
100
+ defaultErrorMessages,
101
+ type
102
+ );
103
+ case "number":
104
+ return validateNumber(selectedValue, rules, defaultErrorMessages, type);
105
+ case "float":
106
+ return validateFloatNumber(
107
+ selectedValue,
108
+ rules,
109
+ defaultErrorMessages,
110
+ type
111
+ );
112
+ case "date":
113
+ return validateDate(selectedValue, rules, defaultErrorMessages, type);
83
114
  case "name":
84
- return validateName(trimmedValue, rules, defaultErrorMessages);
115
+ return validateName(trimmedValue, rules, defaultErrorMessages, type);
85
116
  case "email":
86
- return validateEmail(trimmedValue, rules, defaultErrorMessages);
117
+ return validateEmail(selectedValue, rules, defaultErrorMessages, type);
87
118
  case "mobile":
88
- return validateMobile(trimmedValue, rules, defaultErrorMessages);
119
+ return validateMobile(selectedValue, rules, defaultErrorMessages, type);
89
120
  case "address":
90
- return validateAddress(trimmedValue, rules, defaultErrorMessages);
121
+ return validateAddress(selectedValue, rules, defaultErrorMessages, type);
91
122
  case "password":
92
- return validatePassword(trimmedValue, rules, defaultErrorMessages);
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);
93
136
  case "custom":
94
- return validateCustom(trimmedValue, rules, defaultErrorMessages);
137
+ return validateCustom(selectedValue, rules, defaultErrorMessages, type);
95
138
  default:
96
- return { isValid: false, error: defaultErrorMessages?.noValidation };
97
- }
98
- };
99
-
100
- // ... (keep all the existing validateName, validateEmail, etc. functions from previous solution)
101
-
102
- // Name validation
103
- const validateName = (value, rules, defaultErrorMessages) => {
104
- // Check length constraints
105
- if (rules?.minLength && value?.length < rules?.minLength) {
106
- return {
107
- isValid: false,
108
- error: rules?.errorMessages?.minLength || defaultErrorMessages.minLength,
109
- };
110
- }
111
-
112
- if (rules?.maxLength && value?.length > rules?.maxLength) {
113
- return {
114
- isValid: false,
115
- error: rules?.errorMessages?.maxLength || defaultErrorMessages.maxLength,
116
- };
117
- }
118
-
119
- // Check against custom regex if provided
120
- if (rules?.regex && !new RegExp(rules?.regex).test(value)) {
121
- return {
122
- isValid: false,
123
- error: rules?.errorMessages?.invalid || defaultErrorMessages.invalid,
124
- };
125
- }
126
-
127
- // Default name validation (only letters, spaces, and basic punctuation)
128
- const nameRegex = /^[a-zA-ZÀ-ÿ\s'-.]*$/;
129
- if (!nameRegex.test(value)) {
130
- return {
131
- isValid: false,
132
- error:
133
- rules?.errorMessages?.invalid || "Name contains invalid characters",
134
- };
135
- }
136
-
137
- return { isValid: true, error: "" };
138
- };
139
-
140
- // Email validation
141
- const validateEmail = (value, rules, defaultErrorMessages) => {
142
- // Check length constraints
143
- if (rules?.minLength && value.length < rules?.minLength) {
144
- return {
145
- isValid: false,
146
- error: rules?.errorMessages?.minLength || defaultErrorMessages.minLength,
147
- };
148
- }
149
-
150
- if (rules?.maxLength && value.length > rules?.maxLength) {
151
- return {
152
- isValid: false,
153
- error: rules?.errorMessages?.maxLength || defaultErrorMessages.maxLength,
154
- };
155
- }
156
-
157
- // Check against custom regex if provided
158
- if (rules?.regex && !new RegExp(rules?.regex).test(value)) {
159
- return {
160
- isValid: false,
161
- error: rules?.errorMessages?.invalid || defaultErrorMessages.invalid,
162
- };
163
- }
164
-
165
- // Default email regex
166
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
167
- if (!emailRegex.test(value)) {
168
- return {
169
- isValid: false,
170
- error:
171
- rules?.errorMessages?.invalid || "Please enter a valid email address",
172
- };
173
- }
174
-
175
- return { isValid: true, error: "" };
176
- };
177
-
178
- // Mobile validation
179
-
180
- // const validateMobile = (value, rules, defaultErrorMessages) => {
181
- // // Check length constraints
182
- // if (rules?.minLength && value.length < rules?.minLength) {
183
- // return {
184
- // isValid: false,
185
- // error: rules?.errorMessages?.minLength || defaultErrorMessages.minLength,
186
- // };
187
- // }
188
-
189
- // if (rules?.maxLength && value.length > rules?.maxLength) {
190
- // return {
191
- // isValid: false,
192
- // error: rules?.errorMessages?.maxLength || defaultErrorMessages.maxLength,
193
- // };
194
- // }
195
-
196
- // // Check against custom regex if provided
197
- // if (rules?.regex && !new RegExp(rules?.regex).test(value)) {
198
- // return {
199
- // isValid: false,
200
- // error: rules?.errorMessages?.invalid || defaultErrorMessages.invalid,
201
- // };
202
- // }
203
-
204
- // // Default mobile regex (accepts numbers, +, -, and spaces)
205
- // const mobileRegex = /^[\d\s+\-()]*$/;
206
- // if (!mobileRegex.test(value)) {
207
- // return {
208
- // isValid: false,
209
- // error:
210
- // rules?.errorMessages?.invalid || "Please enter a valid mobile number",
211
- // };
212
- // }
213
-
214
- // return { isValid: true, error: "" };
215
- // };
216
-
217
- const validateMobile = (value, rules = {}, defaultErrorMessages = {}) => {
218
- // Check length constraints
219
- if (rules.minLength && value.length < rules.minLength) {
220
- return {
221
- isValid: false,
222
- error: rules.errorMessages?.minLength || defaultErrorMessages.minLength,
223
- };
224
- }
225
-
226
- if (rules.maxLength && value.length > rules.maxLength) {
227
- return {
228
- isValid: false,
229
- error: rules.errorMessages?.maxLength || defaultErrorMessages.maxLength,
230
- };
231
- }
232
-
233
- // Custom regex check
234
- if (rules.regex && !new RegExp(rules.regex).test(value)) {
235
- return {
236
- isValid: false,
237
- error: rules.errorMessages?.invalid || defaultErrorMessages.invalid,
238
- };
239
- }
240
-
241
- // Validate using libphonenumber-js
242
- const phoneNumber = parsePhoneNumberFromString(
243
- value,
244
- rules?.countryCode || "IN"
245
- );
246
-
247
- // console.log('phoneNumber', phoneNumber)
248
- console.log(
249
- "phoneNumber.isValid()",
250
- phoneNumber.isValid(),
251
- phoneNumber.getType()
252
- );
253
-
254
- if (
255
- !phoneNumber?.isValid() &&
256
- (phoneNumber?.getType() !== "MOBILE" ||
257
- phoneNumber?.getType() !== "FIXED_LINE_OR_MOBILE")
258
- ) {
259
- return {
260
- isValid: false,
261
- error:
262
- rules.errorMessages?.invalid ||
263
- defaultErrorMessages.invalid ||
264
- "Please enter a valid mobile number",
265
- };
266
- }
267
-
268
- return { isValid: true, error: "" };
269
- };
270
-
271
- // Address validation
272
- const validateAddress = (value, rules, defaultErrorMessages) => {
273
- // Check length constraints
274
- if (rules?.minLength && value.length < rules?.minLength) {
275
- return {
276
- isValid: false,
277
- error: rules?.errorMessages?.minLength || defaultErrorMessages.minLength,
278
- };
279
- }
280
-
281
- if (rules?.maxLength && value.length > rules?.maxLength) {
282
- return {
283
- isValid: false,
284
- error: rules?.errorMessages?.maxLength || defaultErrorMessages.maxLength,
285
- };
286
- }
287
-
288
- // Check against custom regex if provided
289
- if (rules?.regex && !new RegExp(rules?.regex).test(value)) {
290
- return {
291
- isValid: false,
292
- error: rules?.errorMessages?.invalid || defaultErrorMessages.invalid,
293
- };
294
- }
295
-
296
- return { isValid: true, error: "" };
297
- };
298
-
299
- // Add password validation
300
- const validatePassword = (value, rules, defaultErrorMessages) => {
301
- // Check length constraints
302
- if (rules?.minLength && value.length < rules?.minLength) {
303
- return {
304
- isValid: false,
305
- error: rules?.errorMessages?.minLength || defaultErrorMessages.minLength,
306
- };
307
- }
308
-
309
- if (rules?.maxLength && value.length > rules?.maxLength) {
310
- return {
311
- isValid: false,
312
- error: rules?.errorMessages?.maxLength || defaultErrorMessages.maxLength,
313
- };
314
- }
315
-
316
- // Check against custom regex if provided
317
- if (rules?.regex && !new RegExp(rules?.regex).test(value)) {
318
- return {
319
- isValid: false,
320
- error: rules?.errorMessages?.invalid || defaultErrorMessages.invalid,
321
- };
322
- }
323
-
324
- // Default password validation (at least one letter, one number)
325
- const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d).+$/;
326
- if (!passwordRegex.test(value)) {
327
- return {
328
- isValid: false,
329
- error:
330
- rules?.errorMessages?.invalid ||
331
- "Password must contain at least one letter and one number",
332
- };
333
- }
334
-
335
- return { isValid: true, error: "" };
336
- };
337
-
338
- // Custom validation
339
- const validateCustom = (value, rules, defaultErrorMessages) => {
340
- // Check length constraints if value is a string
341
- if (typeof value === "string") {
342
- if (rules?.minLength && value.length < rules?.minLength) {
343
139
  return {
344
140
  isValid: false,
345
- error:
346
- rules?.errorMessages?.minLength || defaultErrorMessages.minLength,
347
- };
348
- }
349
-
350
- if (rules?.maxLength && value.length > rules?.maxLength) {
351
- return {
352
- isValid: false,
353
- error:
354
- rules?.errorMessages?.maxLength || defaultErrorMessages.maxLength,
141
+ error: defaultErrorMessages(rules, type)?.noValidation,
355
142
  };
356
- }
357
143
  }
358
144
  };
359
145