@mohasinac/validation 0.1.0 → 1.1.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/dist/index.cjs +246 -3
- package/dist/index.d.cts +64 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +221 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,13 +21,38 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
addressSchema: () => addressSchema,
|
|
24
|
+
calculatePasswordStrength: () => calculatePasswordStrength,
|
|
24
25
|
dateStringSchema: () => dateStringSchema,
|
|
25
26
|
emailSchema: () => emailSchema,
|
|
27
|
+
exactLength: () => exactLength,
|
|
28
|
+
extractCountryCode: () => extractCountryCode,
|
|
29
|
+
formatPhone: () => formatPhone,
|
|
30
|
+
inRange: () => inRange,
|
|
31
|
+
isCommonPassword: () => isCommonPassword,
|
|
32
|
+
isDisposableEmail: () => isDisposableEmail,
|
|
33
|
+
isExternalUrl: () => isExternalUrl,
|
|
34
|
+
isInList: () => isInList,
|
|
35
|
+
isNumeric: () => isNumeric,
|
|
36
|
+
isRequired: () => isRequired,
|
|
37
|
+
isValidEmail: () => isValidEmail,
|
|
38
|
+
isValidEmailDomain: () => isValidEmailDomain,
|
|
39
|
+
isValidIndianMobile: () => isValidIndianMobile,
|
|
40
|
+
isValidIndianPincode: () => isValidIndianPincode,
|
|
41
|
+
isValidPhone: () => isValidPhone,
|
|
42
|
+
isValidUrl: () => isValidUrl,
|
|
43
|
+
isValidUrlWithProtocol: () => isValidUrlWithProtocol,
|
|
44
|
+
matchesPattern: () => matchesPattern,
|
|
45
|
+
maxLength: () => maxLength,
|
|
26
46
|
mediaUrlSchema: () => mediaUrlSchema,
|
|
47
|
+
meetsPasswordRequirements: () => meetsPasswordRequirements,
|
|
48
|
+
minLength: () => minLength,
|
|
49
|
+
normalizeEmail: () => normalizeEmail,
|
|
50
|
+
normalizePhone: () => normalizePhone,
|
|
27
51
|
objectIdSchema: () => objectIdSchema,
|
|
28
52
|
paginationQuerySchema: () => paginationQuerySchema,
|
|
29
53
|
passwordSchema: () => passwordSchema,
|
|
30
54
|
phoneSchema: () => phoneSchema,
|
|
55
|
+
sanitizeUrl: () => sanitizeUrl,
|
|
31
56
|
setupZodErrorMap: () => setupZodErrorMap,
|
|
32
57
|
urlSchema: () => urlSchema,
|
|
33
58
|
zodErrorMap: () => zodErrorMap
|
|
@@ -162,22 +187,240 @@ function zodErrorMap(issue) {
|
|
|
162
187
|
message: (_d = issue.message) != null ? _d : "Invalid value"
|
|
163
188
|
};
|
|
164
189
|
}
|
|
165
|
-
var _applied = false;
|
|
166
190
|
function setupZodErrorMap() {
|
|
167
|
-
if (
|
|
191
|
+
if (globalThis.__mohasinac_zod_applied__) return;
|
|
168
192
|
import_zod2.z.setErrorMap(zodErrorMap);
|
|
169
|
-
|
|
193
|
+
globalThis.__mohasinac_zod_applied__ = true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/email.validator.ts
|
|
197
|
+
function isValidEmail(email) {
|
|
198
|
+
const emailRegex = /^[^\s@]+@[^\s@.][^\s@]*[^\s@.]\.[^\s@]+$|^[^\s@]+@[^\s@.]\.[^\s@]+$/;
|
|
199
|
+
if (!emailRegex.test(email)) return false;
|
|
200
|
+
if (email.includes("..")) return false;
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
function isValidEmailDomain(email, allowedDomains) {
|
|
204
|
+
if (!isValidEmail(email)) return false;
|
|
205
|
+
if (!allowedDomains || allowedDomains.length === 0) return true;
|
|
206
|
+
const domain = email.split("@")[1].toLowerCase();
|
|
207
|
+
return allowedDomains.some((allowed) => domain === allowed.toLowerCase());
|
|
208
|
+
}
|
|
209
|
+
function normalizeEmail(email) {
|
|
210
|
+
return email.trim().toLowerCase();
|
|
211
|
+
}
|
|
212
|
+
function isDisposableEmail(email) {
|
|
213
|
+
var _a;
|
|
214
|
+
const disposableDomains = [
|
|
215
|
+
"tempmail.com",
|
|
216
|
+
"10minutemail.com",
|
|
217
|
+
"guerrillamail.com",
|
|
218
|
+
"mailinator.com",
|
|
219
|
+
"throwaway.email"
|
|
220
|
+
];
|
|
221
|
+
const domain = (_a = email.split("@")[1]) == null ? void 0 : _a.toLowerCase();
|
|
222
|
+
return disposableDomains.includes(domain);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/password.validator.ts
|
|
226
|
+
var DEFAULT_REQUIREMENTS = {
|
|
227
|
+
minLength: 8,
|
|
228
|
+
requireUppercase: true,
|
|
229
|
+
requireLowercase: true,
|
|
230
|
+
requireNumbers: true,
|
|
231
|
+
requireSpecialChars: true
|
|
232
|
+
};
|
|
233
|
+
function meetsPasswordRequirements(password, requirements = DEFAULT_REQUIREMENTS) {
|
|
234
|
+
const missing = [];
|
|
235
|
+
if (password.length < requirements.minLength)
|
|
236
|
+
missing.push(`At least ${requirements.minLength} characters`);
|
|
237
|
+
if (requirements.requireUppercase && !/[A-Z]/.test(password))
|
|
238
|
+
missing.push("One uppercase letter");
|
|
239
|
+
if (requirements.requireLowercase && !/[a-z]/.test(password))
|
|
240
|
+
missing.push("One lowercase letter");
|
|
241
|
+
if (requirements.requireNumbers && !/\d/.test(password))
|
|
242
|
+
missing.push("One number");
|
|
243
|
+
if (requirements.requireSpecialChars && !/[!@#$%^&*(),.?":{}|<>]/.test(password))
|
|
244
|
+
missing.push("One special character");
|
|
245
|
+
return { valid: missing.length === 0, missing };
|
|
246
|
+
}
|
|
247
|
+
function calculatePasswordStrength(password) {
|
|
248
|
+
let score = 0;
|
|
249
|
+
const feedback = [];
|
|
250
|
+
if (password.length >= 8) score++;
|
|
251
|
+
if (password.length >= 12) score++;
|
|
252
|
+
if (password.length < 8) feedback.push("Password is too short");
|
|
253
|
+
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score++;
|
|
254
|
+
if (/\d/.test(password)) score++;
|
|
255
|
+
if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) score++;
|
|
256
|
+
if (/(.)\1{2,}/.test(password)) {
|
|
257
|
+
score = Math.max(0, score - 1);
|
|
258
|
+
feedback.push("Avoid repeated characters");
|
|
259
|
+
}
|
|
260
|
+
if (/^(?:password|123456|qwerty)/i.test(password)) {
|
|
261
|
+
score = 0;
|
|
262
|
+
feedback.push("Avoid common passwords");
|
|
263
|
+
}
|
|
264
|
+
score = Math.min(4, Math.max(0, score));
|
|
265
|
+
const levels = ["too-weak", "weak", "fair", "good", "strong"];
|
|
266
|
+
return { score, level: levels[score], feedback };
|
|
267
|
+
}
|
|
268
|
+
function isCommonPassword(password) {
|
|
269
|
+
const commonPasswords = [
|
|
270
|
+
"password",
|
|
271
|
+
"123456",
|
|
272
|
+
"123456789",
|
|
273
|
+
"qwerty",
|
|
274
|
+
"abc123",
|
|
275
|
+
"monkey",
|
|
276
|
+
"1234567",
|
|
277
|
+
"letmein",
|
|
278
|
+
"trustno1",
|
|
279
|
+
"dragon",
|
|
280
|
+
"baseball",
|
|
281
|
+
"iloveyou",
|
|
282
|
+
"master",
|
|
283
|
+
"sunshine",
|
|
284
|
+
"ashley",
|
|
285
|
+
"bailey",
|
|
286
|
+
"passw0rd",
|
|
287
|
+
"shadow",
|
|
288
|
+
"123123",
|
|
289
|
+
"654321"
|
|
290
|
+
];
|
|
291
|
+
return commonPasswords.includes(password.toLowerCase());
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/phone.validator.ts
|
|
295
|
+
function isValidPhone(phone) {
|
|
296
|
+
const phoneRegex = /^\+?[\d\s-()]+$/;
|
|
297
|
+
const cleaned = phone.replace(/[\s-()]/g, "");
|
|
298
|
+
return phoneRegex.test(phone) && cleaned.length >= 10 && cleaned.length <= 15;
|
|
299
|
+
}
|
|
300
|
+
function normalizePhone(phone) {
|
|
301
|
+
return phone.replace(/[\s-()]/g, "");
|
|
302
|
+
}
|
|
303
|
+
function formatPhone(phone, countryCode = "US") {
|
|
304
|
+
const cleaned = normalizePhone(phone);
|
|
305
|
+
if (countryCode === "US" && cleaned.length === 10) {
|
|
306
|
+
return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3, 6)}-${cleaned.slice(6)}`;
|
|
307
|
+
}
|
|
308
|
+
if (cleaned.startsWith("+")) return cleaned;
|
|
309
|
+
return `+${cleaned}`;
|
|
310
|
+
}
|
|
311
|
+
function extractCountryCode(phone) {
|
|
312
|
+
const cleaned = normalizePhone(phone);
|
|
313
|
+
if (!cleaned.startsWith("+")) return null;
|
|
314
|
+
const match = cleaned.match(/^\+(\d{1,3})/);
|
|
315
|
+
return match ? `+${match[1]}` : null;
|
|
316
|
+
}
|
|
317
|
+
function isValidIndianMobile(phone) {
|
|
318
|
+
const cleaned = normalizePhone(phone).replace(/^\+91/, "");
|
|
319
|
+
return /^[6-9]\d{9}$/.test(cleaned);
|
|
320
|
+
}
|
|
321
|
+
function isValidIndianPincode(pincode) {
|
|
322
|
+
return /^\d{6}$/.test(pincode.trim());
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/url.validator.ts
|
|
326
|
+
function isValidUrl(url) {
|
|
327
|
+
try {
|
|
328
|
+
new URL(url);
|
|
329
|
+
return true;
|
|
330
|
+
} catch (e) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function isValidUrlWithProtocol(url, protocols = ["http", "https"]) {
|
|
335
|
+
if (!isValidUrl(url)) return false;
|
|
336
|
+
try {
|
|
337
|
+
const urlObj = new URL(url);
|
|
338
|
+
return protocols.includes(urlObj.protocol.replace(":", ""));
|
|
339
|
+
} catch (e) {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function isExternalUrl(url, currentDomain) {
|
|
344
|
+
if (!isValidUrl(url)) return false;
|
|
345
|
+
try {
|
|
346
|
+
const urlObj = new URL(url);
|
|
347
|
+
const currentHost = currentDomain || (typeof window !== "undefined" ? window.location.hostname : "");
|
|
348
|
+
return urlObj.hostname !== currentHost;
|
|
349
|
+
} catch (e) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
function sanitizeUrl(url) {
|
|
354
|
+
const dangerousProtocols = ["javascript:", "data:", "vbscript:"];
|
|
355
|
+
for (const protocol of dangerousProtocols) {
|
|
356
|
+
if (url.toLowerCase().startsWith(protocol)) return "about:blank";
|
|
357
|
+
}
|
|
358
|
+
return url;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// src/input.validator.ts
|
|
362
|
+
function isRequired(value) {
|
|
363
|
+
if (value === null || value === void 0) return false;
|
|
364
|
+
if (typeof value === "string") return value.trim().length > 0;
|
|
365
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
function minLength(value, min) {
|
|
369
|
+
return value.length >= min;
|
|
370
|
+
}
|
|
371
|
+
function maxLength(value, max) {
|
|
372
|
+
return value.length <= max;
|
|
373
|
+
}
|
|
374
|
+
function exactLength(value, length) {
|
|
375
|
+
return value.length === length;
|
|
376
|
+
}
|
|
377
|
+
function isNumeric(value) {
|
|
378
|
+
return !isNaN(Number(value)) && !isNaN(parseFloat(value));
|
|
379
|
+
}
|
|
380
|
+
function inRange(value, min, max) {
|
|
381
|
+
return value >= min && value <= max;
|
|
382
|
+
}
|
|
383
|
+
function matchesPattern(value, pattern) {
|
|
384
|
+
return pattern.test(value);
|
|
385
|
+
}
|
|
386
|
+
function isInList(value, list) {
|
|
387
|
+
return list.includes(value);
|
|
170
388
|
}
|
|
171
389
|
// Annotate the CommonJS export names for ESM import in node:
|
|
172
390
|
0 && (module.exports = {
|
|
173
391
|
addressSchema,
|
|
392
|
+
calculatePasswordStrength,
|
|
174
393
|
dateStringSchema,
|
|
175
394
|
emailSchema,
|
|
395
|
+
exactLength,
|
|
396
|
+
extractCountryCode,
|
|
397
|
+
formatPhone,
|
|
398
|
+
inRange,
|
|
399
|
+
isCommonPassword,
|
|
400
|
+
isDisposableEmail,
|
|
401
|
+
isExternalUrl,
|
|
402
|
+
isInList,
|
|
403
|
+
isNumeric,
|
|
404
|
+
isRequired,
|
|
405
|
+
isValidEmail,
|
|
406
|
+
isValidEmailDomain,
|
|
407
|
+
isValidIndianMobile,
|
|
408
|
+
isValidIndianPincode,
|
|
409
|
+
isValidPhone,
|
|
410
|
+
isValidUrl,
|
|
411
|
+
isValidUrlWithProtocol,
|
|
412
|
+
matchesPattern,
|
|
413
|
+
maxLength,
|
|
176
414
|
mediaUrlSchema,
|
|
415
|
+
meetsPasswordRequirements,
|
|
416
|
+
minLength,
|
|
417
|
+
normalizeEmail,
|
|
418
|
+
normalizePhone,
|
|
177
419
|
objectIdSchema,
|
|
178
420
|
paginationQuerySchema,
|
|
179
421
|
passwordSchema,
|
|
180
422
|
phoneSchema,
|
|
423
|
+
sanitizeUrl,
|
|
181
424
|
setupZodErrorMap,
|
|
182
425
|
urlSchema,
|
|
183
426
|
zodErrorMap
|
package/dist/index.d.cts
CHANGED
|
@@ -57,7 +57,70 @@ declare const addressSchema: z.ZodObject<{
|
|
|
57
57
|
declare function zodErrorMap(issue: Parameters<Parameters<typeof z.setErrorMap>[0]>[0]): {
|
|
58
58
|
message: string;
|
|
59
59
|
};
|
|
60
|
+
declare global {
|
|
61
|
+
var __mohasinac_zod_applied__: boolean | undefined;
|
|
62
|
+
}
|
|
60
63
|
/** Apply the custom error map globally. Safe to call multiple times. */
|
|
61
64
|
declare function setupZodErrorMap(): void;
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Email Validation Utilities
|
|
68
|
+
*/
|
|
69
|
+
declare function isValidEmail(email: string): boolean;
|
|
70
|
+
declare function isValidEmailDomain(email: string, allowedDomains?: string[]): boolean;
|
|
71
|
+
declare function normalizeEmail(email: string): string;
|
|
72
|
+
declare function isDisposableEmail(email: string): boolean;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Password Validation Utilities
|
|
76
|
+
*/
|
|
77
|
+
interface PasswordStrength {
|
|
78
|
+
score: number;
|
|
79
|
+
level: "too-weak" | "weak" | "fair" | "good" | "strong";
|
|
80
|
+
feedback: string[];
|
|
81
|
+
}
|
|
82
|
+
interface PasswordRequirements {
|
|
83
|
+
minLength: number;
|
|
84
|
+
requireUppercase: boolean;
|
|
85
|
+
requireLowercase: boolean;
|
|
86
|
+
requireNumbers: boolean;
|
|
87
|
+
requireSpecialChars: boolean;
|
|
88
|
+
}
|
|
89
|
+
declare function meetsPasswordRequirements(password: string, requirements?: PasswordRequirements): {
|
|
90
|
+
valid: boolean;
|
|
91
|
+
missing: string[];
|
|
92
|
+
};
|
|
93
|
+
declare function calculatePasswordStrength(password: string): PasswordStrength;
|
|
94
|
+
declare function isCommonPassword(password: string): boolean;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Phone Number Validation Utilities
|
|
98
|
+
*/
|
|
99
|
+
declare function isValidPhone(phone: string): boolean;
|
|
100
|
+
declare function normalizePhone(phone: string): string;
|
|
101
|
+
declare function formatPhone(phone: string, countryCode?: string): string;
|
|
102
|
+
declare function extractCountryCode(phone: string): string | null;
|
|
103
|
+
declare function isValidIndianMobile(phone: string): boolean;
|
|
104
|
+
declare function isValidIndianPincode(pincode: string): boolean;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* URL Validation Utilities
|
|
108
|
+
*/
|
|
109
|
+
declare function isValidUrl(url: string): boolean;
|
|
110
|
+
declare function isValidUrlWithProtocol(url: string, protocols?: string[]): boolean;
|
|
111
|
+
declare function isExternalUrl(url: string, currentDomain?: string): boolean;
|
|
112
|
+
declare function sanitizeUrl(url: string): string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* General Input Validation Utilities
|
|
116
|
+
*/
|
|
117
|
+
declare function isRequired(value: any): boolean;
|
|
118
|
+
declare function minLength(value: string, min: number): boolean;
|
|
119
|
+
declare function maxLength(value: string, max: number): boolean;
|
|
120
|
+
declare function exactLength(value: string, length: number): boolean;
|
|
121
|
+
declare function isNumeric(value: string): boolean;
|
|
122
|
+
declare function inRange(value: number, min: number, max: number): boolean;
|
|
123
|
+
declare function matchesPattern(value: string, pattern: RegExp): boolean;
|
|
124
|
+
declare function isInList<T>(value: T, list: T[]): boolean;
|
|
125
|
+
|
|
126
|
+
export { type PasswordRequirements, type PasswordStrength, addressSchema, calculatePasswordStrength, dateStringSchema, emailSchema, exactLength, extractCountryCode, formatPhone, inRange, isCommonPassword, isDisposableEmail, isExternalUrl, isInList, isNumeric, isRequired, isValidEmail, isValidEmailDomain, isValidIndianMobile, isValidIndianPincode, isValidPhone, isValidUrl, isValidUrlWithProtocol, matchesPattern, maxLength, mediaUrlSchema, meetsPasswordRequirements, minLength, normalizeEmail, normalizePhone, objectIdSchema, paginationQuerySchema, passwordSchema, phoneSchema, sanitizeUrl, setupZodErrorMap, urlSchema, zodErrorMap };
|
package/dist/index.d.ts
CHANGED
|
@@ -57,7 +57,70 @@ declare const addressSchema: z.ZodObject<{
|
|
|
57
57
|
declare function zodErrorMap(issue: Parameters<Parameters<typeof z.setErrorMap>[0]>[0]): {
|
|
58
58
|
message: string;
|
|
59
59
|
};
|
|
60
|
+
declare global {
|
|
61
|
+
var __mohasinac_zod_applied__: boolean | undefined;
|
|
62
|
+
}
|
|
60
63
|
/** Apply the custom error map globally. Safe to call multiple times. */
|
|
61
64
|
declare function setupZodErrorMap(): void;
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Email Validation Utilities
|
|
68
|
+
*/
|
|
69
|
+
declare function isValidEmail(email: string): boolean;
|
|
70
|
+
declare function isValidEmailDomain(email: string, allowedDomains?: string[]): boolean;
|
|
71
|
+
declare function normalizeEmail(email: string): string;
|
|
72
|
+
declare function isDisposableEmail(email: string): boolean;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Password Validation Utilities
|
|
76
|
+
*/
|
|
77
|
+
interface PasswordStrength {
|
|
78
|
+
score: number;
|
|
79
|
+
level: "too-weak" | "weak" | "fair" | "good" | "strong";
|
|
80
|
+
feedback: string[];
|
|
81
|
+
}
|
|
82
|
+
interface PasswordRequirements {
|
|
83
|
+
minLength: number;
|
|
84
|
+
requireUppercase: boolean;
|
|
85
|
+
requireLowercase: boolean;
|
|
86
|
+
requireNumbers: boolean;
|
|
87
|
+
requireSpecialChars: boolean;
|
|
88
|
+
}
|
|
89
|
+
declare function meetsPasswordRequirements(password: string, requirements?: PasswordRequirements): {
|
|
90
|
+
valid: boolean;
|
|
91
|
+
missing: string[];
|
|
92
|
+
};
|
|
93
|
+
declare function calculatePasswordStrength(password: string): PasswordStrength;
|
|
94
|
+
declare function isCommonPassword(password: string): boolean;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Phone Number Validation Utilities
|
|
98
|
+
*/
|
|
99
|
+
declare function isValidPhone(phone: string): boolean;
|
|
100
|
+
declare function normalizePhone(phone: string): string;
|
|
101
|
+
declare function formatPhone(phone: string, countryCode?: string): string;
|
|
102
|
+
declare function extractCountryCode(phone: string): string | null;
|
|
103
|
+
declare function isValidIndianMobile(phone: string): boolean;
|
|
104
|
+
declare function isValidIndianPincode(pincode: string): boolean;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* URL Validation Utilities
|
|
108
|
+
*/
|
|
109
|
+
declare function isValidUrl(url: string): boolean;
|
|
110
|
+
declare function isValidUrlWithProtocol(url: string, protocols?: string[]): boolean;
|
|
111
|
+
declare function isExternalUrl(url: string, currentDomain?: string): boolean;
|
|
112
|
+
declare function sanitizeUrl(url: string): string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* General Input Validation Utilities
|
|
116
|
+
*/
|
|
117
|
+
declare function isRequired(value: any): boolean;
|
|
118
|
+
declare function minLength(value: string, min: number): boolean;
|
|
119
|
+
declare function maxLength(value: string, max: number): boolean;
|
|
120
|
+
declare function exactLength(value: string, length: number): boolean;
|
|
121
|
+
declare function isNumeric(value: string): boolean;
|
|
122
|
+
declare function inRange(value: number, min: number, max: number): boolean;
|
|
123
|
+
declare function matchesPattern(value: string, pattern: RegExp): boolean;
|
|
124
|
+
declare function isInList<T>(value: T, list: T[]): boolean;
|
|
125
|
+
|
|
126
|
+
export { type PasswordRequirements, type PasswordStrength, addressSchema, calculatePasswordStrength, dateStringSchema, emailSchema, exactLength, extractCountryCode, formatPhone, inRange, isCommonPassword, isDisposableEmail, isExternalUrl, isInList, isNumeric, isRequired, isValidEmail, isValidEmailDomain, isValidIndianMobile, isValidIndianPincode, isValidPhone, isValidUrl, isValidUrlWithProtocol, matchesPattern, maxLength, mediaUrlSchema, meetsPasswordRequirements, minLength, normalizeEmail, normalizePhone, objectIdSchema, paginationQuerySchema, passwordSchema, phoneSchema, sanitizeUrl, setupZodErrorMap, urlSchema, zodErrorMap };
|
package/dist/index.js
CHANGED
|
@@ -126,21 +126,239 @@ function zodErrorMap(issue) {
|
|
|
126
126
|
message: (_d = issue.message) != null ? _d : "Invalid value"
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
|
-
var _applied = false;
|
|
130
129
|
function setupZodErrorMap() {
|
|
131
|
-
if (
|
|
130
|
+
if (globalThis.__mohasinac_zod_applied__) return;
|
|
132
131
|
z2.setErrorMap(zodErrorMap);
|
|
133
|
-
|
|
132
|
+
globalThis.__mohasinac_zod_applied__ = true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/email.validator.ts
|
|
136
|
+
function isValidEmail(email) {
|
|
137
|
+
const emailRegex = /^[^\s@]+@[^\s@.][^\s@]*[^\s@.]\.[^\s@]+$|^[^\s@]+@[^\s@.]\.[^\s@]+$/;
|
|
138
|
+
if (!emailRegex.test(email)) return false;
|
|
139
|
+
if (email.includes("..")) return false;
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
function isValidEmailDomain(email, allowedDomains) {
|
|
143
|
+
if (!isValidEmail(email)) return false;
|
|
144
|
+
if (!allowedDomains || allowedDomains.length === 0) return true;
|
|
145
|
+
const domain = email.split("@")[1].toLowerCase();
|
|
146
|
+
return allowedDomains.some((allowed) => domain === allowed.toLowerCase());
|
|
147
|
+
}
|
|
148
|
+
function normalizeEmail(email) {
|
|
149
|
+
return email.trim().toLowerCase();
|
|
150
|
+
}
|
|
151
|
+
function isDisposableEmail(email) {
|
|
152
|
+
var _a;
|
|
153
|
+
const disposableDomains = [
|
|
154
|
+
"tempmail.com",
|
|
155
|
+
"10minutemail.com",
|
|
156
|
+
"guerrillamail.com",
|
|
157
|
+
"mailinator.com",
|
|
158
|
+
"throwaway.email"
|
|
159
|
+
];
|
|
160
|
+
const domain = (_a = email.split("@")[1]) == null ? void 0 : _a.toLowerCase();
|
|
161
|
+
return disposableDomains.includes(domain);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/password.validator.ts
|
|
165
|
+
var DEFAULT_REQUIREMENTS = {
|
|
166
|
+
minLength: 8,
|
|
167
|
+
requireUppercase: true,
|
|
168
|
+
requireLowercase: true,
|
|
169
|
+
requireNumbers: true,
|
|
170
|
+
requireSpecialChars: true
|
|
171
|
+
};
|
|
172
|
+
function meetsPasswordRequirements(password, requirements = DEFAULT_REQUIREMENTS) {
|
|
173
|
+
const missing = [];
|
|
174
|
+
if (password.length < requirements.minLength)
|
|
175
|
+
missing.push(`At least ${requirements.minLength} characters`);
|
|
176
|
+
if (requirements.requireUppercase && !/[A-Z]/.test(password))
|
|
177
|
+
missing.push("One uppercase letter");
|
|
178
|
+
if (requirements.requireLowercase && !/[a-z]/.test(password))
|
|
179
|
+
missing.push("One lowercase letter");
|
|
180
|
+
if (requirements.requireNumbers && !/\d/.test(password))
|
|
181
|
+
missing.push("One number");
|
|
182
|
+
if (requirements.requireSpecialChars && !/[!@#$%^&*(),.?":{}|<>]/.test(password))
|
|
183
|
+
missing.push("One special character");
|
|
184
|
+
return { valid: missing.length === 0, missing };
|
|
185
|
+
}
|
|
186
|
+
function calculatePasswordStrength(password) {
|
|
187
|
+
let score = 0;
|
|
188
|
+
const feedback = [];
|
|
189
|
+
if (password.length >= 8) score++;
|
|
190
|
+
if (password.length >= 12) score++;
|
|
191
|
+
if (password.length < 8) feedback.push("Password is too short");
|
|
192
|
+
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score++;
|
|
193
|
+
if (/\d/.test(password)) score++;
|
|
194
|
+
if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) score++;
|
|
195
|
+
if (/(.)\1{2,}/.test(password)) {
|
|
196
|
+
score = Math.max(0, score - 1);
|
|
197
|
+
feedback.push("Avoid repeated characters");
|
|
198
|
+
}
|
|
199
|
+
if (/^(?:password|123456|qwerty)/i.test(password)) {
|
|
200
|
+
score = 0;
|
|
201
|
+
feedback.push("Avoid common passwords");
|
|
202
|
+
}
|
|
203
|
+
score = Math.min(4, Math.max(0, score));
|
|
204
|
+
const levels = ["too-weak", "weak", "fair", "good", "strong"];
|
|
205
|
+
return { score, level: levels[score], feedback };
|
|
206
|
+
}
|
|
207
|
+
function isCommonPassword(password) {
|
|
208
|
+
const commonPasswords = [
|
|
209
|
+
"password",
|
|
210
|
+
"123456",
|
|
211
|
+
"123456789",
|
|
212
|
+
"qwerty",
|
|
213
|
+
"abc123",
|
|
214
|
+
"monkey",
|
|
215
|
+
"1234567",
|
|
216
|
+
"letmein",
|
|
217
|
+
"trustno1",
|
|
218
|
+
"dragon",
|
|
219
|
+
"baseball",
|
|
220
|
+
"iloveyou",
|
|
221
|
+
"master",
|
|
222
|
+
"sunshine",
|
|
223
|
+
"ashley",
|
|
224
|
+
"bailey",
|
|
225
|
+
"passw0rd",
|
|
226
|
+
"shadow",
|
|
227
|
+
"123123",
|
|
228
|
+
"654321"
|
|
229
|
+
];
|
|
230
|
+
return commonPasswords.includes(password.toLowerCase());
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/phone.validator.ts
|
|
234
|
+
function isValidPhone(phone) {
|
|
235
|
+
const phoneRegex = /^\+?[\d\s-()]+$/;
|
|
236
|
+
const cleaned = phone.replace(/[\s-()]/g, "");
|
|
237
|
+
return phoneRegex.test(phone) && cleaned.length >= 10 && cleaned.length <= 15;
|
|
238
|
+
}
|
|
239
|
+
function normalizePhone(phone) {
|
|
240
|
+
return phone.replace(/[\s-()]/g, "");
|
|
241
|
+
}
|
|
242
|
+
function formatPhone(phone, countryCode = "US") {
|
|
243
|
+
const cleaned = normalizePhone(phone);
|
|
244
|
+
if (countryCode === "US" && cleaned.length === 10) {
|
|
245
|
+
return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3, 6)}-${cleaned.slice(6)}`;
|
|
246
|
+
}
|
|
247
|
+
if (cleaned.startsWith("+")) return cleaned;
|
|
248
|
+
return `+${cleaned}`;
|
|
249
|
+
}
|
|
250
|
+
function extractCountryCode(phone) {
|
|
251
|
+
const cleaned = normalizePhone(phone);
|
|
252
|
+
if (!cleaned.startsWith("+")) return null;
|
|
253
|
+
const match = cleaned.match(/^\+(\d{1,3})/);
|
|
254
|
+
return match ? `+${match[1]}` : null;
|
|
255
|
+
}
|
|
256
|
+
function isValidIndianMobile(phone) {
|
|
257
|
+
const cleaned = normalizePhone(phone).replace(/^\+91/, "");
|
|
258
|
+
return /^[6-9]\d{9}$/.test(cleaned);
|
|
259
|
+
}
|
|
260
|
+
function isValidIndianPincode(pincode) {
|
|
261
|
+
return /^\d{6}$/.test(pincode.trim());
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/url.validator.ts
|
|
265
|
+
function isValidUrl(url) {
|
|
266
|
+
try {
|
|
267
|
+
new URL(url);
|
|
268
|
+
return true;
|
|
269
|
+
} catch (e) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function isValidUrlWithProtocol(url, protocols = ["http", "https"]) {
|
|
274
|
+
if (!isValidUrl(url)) return false;
|
|
275
|
+
try {
|
|
276
|
+
const urlObj = new URL(url);
|
|
277
|
+
return protocols.includes(urlObj.protocol.replace(":", ""));
|
|
278
|
+
} catch (e) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function isExternalUrl(url, currentDomain) {
|
|
283
|
+
if (!isValidUrl(url)) return false;
|
|
284
|
+
try {
|
|
285
|
+
const urlObj = new URL(url);
|
|
286
|
+
const currentHost = currentDomain || (typeof window !== "undefined" ? window.location.hostname : "");
|
|
287
|
+
return urlObj.hostname !== currentHost;
|
|
288
|
+
} catch (e) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function sanitizeUrl(url) {
|
|
293
|
+
const dangerousProtocols = ["javascript:", "data:", "vbscript:"];
|
|
294
|
+
for (const protocol of dangerousProtocols) {
|
|
295
|
+
if (url.toLowerCase().startsWith(protocol)) return "about:blank";
|
|
296
|
+
}
|
|
297
|
+
return url;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/input.validator.ts
|
|
301
|
+
function isRequired(value) {
|
|
302
|
+
if (value === null || value === void 0) return false;
|
|
303
|
+
if (typeof value === "string") return value.trim().length > 0;
|
|
304
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
function minLength(value, min) {
|
|
308
|
+
return value.length >= min;
|
|
309
|
+
}
|
|
310
|
+
function maxLength(value, max) {
|
|
311
|
+
return value.length <= max;
|
|
312
|
+
}
|
|
313
|
+
function exactLength(value, length) {
|
|
314
|
+
return value.length === length;
|
|
315
|
+
}
|
|
316
|
+
function isNumeric(value) {
|
|
317
|
+
return !isNaN(Number(value)) && !isNaN(parseFloat(value));
|
|
318
|
+
}
|
|
319
|
+
function inRange(value, min, max) {
|
|
320
|
+
return value >= min && value <= max;
|
|
321
|
+
}
|
|
322
|
+
function matchesPattern(value, pattern) {
|
|
323
|
+
return pattern.test(value);
|
|
324
|
+
}
|
|
325
|
+
function isInList(value, list) {
|
|
326
|
+
return list.includes(value);
|
|
134
327
|
}
|
|
135
328
|
export {
|
|
136
329
|
addressSchema,
|
|
330
|
+
calculatePasswordStrength,
|
|
137
331
|
dateStringSchema,
|
|
138
332
|
emailSchema,
|
|
333
|
+
exactLength,
|
|
334
|
+
extractCountryCode,
|
|
335
|
+
formatPhone,
|
|
336
|
+
inRange,
|
|
337
|
+
isCommonPassword,
|
|
338
|
+
isDisposableEmail,
|
|
339
|
+
isExternalUrl,
|
|
340
|
+
isInList,
|
|
341
|
+
isNumeric,
|
|
342
|
+
isRequired,
|
|
343
|
+
isValidEmail,
|
|
344
|
+
isValidEmailDomain,
|
|
345
|
+
isValidIndianMobile,
|
|
346
|
+
isValidIndianPincode,
|
|
347
|
+
isValidPhone,
|
|
348
|
+
isValidUrl,
|
|
349
|
+
isValidUrlWithProtocol,
|
|
350
|
+
matchesPattern,
|
|
351
|
+
maxLength,
|
|
139
352
|
mediaUrlSchema,
|
|
353
|
+
meetsPasswordRequirements,
|
|
354
|
+
minLength,
|
|
355
|
+
normalizeEmail,
|
|
356
|
+
normalizePhone,
|
|
140
357
|
objectIdSchema,
|
|
141
358
|
paginationQuerySchema,
|
|
142
359
|
passwordSchema,
|
|
143
360
|
phoneSchema,
|
|
361
|
+
sanitizeUrl,
|
|
144
362
|
setupZodErrorMap,
|
|
145
363
|
urlSchema,
|
|
146
364
|
zodErrorMap
|